Skip to content

Commit 5ee79ef

Browse files
MarkDaoustcopybara-github
authored andcommitted
feat: interaction.{output_text,output_image,output_audio,output_video}
Add SDK methods for shortcut properties on the response object to access the output generated in response to the current request, without forcing developers to iterate through the full steps timeline or filter out previous conversation history: interaction.output_text: Concatenated last consecutive text generated by the model in response to the current request. .output_image: The last image generated by the model in response to the current request. .output_audio: The last audio clip generated by the model in response to the current request. .output_video: The last video generated by the model in response to the current request. PiperOrigin-RevId: 915550451
1 parent 6a5db58 commit 5ee79ef

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

google/genai/_interactions/types/interaction.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
from .video_content import VideoContent
3434
from .._legacy_lyria import is_legacy_lyria_response_body
3535
from .webhook_config import WebhookConfig
36+
from .user_input_step import UserInputStep
3637
from .document_content import DocumentContent
38+
from .model_output_step import ModelOutputStep
3739
from .dynamic_agent_config import DynamicAgentConfig
3840
from .text_response_format import TextResponseFormat
3941
from .audio_response_format import AudioResponseFormat
@@ -212,3 +214,70 @@ def _coerce_outputs_to_steps(cls, values: Any) -> Any:
212214
def _coerce_outputs_to_steps(cls, data: Any) -> Any:
213215
coerced, _ = cls._maybe_coerce_outputs(data)
214216
return coerced
217+
218+
@property
219+
def _last_model_output_steps(self) -> List[ModelOutputStep]:
220+
if not self.steps:
221+
return []
222+
trailing: List[ModelOutputStep] = []
223+
for step in reversed(self.steps):
224+
if isinstance(step, ModelOutputStep):
225+
trailing.append(step)
226+
else:
227+
break
228+
trailing.reverse()
229+
return trailing
230+
231+
@property
232+
def output_text(self) -> str:
233+
"""Concatenated last consecutive text from the last consecutive model output steps."""
234+
parts: List[str] = []
235+
done = False
236+
for step in reversed(self._last_model_output_steps):
237+
if done:
238+
break
239+
if step.content:
240+
for content in reversed(step.content):
241+
if isinstance(content, TextContent):
242+
parts.append(content.text)
243+
else:
244+
done = True
245+
break
246+
parts.reverse()
247+
return "".join(parts)
248+
249+
@property
250+
def output_image(self) -> Optional[ImageContent]:
251+
"""The last image generated by the model in response to the current request."""
252+
for step in reversed(self.steps):
253+
if isinstance(step, UserInputStep):
254+
break
255+
if isinstance(step, ModelOutputStep) and step.content:
256+
for content in reversed(step.content):
257+
if isinstance(content, ImageContent):
258+
return content
259+
return None
260+
261+
@property
262+
def output_audio(self) -> Optional[AudioContent]:
263+
"""The last audio generated by the model in response to the current request."""
264+
for step in reversed(self.steps):
265+
if isinstance(step, UserInputStep):
266+
break
267+
if isinstance(step, ModelOutputStep) and step.content:
268+
for content in reversed(step.content):
269+
if isinstance(content, AudioContent):
270+
return content
271+
return None
272+
273+
@property
274+
def output_video(self) -> Optional[VideoContent]:
275+
"""The last video generated by the model in response to the current request."""
276+
for step in reversed(self.steps):
277+
if isinstance(step, UserInputStep):
278+
break
279+
if isinstance(step, ModelOutputStep) and step.content:
280+
for content in reversed(step.content):
281+
if isinstance(content, VideoContent):
282+
return content
283+
return None

0 commit comments

Comments
 (0)