Skip to content

Commit 7c11f58

Browse files
wuliang229copybara-github
authored andcommitted
fix(samples): Fix monitor_video_stream in live bidi streaming sample
- Fix TypeError by adding required model parameter to generate_content call. - Support Vertex AI (GCP) authentication via gcloud credentials by allowing Client configuration via environment variables. - Fix deadlock by yielding correct type (string count) instead of full GenerateContentResponse from monitor_video_stream. - Clean up duplicate imports. - Update agent system instruction with CRITICAL warning to restrict calling monitor tools to at most once per request and explain the background streaming behavior. - Improve monitor tools (video and stock) docstrings with CRITICAL warnings to instruct the model to call them only once and wait for background updates. Co-authored-by: Liang Wu <wuliang@google.com> PiperOrigin-RevId: 947835801
1 parent f4decf6 commit 7c11f58

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

  • contributing/samples/live/live_bidi_streaming_tools_agent

contributing/samples/live/live_bidi_streaming_tools_agent/agent.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@
2222

2323

2424
async def monitor_stock_price(stock_symbol: str) -> AsyncGenerator[str, None]:
25-
"""This function will monitor the price for the given stock_symbol in a continuous, streaming and asynchronously way."""
25+
"""Starts a background monitor for the price of the given stock_symbol.
26+
27+
Call this function ONLY ONCE to initiate monitoring. Once started, it runs
28+
continuously in the background and automatically streams price alerts.
29+
30+
CRITICAL: Do NOT call this function again to "check" or "poll" for updates.
31+
Simply wait for the background task to yield new values and report them.
32+
Calling this again while running will launch a duplicate background task.
33+
"""
2634
print(f"Start monitor stock price for {stock_symbol}!")
2735

2836
# Let's mock stock price change.
@@ -51,13 +59,21 @@ async def monitor_stock_price(stock_symbol: str) -> AsyncGenerator[str, None]:
5159
async def monitor_video_stream(
5260
input_stream: LiveRequestQueue,
5361
) -> AsyncGenerator[str, None]:
54-
"""Monitor how many people are in the video streams."""
62+
"""Starts a background monitor for the video stream.
63+
64+
Call this function ONLY ONCE to initiate monitoring. Once started, it runs
65+
continuously in the background and automatically streams updates back to
66+
you whenever the person count changes.
67+
68+
CRITICAL: Do NOT call this function again to "check" or "poll" for updates.
69+
Simply wait for the background task to yield new values and report them.
70+
Calling this again while running will launch a duplicate background task.
71+
"""
5572
from google.genai import Client
5673

5774
print("start monitor_video_stream!")
58-
from google.genai import Client
5975

60-
client = Client(enterprise=False)
76+
client = Client()
6177
prompt_text = (
6278
"Count the number of people in this image. Just respond with a numeric"
6379
" number."
@@ -90,6 +106,7 @@ async def monitor_video_stream(
90106

91107
# Call the model to generate content based on the provided image and prompt
92108
response = client.models.generate_content(
109+
model="gemini-2.5-flash",
93110
contents=contents,
94111
config=genai_types.GenerateContentConfig(
95112
system_instruction=(
@@ -99,12 +116,12 @@ async def monitor_video_stream(
99116
)
100117
),
101118
)
119+
new_count = response.candidates[0].content.parts[0].text.strip()
102120
if not last_count:
103-
last_count = response.candidates[0].content.parts[0].text
104-
elif last_count != response.candidates[0].content.parts[0].text:
105-
last_count = response.candidates[0].content.parts[0].text
106-
yield response
107-
print("response:", response)
121+
last_count = new_count
122+
elif last_count != new_count:
123+
last_count = new_count
124+
yield new_count
108125

109126
# Wait before checking for new images
110127
await asyncio.sleep(0.5)
@@ -135,6 +152,11 @@ def stop_streaming(function_name: str):
135152
You can use monitor_video_stream function to do that. When monitor_video_stream
136153
returns the alert, you should tell the users.
137154
When users want to monitor a stock price, you can use monitor_stock_price.
155+
CRITICAL: Only call the monitor tools (monitor_video_stream, monitor_stock_price) at most once per request.
156+
Once called, these tools run continuously in the background. Do NOT call them again to "poll" or "check" for updates.
157+
Instead, simply wait for the background tool to stream a new message/alert to you, and then report that alert to the user.
158+
Calling the tool again while it is already running will cause duplicate tasks and errors.
159+
If you need to stop a monitor, call stop_streaming. Only after stopping can you call the monitor tool again if needed.
138160
Don't ask too many questions. Don't be too talkative.
139161
""",
140162
tools=[

0 commit comments

Comments
 (0)