Skip to content

Commit f322c46

Browse files
committed
Add example where tool and user overlap
1 parent 44a7259 commit f322c46

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
interactions:
2+
- request:
3+
body: |-
4+
{
5+
"contents": [
6+
{
7+
"role": "user",
8+
"parts": [
9+
{
10+
"text": "Get weather details in New Delhi and San Francisco?"
11+
}
12+
]
13+
},
14+
{
15+
"role": "model",
16+
"parts": [
17+
{
18+
"functionCall": {
19+
"name": "get_current_weather",
20+
"args": {
21+
"location": "New Delhi"
22+
}
23+
}
24+
},
25+
{
26+
"functionCall": {
27+
"name": "get_current_weather",
28+
"args": {
29+
"location": "San Francisco"
30+
}
31+
}
32+
}
33+
]
34+
},
35+
{
36+
"role": "user",
37+
"parts": [
38+
{
39+
"functionResponse": {
40+
"name": "get_current_weather",
41+
"response": {
42+
"content": "{\"temperature\": 35, \"unit\": \"C\"}"
43+
}
44+
}
45+
},
46+
{
47+
"functionResponse": {
48+
"name": "get_current_weather",
49+
"response": {
50+
"content": "{\"temperature\": 25, \"unit\": \"C\"}"
51+
}
52+
}
53+
},
54+
{
55+
"text": "Please respond in French"
56+
}
57+
]
58+
}
59+
],
60+
"tools": [
61+
{
62+
"functionDeclarations": [
63+
{
64+
"name": "get_current_weather",
65+
"description": "Get the current weather in a given location",
66+
"parameters": {
67+
"type": 6,
68+
"properties": {
69+
"location": {
70+
"type": 1,
71+
"description": "The location for which to get the weather. It can be a city name, a city name and state, or a zip code. Examples: 'San Francisco', 'San Francisco, CA', '95616', etc."
72+
}
73+
},
74+
"propertyOrdering": [
75+
"location"
76+
]
77+
}
78+
}
79+
]
80+
}
81+
]
82+
}
83+
headers:
84+
Accept:
85+
- '*/*'
86+
Accept-Encoding:
87+
- gzip, deflate
88+
Connection:
89+
- keep-alive
90+
Content-Length:
91+
- '1797'
92+
Content-Type:
93+
- application/json
94+
User-Agent:
95+
- python-requests/2.32.3
96+
method: POST
97+
uri: https://us-central1-aiplatform.googleapis.com/v1/projects/fake-project/locations/us-central1/publishers/google/models/gemini-1.5-flash-002:generateContent?%24alt=json%3Benum-encoding%3Dint
98+
response:
99+
body:
100+
string: |-
101+
{
102+
"candidates": [
103+
{
104+
"content": {
105+
"role": "model",
106+
"parts": [
107+
{
108+
"text": "La temp\u00e9rature actuelle \u00e0 New Delhi est de 35 degr\u00e9s Celsius et \u00e0 San Francisco, de 25 degr\u00e9s Celsius.\n"
109+
}
110+
]
111+
},
112+
"finishReason": 1,
113+
"avgLogprobs": -0.13563571526454046
114+
}
115+
],
116+
"usageMetadata": {
117+
"promptTokenCount": 130,
118+
"candidatesTokenCount": 26,
119+
"totalTokenCount": 156,
120+
"promptTokensDetails": [
121+
{
122+
"modality": 1,
123+
"tokenCount": 130
124+
}
125+
],
126+
"candidatesTokensDetails": [
127+
{
128+
"modality": 1,
129+
"tokenCount": 26
130+
}
131+
]
132+
},
133+
"modelVersion": "gemini-1.5-flash-002",
134+
"createTime": "2025-02-06T18:23:19.079289Z",
135+
"responseId": "F_6kZ7nrBNa5nvgP1YzPmQE"
136+
}
137+
headers:
138+
Content-Type:
139+
- application/json; charset=UTF-8
140+
Transfer-Encoding:
141+
- chunked
142+
Vary:
143+
- Origin
144+
- X-Origin
145+
- Referer
146+
content-length:
147+
- '794'
148+
status:
149+
code: 200
150+
message: OK
151+
version: 1

instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,70 @@ def test_tool_events_no_content(
309309
}
310310

311311

312+
@pytest.mark.vcr
313+
def test_tool_events_breakthings(
314+
span_exporter: InMemorySpanExporter,
315+
log_exporter: InMemoryLogExporter,
316+
instrument_with_content: VertexAIInstrumentor,
317+
):
318+
model = GenerativeModel("gemini-1.5-flash-002", tools=[weather_tool()])
319+
model.generate_content(
320+
[
321+
# User asked about weather
322+
Content(
323+
role="user",
324+
parts=[
325+
Part.from_text(
326+
"Get weather details in New Delhi and San Francisco?"
327+
),
328+
],
329+
),
330+
# Model requests two function calls
331+
Content(
332+
role="model",
333+
parts=[
334+
Part.from_dict(
335+
{
336+
"function_call": {
337+
"name": "get_current_weather",
338+
"args": {"location": "New Delhi"},
339+
}
340+
},
341+
),
342+
Part.from_dict(
343+
{
344+
"function_call": {
345+
"name": "get_current_weather",
346+
"args": {"location": "San Francisco"},
347+
}
348+
},
349+
),
350+
],
351+
),
352+
# User responds with function responses and asks for french
353+
Content(
354+
role="user",
355+
parts=[
356+
Part.from_function_response(
357+
name="get_current_weather",
358+
response={
359+
"content": '{"temperature": 35, "unit": "C"}'
360+
},
361+
),
362+
Part.from_function_response(
363+
name="get_current_weather",
364+
response={
365+
"content": '{"temperature": 25, "unit": "C"}'
366+
},
367+
),
368+
# NOTE: User message too
369+
Part.from_text("Please respond in French"),
370+
],
371+
),
372+
]
373+
)
374+
375+
312376
def weather_tool() -> Tool:
313377
# Adapted from https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#parallel-samples
314378
get_current_weather_func = FunctionDeclaration(

0 commit comments

Comments
 (0)