Skip to content

Commit 5bd0929

Browse files
aelisseekibergus
authored andcommitted
Adds async function calling.
Async function calls are non-blocking function calls that are particularly well suited for realtime agents. They allow long-running operations to be run on the background without interrupting the main realtime agents. When such functions return a stream of parts and are implemented with processors, async function calls provide a simple mechanism to implement multi-agents. PiperOrigin-RevId: 828839605
1 parent b433e91 commit 5bd0929

File tree

4 files changed

+1321
-118
lines changed

4 files changed

+1321
-118
lines changed

genai_processors/content_api.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ def from_function_response(
332332
function_call_id: str | None = None,
333333
will_continue: bool | None = None,
334334
scheduling: genai_types.FunctionResponseScheduling | None = None,
335+
is_error: bool = False,
335336
**kwargs,
336337
) -> 'ProcessorPart':
337338
"""Constructs a ProcessorPart as a function response.
@@ -349,12 +350,19 @@ def from_function_response(
349350
scheduling: The scheduling policy for the function response. Controls
350351
whether the response generation will be triggered immediately or the
351352
function response is just added to the context.
353+
is_error: Whether the function response is an error. When it is an error,
354+
the response will be stored in the '.error' field in the function
355+
response.
352356
**kwargs: Additional keyword arguments to pass to the `ProcessorPart`
353357
constructor.
354358
355359
Returns:
356360
A ProcessorPart representing the function response.
357361
"""
362+
if is_error:
363+
response_key = 'error'
364+
else:
365+
response_key = 'result'
358366
function_response_args = dict(
359367
id=function_call_id,
360368
name=name,
@@ -365,15 +373,15 @@ def from_function_response(
365373
# serializable object. This is what tools in Gemini API return historically.
366374
try:
367375
function_response = genai_types.FunctionResponse(
368-
response={'result': response}, **function_response_args
376+
response={response_key: response}, **function_response_args
369377
)
370378
function_response.json()
371379
except ValueError:
372380
# Response is not JSON serializable. Then try to construct content.
373381
response_content = ProcessorContent(response)
374382
try:
375383
function_response = genai_types.FunctionResponse(
376-
response={'result': as_text(response_content, strict=True)},
384+
response={response_key: as_text(response_content, strict=True)},
377385
**function_response_args,
378386
)
379387
except ValueError:
@@ -445,12 +453,16 @@ def from_dataclass(cls, *, dataclass: Any, **kwargs) -> 'ProcessorPart':
445453
return cls(part, **kwargs)
446454

447455
@classmethod
448-
def end_of_turn(cls, substream_name: str = '') -> 'ProcessorPart':
456+
def end_of_turn(
457+
cls, substream_name: str = '', metadata: dict[str, Any] | None = None
458+
) -> 'ProcessorPart':
459+
metadata = metadata or {}
460+
metadata['turn_complete'] = True
449461
return ProcessorPart(
450462
'',
451463
role='user',
452464
substream_name=substream_name,
453-
metadata={'turn_complete': True},
465+
metadata=metadata,
454466
)
455467

456468
@classmethod

0 commit comments

Comments
 (0)