8000 Convert Session To Invocation. · Syntax404-coder/adk-python@82b8e30 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 82b8e30

Browse files
ankursharmascopybara-github
authored andcommitted
Convert Session To Invocation.
PiperOrigin-RevId: 758356942
1 parent 4188673 commit 82b8e30

File tree

2 files changed

+93
-4
lines changed

2 files changed

+93
-4
lines changed

src/google/adk/cli/utils/evals.py

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Any
15+
from typing import Any, Tuple
1616

17+
from deprecated import deprecated
18+
from google.genai import types as genai_types
19+
20+
from ...evaluation.eval_case import IntermediateData
21+
from ...evaluation.eval_case import Invocation
1722
from ...sessions.session import Session
1823

1924

25+
@deprecated(reason='Use convert_session_to_eval_invocations instead.')
2026
def convert_session_to_eval_format(session: Session) -> list[dict[str, Any]]:
2127
"""Converts a session data into eval format.
2228
@@ -91,3 +97,79 @@ def convert_session_to_eval_format(session: Session) -> list[dict[str, Any]]:
9197
})
9298

8000
9399
return eval_case
100+
101+
102+
def convert_session_to_eval_invocations(session: Session) -> list[Invocation]:
103+
"""Converts a session data into a list of Invocation.
104+
105+
Args:
106+
session: The session that should be converted.
107+
108+
Returns:
109+
list: A list of invocation.
110+
"""
111+
invocations: list[Invocation] = []
112+
events = session.events if session and session.events else []
113+
114+
for event in events:
115+
if event.author == 'user':
116+
if not event.content or not event.content.parts:
117+
continue
118+
119+
# The content present in this event is the user content.
120+
user_content = event.content
121+
invocation_id = event.invocation_id
122+
invocaton_timestamp = event.timestamp
123+
124+
# Find the corresponding tool usage or response for the query
125+
tool_uses: list[genai_types.FunctionCall] = []
126+
intermediate_responses: list[Tuple[str, list[genai_types.Part]]] = []
127+
128+
# Check subsequent events to extract tool uses or responses for this turn.
129+
for subsequent_event in events[events.index(event) + 1 :]:
130+
event_author = subsequent_event.author or 'agent'
131+
if event_author == 'user':
132+
# We found an event where the author was the user. This means that a
133+
# new turn has started. So close this turn here.
134+
break
135+
136+
if not subsequent_event.content or not subsequent_event.content.parts:
137+
continue
138+
139+
intermediate_response_parts = []
140+
for subsequent_part in subsequent_event.content.parts:
141+
# Some events have both function call and reference
142+
if subsequent_part.function_call:
143+
tool_uses.append(subsequent_part.function_call)
144+
elif subsequent_part.text:
145+
# Also keep track of all the natural language responses that
146+
# agent (or sub agents) generated.
147+
intermediate_response_parts.append(subsequent_part)
148+
149+
if intermediate_response_parts:
150+
# Only add an entry if there any intermediate entries.
151+
intermediate_responses.append(
152+
(event_author, intermediate_response_parts)
153+
)
154+
155+
# If we are here then either we are done reading all the events or we
156+
# encountered an event that had content authored by the end-user.
157+
# This, basically means an end of turn.
158+
# We assume that the last natural language intermediate response is the
159+
# final response from the agent/model. We treat that as a reference.
160+
invocations.append(
161+
Invocation(
162+
user_content=user_content,
163+
invocation_id=invocation_id,
164+
creation_timestamp=invocaton_timestamp,
165+
intermediate_data=IntermediateData(
166+
tool_uses=tool_uses,
167+
intermediate_responses=intermediate_responses[:-1],
168+
),
169+
final_response=genai_types.Content(
170+
parts=intermediate_responses[-1][1]
171+
),
172+
)
173+
)
174+
175+
return invocations

src/google/adk/evaluation/eval_case.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515

16-
from typing import Any, Optional
16+
from typing import Any, Optional, Tuple
1717

1818
from google.genai import types as genai_types
1919
from pydantic import BaseModel
@@ -26,9 +26,16 @@ class IntermediateData(BaseModel):
2626
tool_uses: list[genai_types.FunctionCall]
2727
"""Tool use trajectory in chronological order."""
2828

29-
intermediate_responses: list[genai_types.Part]
29+
intermediate_responses: list[Tuple[str, list[genai_types.Part]]]
3030
"""Intermediate responses generated by sub-agents to convey progress or status
31-
in a multi-agent system, distinct from the final response."""
31+
in a multi-agent system, distinct from the final response.
32+
33+
This is expressed as a Tuple of:
34+
- Author: Usually the sub-agent name that generated the intermediate
35+
response.
36+
37+
- A list of Parts that comprise of the response.
38+
"""
3239

3340

3441
class Invocation(BaseModel):

0 commit comments

Comments
 (0)
0