llm-gemini 0.17__tar.gz → 0.18.1__tar.gz
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.17 → llm_gemini-0.18.1}/PKG-INFO +2 -1
- {llm_gemini-0.17 → llm_gemini-0.18.1}/README.md +1 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/PKG-INFO +2 -1
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.py +64 -10
- {llm_gemini-0.17 → llm_gemini-0.18.1}/pyproject.toml +1 -1
- {llm_gemini-0.17 → llm_gemini-0.18.1}/tests/test_gemini.py +21 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/LICENSE +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/SOURCES.txt +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/dependency_links.txt +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/entry_points.txt +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/requires.txt +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/llm_gemini.egg-info/top_level.txt +0 -0
- {llm_gemini-0.17 → llm_gemini-0.18.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: llm-gemini
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.18.1
|
4
4
|
Summary: LLM plugin to access Google's Gemini family of models
|
5
5
|
Author: Simon Willison
|
6
6
|
License: Apache-2.0
|
@@ -66,6 +66,7 @@ llm "A joke about a pelican and a walrus"
|
|
66
66
|
|
67
67
|
Other models are:
|
68
68
|
|
69
|
+
- `gemini-2.5-flash-preview-04-17` - Gemini 2.5 Flash preview
|
69
70
|
- `gemini-2.5-pro-exp-03-25` - free experimental release of Gemini 2.5 Pro
|
70
71
|
- `gemini-2.5-pro-preview-03-25` - paid preview of Gemini 2.5 Pro
|
71
72
|
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
@@ -43,6 +43,7 @@ llm "A joke about a pelican and a walrus"
|
|
43
43
|
|
44
44
|
Other models are:
|
45
45
|
|
46
|
+
- `gemini-2.5-flash-preview-04-17` - Gemini 2.5 Flash preview
|
46
47
|
- `gemini-2.5-pro-exp-03-25` - free experimental release of Gemini 2.5 Pro
|
47
48
|
- `gemini-2.5-pro-preview-03-25` - paid preview of Gemini 2.5 Pro
|
48
49
|
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: llm-gemini
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.18.1
|
4
4
|
Summary: LLM plugin to access Google's Gemini family of models
|
5
5
|
Author: Simon Willison
|
6
6
|
License: Apache-2.0
|
@@ -66,6 +66,7 @@ llm "A joke about a pelican and a walrus"
|
|
66
66
|
|
67
67
|
Other models are:
|
68
68
|
|
69
|
+
- `gemini-2.5-flash-preview-04-17` - Gemini 2.5 Flash preview
|
69
70
|
- `gemini-2.5-pro-exp-03-25` - free experimental release of Gemini 2.5 Pro
|
70
71
|
- `gemini-2.5-pro-preview-03-25` - paid preview of Gemini 2.5 Pro
|
71
72
|
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
@@ -36,6 +36,23 @@ GOOGLE_SEARCH_MODELS = {
|
|
36
36
|
"gemini-1.5-flash-002",
|
37
37
|
"gemini-2.0-flash-exp",
|
38
38
|
"gemini-2.0-flash",
|
39
|
+
"gemini-2.5-pro-preview-03-25",
|
40
|
+
"gemini-2.5-pro-exp-03-25",
|
41
|
+
}
|
42
|
+
|
43
|
+
# Older Google models used google_search_retrieval instead of google_search
|
44
|
+
GOOGLE_SEARCH_MODELS_USING_SEARCH_RETRIEVAL = {
|
45
|
+
"gemini-1.5-pro-latest",
|
46
|
+
"gemini-1.5-flash-latest",
|
47
|
+
"gemini-1.5-pro-001",
|
48
|
+
"gemini-1.5-flash-001",
|
49
|
+
"gemini-1.5-pro-002",
|
50
|
+
"gemini-1.5-flash-002",
|
51
|
+
"gemini-2.0-flash-exp",
|
52
|
+
}
|
53
|
+
|
54
|
+
THINKING_BUDGET_MODELS = {
|
55
|
+
"gemini-2.5-flash-preview-04-17",
|
39
56
|
}
|
40
57
|
|
41
58
|
|
@@ -70,17 +87,22 @@ def register_models(register):
|
|
70
87
|
"gemini-2.5-pro-exp-03-25",
|
71
88
|
# 4th April 2025 (paid):
|
72
89
|
"gemini-2.5-pro-preview-03-25",
|
90
|
+
# 17th April 2025:
|
91
|
+
"gemini-2.5-flash-preview-04-17",
|
73
92
|
]:
|
74
93
|
can_google_search = model_id in GOOGLE_SEARCH_MODELS
|
94
|
+
can_thinking_budget = model_id in THINKING_BUDGET_MODELS
|
75
95
|
register(
|
76
96
|
GeminiPro(
|
77
97
|
model_id,
|
78
98
|
can_google_search=can_google_search,
|
99
|
+
can_thinking_budget=can_thinking_budget,
|
79
100
|
can_schema="flash-thinking" not in model_id,
|
80
101
|
),
|
81
102
|
AsyncGeminiPro(
|
82
103
|
model_id,
|
83
104
|
can_google_search=can_google_search,
|
105
|
+
can_thinking_budget=can_thinking_budget,
|
84
106
|
can_schema="flash-thinking" not in model_id,
|
85
107
|
),
|
86
108
|
)
|
@@ -208,12 +230,27 @@ class _SharedGemini:
|
|
208
230
|
default=None,
|
209
231
|
)
|
210
232
|
|
211
|
-
|
233
|
+
class OptionsWithThinkingBudget(OptionsWithGoogleSearch):
|
234
|
+
thinking_budget: Optional[int] = Field(
|
235
|
+
description="Indicates the thinking budget in tokens. Set to 0 to disable.",
|
236
|
+
default=None,
|
237
|
+
)
|
238
|
+
|
239
|
+
def __init__(
|
240
|
+
self,
|
241
|
+
model_id,
|
242
|
+
can_google_search=False,
|
243
|
+
can_thinking_budget=False,
|
244
|
+
can_schema=False,
|
245
|
+
):
|
212
246
|
self.model_id = model_id
|
213
247
|
self.can_google_search = can_google_search
|
214
248
|
self.supports_schema = can_schema
|
215
249
|
if can_google_search:
|
216
250
|
self.Options = self.OptionsWithGoogleSearch
|
251
|
+
self.can_thinking_budget = can_thinking_budget
|
252
|
+
if can_thinking_budget:
|
253
|
+
self.Options = self.OptionsWithThinkingBudget
|
217
254
|
|
218
255
|
def build_messages(self, prompt, conversation):
|
219
256
|
messages = []
|
@@ -262,14 +299,27 @@ class _SharedGemini:
|
|
262
299
|
if prompt.options and prompt.options.code_execution:
|
263
300
|
body["tools"] = [{"codeExecution": {}}]
|
264
301
|
if prompt.options and self.can_google_search and prompt.options.google_search:
|
265
|
-
|
302
|
+
tool_name = (
|
303
|
+
"google_search_retrieval"
|
304
|
+
if self.model_id in GOOGLE_SEARCH_MODELS_USING_SEARCH_RETRIEVAL
|
305
|
+
else "google_search"
|
306
|
+
)
|
307
|
+
body["tools"] = [{tool_name: {}}]
|
266
308
|
if prompt.system:
|
267
309
|
body["systemInstruction"] = {"parts": [{"text": prompt.system}]}
|
268
310
|
|
311
|
+
generation_config = {}
|
312
|
+
|
269
313
|
if prompt.schema:
|
270
|
-
|
271
|
-
|
272
|
-
|
314
|
+
generation_config.update(
|
315
|
+
{
|
316
|
+
"response_mime_type": "application/json",
|
317
|
+
"response_schema": cleanup_schema(copy.deepcopy(prompt.schema)),
|
318
|
+
}
|
319
|
+
)
|
320
|
+
if self.can_thinking_budget and prompt.options.thinking_budget is not None:
|
321
|
+
generation_config["thinking_config"] = {
|
322
|
+
"thinking_budget": prompt.options.thinking_budget
|
273
323
|
}
|
274
324
|
|
275
325
|
config_map = {
|
@@ -279,16 +329,17 @@ class _SharedGemini:
|
|
279
329
|
"top_k": "topK",
|
280
330
|
}
|
281
331
|
if prompt.options and prompt.options.json_object:
|
282
|
-
|
332
|
+
generation_config["response_mime_type"] = "application/json"
|
283
333
|
|
284
334
|
if any(
|
285
335
|
getattr(prompt.options, key, None) is not None for key in config_map.keys()
|
286
336
|
):
|
287
|
-
generation_config = {}
|
288
337
|
for key, other_key in config_map.items():
|
289
338
|
config_value = getattr(prompt.options, key, None)
|
290
339
|
if config_value is not None:
|
291
340
|
generation_config[other_key] = config_value
|
341
|
+
|
342
|
+
if generation_config:
|
292
343
|
body["generationConfig"] = generation_config
|
293
344
|
|
294
345
|
return body
|
@@ -458,9 +509,12 @@ def register_commands(cli):
|
|
458
509
|
def models(key):
|
459
510
|
"List of Gemini models pulled from their API"
|
460
511
|
key = llm.get_key(key, "gemini", "LLM_GEMINI_KEY")
|
461
|
-
|
462
|
-
|
463
|
-
|
512
|
+
if not key:
|
513
|
+
raise click.ClickException(
|
514
|
+
"You must set the LLM_GEMINI_KEY environment variable or use --key"
|
515
|
+
)
|
516
|
+
url = f"https://generativelanguage.googleapis.com/v1beta/models"
|
517
|
+
response = httpx.get(url, headers={"x-goog-api-key": key})
|
464
518
|
response.raise_for_status()
|
465
519
|
click.echo(json.dumps(response.json()["models"], indent=2))
|
466
520
|
|
@@ -1,4 +1,6 @@
|
|
1
|
+
from click.testing import CliRunner
|
1
2
|
import llm
|
3
|
+
from llm.cli import cli
|
2
4
|
import nest_asyncio
|
3
5
|
import json
|
4
6
|
import os
|
@@ -210,3 +212,22 @@ def test_cleanup_schema(schema, expected):
|
|
210
212
|
# Use a deep copy so the original test data remains unchanged.
|
211
213
|
result = cleanup_schema(schema)
|
212
214
|
assert result == expected
|
215
|
+
|
216
|
+
|
217
|
+
@pytest.mark.vcr
|
218
|
+
def test_cli_gemini_models(tmpdir, monkeypatch):
|
219
|
+
user_dir = tmpdir / "llm.datasette.io"
|
220
|
+
user_dir.mkdir()
|
221
|
+
monkeypatch.setenv("LLM_USER_PATH", str(user_dir))
|
222
|
+
# With no key set should error nicely
|
223
|
+
runner = CliRunner()
|
224
|
+
result = runner.invoke(cli, ["gemini", "models"])
|
225
|
+
assert result.exit_code == 1
|
226
|
+
assert (
|
227
|
+
"Error: You must set the LLM_GEMINI_KEY environment variable or use --key\n"
|
228
|
+
== result.output
|
229
|
+
)
|
230
|
+
# Try again with --key
|
231
|
+
result2 = runner.invoke(cli, ["gemini", "models", "--key", GEMINI_API_KEY])
|
232
|
+
assert result2.exit_code == 0
|
233
|
+
assert "gemini-1.5-flash-latest" in result2.output
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|