llm-gemini 0.20a0__py3-none-any.whl → 0.20a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {llm_gemini-0.20a0.dist-info → llm_gemini-0.20a2.dist-info}/METADATA +5 -5
- llm_gemini-0.20a2.dist-info/RECORD +7 -0
- {llm_gemini-0.20a0.dist-info → llm_gemini-0.20a2.dist-info}/WHEEL +1 -1
- llm_gemini.py +87 -12
- llm_gemini-0.20a0.dist-info/RECORD +0 -7
- {llm_gemini-0.20a0.dist-info → llm_gemini-0.20a2.dist-info}/entry_points.txt +0 -0
- {llm_gemini-0.20a0.dist-info → llm_gemini-0.20a2.dist-info}/licenses/LICENSE +0 -0
- {llm_gemini-0.20a0.dist-info → llm_gemini-0.20a2.dist-info}/top_level.txt +0 -0
@@ -1,17 +1,16 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: llm-gemini
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.20a2
|
4
4
|
Summary: LLM plugin to access Google's Gemini family of models
|
5
5
|
Author: Simon Willison
|
6
|
-
License: Apache-2.0
|
6
|
+
License-Expression: Apache-2.0
|
7
7
|
Project-URL: Homepage, https://github.com/simonw/llm-gemini
|
8
8
|
Project-URL: Changelog, https://github.com/simonw/llm-gemini/releases
|
9
9
|
Project-URL: Issues, https://github.com/simonw/llm-gemini/issues
|
10
10
|
Project-URL: CI, https://github.com/simonw/llm-gemini/actions
|
11
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
12
11
|
Description-Content-Type: text/markdown
|
13
12
|
License-File: LICENSE
|
14
|
-
Requires-Dist: llm>=0.
|
13
|
+
Requires-Dist: llm>=0.26a0
|
15
14
|
Requires-Dist: httpx
|
16
15
|
Requires-Dist: ijson
|
17
16
|
Provides-Extra: test
|
@@ -67,7 +66,8 @@ llm "A joke about a pelican and a walrus"
|
|
67
66
|
Other models are:
|
68
67
|
|
69
68
|
- `gemini-2.5-pro-preview-05-06` - latest paid Gemini 2.5 Pro preview
|
70
|
-
- `gemini-2.5-flash-preview-
|
69
|
+
- `gemini-2.5-flash-preview-05-20` - Gemini 2.5 Flash preview
|
70
|
+
- `gemini-2.5-flash-preview-04-17` - Earlier Gemini 2.5 Flash preview
|
71
71
|
- `gemini-2.5-pro-exp-03-25` - free experimental release of Gemini 2.5 Pro
|
72
72
|
- `gemini-2.5-pro-preview-03-25` - paid preview of Gemini 2.5 Pro
|
73
73
|
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
@@ -0,0 +1,7 @@
|
|
1
|
+
llm_gemini.py,sha256=rHA904SF-06hjTf2bem219ZxK98DlS6BuUVLl92FffM,21465
|
2
|
+
llm_gemini-0.20a2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
3
|
+
llm_gemini-0.20a2.dist-info/METADATA,sha256=gQD_OgG2F6UP3Lpvf-TsfVIlCCx0djUualXyIwC24Bk,8139
|
4
|
+
llm_gemini-0.20a2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
5
|
+
llm_gemini-0.20a2.dist-info/entry_points.txt,sha256=n544bpgUPIBc5l_cnwsTxPc3gMGJHPtAyqBNp-CkMWk,26
|
6
|
+
llm_gemini-0.20a2.dist-info/top_level.txt,sha256=WUQmG6_2QKbT_8W4HH93qyKl_0SUteL4Ra6_PhyNGKU,11
|
7
|
+
llm_gemini-0.20a2.dist-info/RECORD,,
|
llm_gemini.py
CHANGED
@@ -40,6 +40,7 @@ GOOGLE_SEARCH_MODELS = {
|
|
40
40
|
"gemini-2.5-pro-exp-03-25",
|
41
41
|
"gemini-2.5-flash-preview-04-17",
|
42
42
|
"gemini-2.5-pro-preview-05-06",
|
43
|
+
"gemini-2.5-flash-preview-05-20",
|
43
44
|
}
|
44
45
|
|
45
46
|
# Older Google models used google_search_retrieval instead of google_search
|
@@ -55,6 +56,7 @@ GOOGLE_SEARCH_MODELS_USING_SEARCH_RETRIEVAL = {
|
|
55
56
|
|
56
57
|
THINKING_BUDGET_MODELS = {
|
57
58
|
"gemini-2.5-flash-preview-04-17",
|
59
|
+
"gemini-2.5-flash-preview-05-20",
|
58
60
|
}
|
59
61
|
|
60
62
|
|
@@ -93,6 +95,8 @@ def register_models(register):
|
|
93
95
|
"gemini-2.5-flash-preview-04-17",
|
94
96
|
# 6th May 2025:
|
95
97
|
"gemini-2.5-pro-preview-05-06",
|
98
|
+
# 20th May 2025:
|
99
|
+
"gemini-2.5-flash-preview-05-20",
|
96
100
|
]:
|
97
101
|
can_google_search = model_id in GOOGLE_SEARCH_MODELS
|
98
102
|
can_thinking_budget = model_id in THINKING_BUDGET_MODELS
|
@@ -148,6 +152,7 @@ class _SharedGemini:
|
|
148
152
|
key_env_var = "LLM_GEMINI_KEY"
|
149
153
|
can_stream = True
|
150
154
|
supports_schema = True
|
155
|
+
supports_tools = True
|
151
156
|
|
152
157
|
attachment_types = (
|
153
158
|
# Text
|
@@ -273,14 +278,57 @@ class _SharedGemini:
|
|
273
278
|
)
|
274
279
|
if response.prompt.prompt:
|
275
280
|
parts.append({"text": response.prompt.prompt})
|
281
|
+
if response.prompt.tool_results:
|
282
|
+
parts.extend(
|
283
|
+
[
|
284
|
+
{
|
285
|
+
"function_response": {
|
286
|
+
"name": tool_result.name,
|
287
|
+
"response": {
|
288
|
+
"output": tool_result.output,
|
289
|
+
},
|
290
|
+
}
|
291
|
+
}
|
292
|
+
for tool_result in response.prompt.tool_results
|
293
|
+
]
|
294
|
+
)
|
276
295
|
messages.append({"role": "user", "parts": parts})
|
277
|
-
|
278
|
-
|
279
|
-
|
296
|
+
model_parts = []
|
297
|
+
response_text = response.text_or_raise()
|
298
|
+
if response_text:
|
299
|
+
model_parts.append({"text": response_text})
|
300
|
+
tool_calls = response.tool_calls_or_raise()
|
301
|
+
if tool_calls:
|
302
|
+
model_parts.extend(
|
303
|
+
[
|
304
|
+
{
|
305
|
+
"function_call": {
|
306
|
+
"name": tool_call.name,
|
307
|
+
"args": tool_call.arguments,
|
308
|
+
}
|
309
|
+
}
|
310
|
+
for tool_call in tool_calls
|
311
|
+
]
|
312
|
+
)
|
313
|
+
messages.append({"role": "model", "parts": model_parts})
|
280
314
|
|
281
315
|
parts = []
|
282
316
|
if prompt.prompt:
|
283
317
|
parts.append({"text": prompt.prompt})
|
318
|
+
if prompt.tool_results:
|
319
|
+
parts.extend(
|
320
|
+
[
|
321
|
+
{
|
322
|
+
"function_response": {
|
323
|
+
"name": tool_result.name,
|
324
|
+
"response": {
|
325
|
+
"output": tool_result.output,
|
326
|
+
},
|
327
|
+
}
|
328
|
+
}
|
329
|
+
for tool_result in prompt.tool_results
|
330
|
+
]
|
331
|
+
)
|
284
332
|
for attachment in prompt.attachments:
|
285
333
|
mime_type = resolve_type(attachment)
|
286
334
|
parts.append(
|
@@ -300,17 +348,34 @@ class _SharedGemini:
|
|
300
348
|
"contents": self.build_messages(prompt, conversation),
|
301
349
|
"safetySettings": SAFETY_SETTINGS,
|
302
350
|
}
|
351
|
+
if prompt.system:
|
352
|
+
body["systemInstruction"] = {"parts": [{"text": prompt.system}]}
|
353
|
+
|
354
|
+
tools = []
|
303
355
|
if prompt.options and prompt.options.code_execution:
|
304
|
-
|
356
|
+
tools.append({"codeExecution": {}})
|
305
357
|
if prompt.options and self.can_google_search and prompt.options.google_search:
|
306
358
|
tool_name = (
|
307
359
|
"google_search_retrieval"
|
308
360
|
if self.model_id in GOOGLE_SEARCH_MODELS_USING_SEARCH_RETRIEVAL
|
309
361
|
else "google_search"
|
310
362
|
)
|
311
|
-
|
312
|
-
if prompt.
|
313
|
-
|
363
|
+
tools.append({tool_name: {}})
|
364
|
+
if prompt.tools:
|
365
|
+
tools.append(
|
366
|
+
{
|
367
|
+
"functionDeclarations": [
|
368
|
+
{
|
369
|
+
"name": tool.name,
|
370
|
+
"description": tool.description,
|
371
|
+
"parameters": tool.input_schema,
|
372
|
+
}
|
373
|
+
for tool in prompt.tools
|
374
|
+
]
|
375
|
+
}
|
376
|
+
)
|
377
|
+
if tools:
|
378
|
+
body["tools"] = tools
|
314
379
|
|
315
380
|
generation_config = {}
|
316
381
|
|
@@ -321,6 +386,7 @@ class _SharedGemini:
|
|
321
386
|
"response_schema": cleanup_schema(copy.deepcopy(prompt.schema)),
|
322
387
|
}
|
323
388
|
)
|
389
|
+
|
324
390
|
if self.can_thinking_budget and prompt.options.thinking_budget is not None:
|
325
391
|
generation_config["thinking_config"] = {
|
326
392
|
"thinking_budget": prompt.options.thinking_budget
|
@@ -348,7 +414,14 @@ class _SharedGemini:
|
|
348
414
|
|
349
415
|
return body
|
350
416
|
|
351
|
-
def process_part(self, part):
|
417
|
+
def process_part(self, part, response):
|
418
|
+
if "functionCall" in part:
|
419
|
+
response.add_tool_call(
|
420
|
+
llm.ToolCall(
|
421
|
+
name=part["functionCall"]["name"],
|
422
|
+
arguments=part["functionCall"]["args"],
|
423
|
+
)
|
424
|
+
)
|
352
425
|
if "text" in part:
|
353
426
|
return part["text"]
|
354
427
|
elif "executableCode" in part:
|
@@ -357,10 +430,10 @@ class _SharedGemini:
|
|
357
430
|
return f'```\n{part["codeExecutionResult"]["output"].strip()}\n```\n'
|
358
431
|
return ""
|
359
432
|
|
360
|
-
def process_candidates(self, candidates):
|
433
|
+
def process_candidates(self, candidates, response):
|
361
434
|
# We only use the first candidate
|
362
435
|
for part in candidates[0]["content"]["parts"]:
|
363
|
-
yield self.process_part(part)
|
436
|
+
yield self.process_part(part, response)
|
364
437
|
|
365
438
|
def set_usage(self, response):
|
366
439
|
try:
|
@@ -404,7 +477,9 @@ class GeminiPro(_SharedGemini, llm.KeyModel):
|
|
404
477
|
if isinstance(event, dict) and "error" in event:
|
405
478
|
raise llm.ModelError(event["error"]["message"])
|
406
479
|
try:
|
407
|
-
yield from self.process_candidates(
|
480
|
+
yield from self.process_candidates(
|
481
|
+
event["candidates"], response
|
482
|
+
)
|
408
483
|
except KeyError:
|
409
484
|
yield ""
|
410
485
|
gathered.append(event)
|
@@ -437,7 +512,7 @@ class AsyncGeminiPro(_SharedGemini, llm.AsyncKeyModel):
|
|
437
512
|
raise llm.ModelError(event["error"]["message"])
|
438
513
|
try:
|
439
514
|
for chunk in self.process_candidates(
|
440
|
-
event["candidates"]
|
515
|
+
event["candidates"], response
|
441
516
|
):
|
442
517
|
yield chunk
|
443
518
|
except KeyError:
|
@@ -1,7 +0,0 @@
|
|
1
|
-
llm_gemini.py,sha256=GJp1oDwcdLXy2QAYwp7jGN0KZsbmj_pJcqktYRC139Q,18700
|
2
|
-
llm_gemini-0.20a0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
3
|
-
llm_gemini-0.20a0.dist-info/METADATA,sha256=sqrfXHXhfZ9PzoBzkJ6VaW-liP9dd8nAYztOiZhOgS0,8119
|
4
|
-
llm_gemini-0.20a0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
5
|
-
llm_gemini-0.20a0.dist-info/entry_points.txt,sha256=n544bpgUPIBc5l_cnwsTxPc3gMGJHPtAyqBNp-CkMWk,26
|
6
|
-
llm_gemini-0.20a0.dist-info/top_level.txt,sha256=WUQmG6_2QKbT_8W4HH93qyKl_0SUteL4Ra6_PhyNGKU,11
|
7
|
-
llm_gemini-0.20a0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|