20
20
from google .genai .types import Part
21
21
import pytest
22
22
23
- _TEST_MODEL_NAME = "vertex_ai/meta/llama-4-maverick-17b-128e-instruct-maas"
24
23
24
+ _TEST_MODEL_NAME = "vertex_ai/meta/llama-3.1-405b-instruct-maas"
25
25
26
26
_SYSTEM_PROMPT = """You are a helpful assistant."""
27
27
28
28
29
+ def get_weather (city : str ) -> str :
30
+ """Simulates a web search. Use it get information on weather.
31
+
32
+ Args:
33
+ city: A string containing the location to get weather information for.
34
+
35
+ Returns:
36
+ A string with the simulated weather information for the queried city.
37
+ """
38
+ if "sf" in city .lower () or "san francisco" in city .lower ():
39
+ return "It's 70 degrees and foggy."
40
+ return "It's 80 degrees and sunny."
41
+
42
+
29
43
@pytest .fixture
30
44
def oss_llm ():
31
45
return LiteLlm (model = _TEST_MODEL_NAME )
@@ -44,17 +58,57 @@ def llm_request():
44
58
)
45
59
46
60
61
+ @pytest .fixture
62
+ def llm_request_with_tools ():
63
+ return LlmRequest (
64
+ model = _TEST_MODEL_NAME ,
65
+ contents = [
66
+ Content (
67
+ role = "user" ,
68
+ parts = [
69
+ Part .from_text (text = "What is the weather in San Francisco?" )
70
+ ],
71
+ )
72
+ ],
73
+ config = types .GenerateContentConfig (
74
+ temperature = 0.1 ,
75
+ response_modalities = [types .Modality .TEXT ],
76
+ system_instruction = _SYSTEM_PROMPT ,
77
+ tools = [
78
+ types .Tool (
79
+ function_declarations = [
80
+ types .FunctionDeclaration (
81
+ name = "get_weather" ,
82
+ description = "Get the weather in a given location" ,
83
+ parameters = types .Schema (
84
+ type = types .Type .OBJECT ,
85
+ properties = {
86
+ "city" : types .Schema (
87
+ type = types .Type .STRING ,
88
+ description = (
89
+ "The city to get the weather for."
90
+ ),
91
+ ),
92
+ },
93
+ required = ["city" ],
94
+ ),
95
+ )
96
+ ]
97
+ )
98
+ ],
99
+ ),
100
+ )
101
+
102
+
47
103
@pytest .mark .asyncio
48
104
async def test_generate_content_async (oss_llm , llm_request ):
49
105
async for response in oss_llm .generate_content_async (llm_request ):
50
106
assert isinstance (response , LlmResponse )
51
107
assert response .content .parts [0 ].text
52
108
53
109
54
- # Note that, this test disabled streaming because streaming is not supported
55
- # properly in the current test model for now.
56
110
@pytest .mark .asyncio
57
- async def test_generate_content_async_stream (oss_llm , llm_request ):
111
+ async def test_generate_content_async (oss_llm , llm_request ):
58
112
responses = [
59
113
resp
60
114
async for resp in oss_llm .generate_content_async (
@@ -63,3 +117,50 @@ async def test_generate_content_async_stream(oss_llm, llm_request):
63
117
]
64
118
part = responses [0 ].content .parts [0 ]
65
119
assert len (part .text ) > 0
120
+
121
+
122
+ @pytest .mark .asyncio
123
+ async def test_generate_content_async_with_tools (
124
+ oss_llm , llm_request_with_tools
125
+ ):
126
+ responses = [
127
+ resp
128
+ async for resp in oss_llm .generate_content_async (
129
+ llm_request_with_tools , stream = False
130
+ )
131
+ ]
132
+ function_call = responses [0 ].content .parts [0 ].function_call
133
+ assert function_call .name == "get_weather"
134
+ assert function_call .args ["city" ] == "San Francisco"
135
+
136
+
137
+ @pytest .mark .asyncio
138
+ async def test_generate_content_async_stream (oss_llm , llm_request ):
139
+ responses = [
140
+ resp
141
+ async for resp in oss_llm .generate_content_async (llm_request , stream = True )
142
+ ]
143
+ text = ""
144
+ for i in range (len (responses ) - 1 ):
145
+ assert responses [i ].partial is True
146
+ assert responses [i ].content .parts [0 ].text
147
+ text += responses [i ].content .parts [0 ].text
148
+
149
+ # Last message should be accumulated text
150
+ assert responses [- 1 ].content .parts [0 ].text == text
151
+ assert not responses [- 1 ].partial
152
+
153
+
154
+ @pytest .mark .asyncio
155
+ async def test_generate_content_async_stream_with_tools (
156
+ oss_llm , llm_request_with_tools
157
+ ):
158
+ responses = [
159
+ resp
160
+ async for resp in oss_llm .generate_content_async (
161
+ llm_request_with_tools , stream = True
162
+ )
163
+ ]
164
+ function_call = responses [- 1 ].content .parts [0 ].function_call
165
+ assert function_call .name == "get_weather"
166
+ assert function_call .args ["city" ] == "San Francisco"
0 commit comments