llm-gemini 0.14__tar.gz → 0.15__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.14 → llm_gemini-0.15}/PKG-INFO +2 -1
- {llm_gemini-0.14 → llm_gemini-0.15}/README.md +1 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/PKG-INFO +2 -1
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.py +36 -8
- {llm_gemini-0.14 → llm_gemini-0.15}/pyproject.toml +5 -1
- {llm_gemini-0.14 → llm_gemini-0.15}/tests/test_gemini.py +87 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/LICENSE +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/SOURCES.txt +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/dependency_links.txt +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/entry_points.txt +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/requires.txt +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/llm_gemini.egg-info/top_level.txt +0 -0
- {llm_gemini-0.14 → llm_gemini-0.15}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: llm-gemini
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.15
|
4
4
|
Summary: LLM plugin to access Google's Gemini family of models
|
5
5
|
Author: Simon Willison
|
6
6
|
License: Apache-2.0
|
@@ -72,6 +72,7 @@ Other models are:
|
|
72
72
|
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
73
73
|
- `gemini-2.0-flash-lite` - Gemini 2.0 Flash-Lite
|
74
74
|
- `gemini-2.0-pro-exp-02-05` - experimental release of Gemini 2.0 Pro
|
75
|
+
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
75
76
|
|
76
77
|
### Images, audio and video
|
77
78
|
|
@@ -50,6 +50,7 @@ Other models are:
|
|
50
50
|
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
51
51
|
- `gemini-2.0-flash-lite` - Gemini 2.0 Flash-Lite
|
52
52
|
- `gemini-2.0-pro-exp-02-05` - experimental release of Gemini 2.0 Pro
|
53
|
+
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
53
54
|
|
54
55
|
### Images, audio and video
|
55
56
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: llm-gemini
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.15
|
4
4
|
Summary: LLM plugin to access Google's Gemini family of models
|
5
5
|
Author: Simon Willison
|
6
6
|
License: Apache-2.0
|
@@ -72,6 +72,7 @@ Other models are:
|
|
72
72
|
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
73
73
|
- `gemini-2.0-flash-lite` - Gemini 2.0 Flash-Lite
|
74
74
|
- `gemini-2.0-pro-exp-02-05` - experimental release of Gemini 2.0 Pro
|
75
|
+
- `gemma-3-27b-it` - [Gemma 3](https://blog.google/technology/developers/gemma-3/) 27B
|
75
76
|
|
76
77
|
### Images, audio and video
|
77
78
|
|
@@ -1,6 +1,8 @@
|
|
1
|
+
import click
|
1
2
|
import copy
|
2
3
|
import httpx
|
3
4
|
import ijson
|
5
|
+
import json
|
4
6
|
import llm
|
5
7
|
from pydantic import Field
|
6
8
|
from typing import Optional
|
@@ -62,6 +64,8 @@ def register_models(register):
|
|
62
64
|
"gemini-2.0-pro-exp-02-05",
|
63
65
|
# Released 25th Feb 2025:
|
64
66
|
"gemini-2.0-flash-lite",
|
67
|
+
# Released 12th March 2025:
|
68
|
+
"gemma-3-27b-it",
|
65
69
|
]:
|
66
70
|
can_google_search = model_id in GOOGLE_SEARCH_MODELS
|
67
71
|
register(
|
@@ -88,18 +92,24 @@ def resolve_type(attachment):
|
|
88
92
|
return mime_type
|
89
93
|
|
90
94
|
|
91
|
-
def cleanup_schema(schema):
|
95
|
+
def cleanup_schema(schema, in_properties=False):
|
92
96
|
"Gemini supports only a subset of JSON schema"
|
93
97
|
keys_to_remove = ("$schema", "additionalProperties", "title")
|
94
|
-
|
98
|
+
|
95
99
|
if isinstance(schema, dict):
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
# Only remove keys if we're not inside a 'properties' block.
|
101
|
+
if not in_properties:
|
102
|
+
for key in keys_to_remove:
|
103
|
+
schema.pop(key, None)
|
104
|
+
for key, value in list(schema.items()):
|
105
|
+
# If the key is 'properties', set the flag for its value.
|
106
|
+
if key == "properties" and isinstance(value, dict):
|
107
|
+
cleanup_schema(value, in_properties=True)
|
108
|
+
else:
|
109
|
+
cleanup_schema(value, in_properties=in_properties)
|
100
110
|
elif isinstance(schema, list):
|
101
|
-
for
|
102
|
-
cleanup_schema(
|
111
|
+
for item in schema:
|
112
|
+
cleanup_schema(item, in_properties=in_properties)
|
103
113
|
return schema
|
104
114
|
|
105
115
|
|
@@ -431,3 +441,21 @@ class GeminiEmbeddingModel(llm.EmbeddingModel):
|
|
431
441
|
if self.truncate:
|
432
442
|
values = [value[: self.truncate] for value in values]
|
433
443
|
return values
|
444
|
+
|
445
|
+
|
446
|
+
@llm.hookimpl
|
447
|
+
def register_commands(cli):
|
448
|
+
@cli.group()
|
449
|
+
def gemini():
|
450
|
+
"Commands relating to the llm-gemini plugin"
|
451
|
+
|
452
|
+
@gemini.command()
|
453
|
+
@click.option("--key", help="API key to use")
|
454
|
+
def models(key):
|
455
|
+
"List of Gemini models pulled from their API"
|
456
|
+
key = llm.get_key(key, "gemini", "LLM_GEMINI_KEY")
|
457
|
+
response = httpx.get(
|
458
|
+
f"https://generativelanguage.googleapis.com/v1beta/models?key={key}",
|
459
|
+
)
|
460
|
+
response.raise_for_status()
|
461
|
+
click.echo(json.dumps(response.json(), indent=2))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "llm-gemini"
|
3
|
-
version = "0.
|
3
|
+
version = "0.15"
|
4
4
|
description = "LLM plugin to access Google's Gemini family of models"
|
5
5
|
readme = "README.md"
|
6
6
|
authors = [{name = "Simon Willison"}]
|
@@ -25,3 +25,7 @@ gemini = "llm_gemini"
|
|
25
25
|
|
26
26
|
[project.optional-dependencies]
|
27
27
|
test = ["pytest", "pytest-recording", "pytest-asyncio", "nest-asyncio"]
|
28
|
+
|
29
|
+
[tool.pytest.ini_options]
|
30
|
+
asyncio_mode = "strict"
|
31
|
+
asyncio_default_fixture_loop_scope = "function"
|
@@ -4,6 +4,7 @@ import json
|
|
4
4
|
import os
|
5
5
|
import pytest
|
6
6
|
import pydantic
|
7
|
+
from llm_gemini import cleanup_schema
|
7
8
|
|
8
9
|
nest_asyncio.apply()
|
9
10
|
|
@@ -123,3 +124,89 @@ def test_embedding(model_id, monkeypatch):
|
|
123
124
|
elif model_id.endswith("-512"):
|
124
125
|
expected_length = 512
|
125
126
|
assert len(response) == expected_length
|
127
|
+
|
128
|
+
|
129
|
+
@pytest.mark.parametrize(
|
130
|
+
"schema,expected",
|
131
|
+
[
|
132
|
+
# Test 1: Top-level keys removal
|
133
|
+
(
|
134
|
+
{
|
135
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
136
|
+
"title": "Example Schema",
|
137
|
+
"additionalProperties": False,
|
138
|
+
"type": "object",
|
139
|
+
},
|
140
|
+
{"type": "object"},
|
141
|
+
),
|
142
|
+
# Test 2: Preserve keys within a "properties" block
|
143
|
+
(
|
144
|
+
{
|
145
|
+
"type": "object",
|
146
|
+
"properties": {
|
147
|
+
"authors": {"type": "string"},
|
148
|
+
"title": {"type": "string"},
|
149
|
+
"reference": {"type": "string"},
|
150
|
+
"year": {"type": "string"},
|
151
|
+
},
|
152
|
+
"title": "This should be removed from the top-level",
|
153
|
+
},
|
154
|
+
{
|
155
|
+
"type": "object",
|
156
|
+
"properties": {
|
157
|
+
"authors": {"type": "string"},
|
158
|
+
"title": {"type": "string"},
|
159
|
+
"reference": {"type": "string"},
|
160
|
+
"year": {"type": "string"},
|
161
|
+
},
|
162
|
+
},
|
163
|
+
),
|
164
|
+
# Test 3: Nested keys outside and inside properties block
|
165
|
+
(
|
166
|
+
{
|
167
|
+
"definitions": {
|
168
|
+
"info": {
|
169
|
+
"title": "Info title", # should be removed because it's not inside a "properties" block
|
170
|
+
"description": "A description",
|
171
|
+
"properties": {
|
172
|
+
"name": {
|
173
|
+
"title": "Name Title",
|
174
|
+
"type": "string",
|
175
|
+
}, # title here should be preserved
|
176
|
+
"$schema": {
|
177
|
+
"type": "string"
|
178
|
+
}, # should be preserved as it's within properties
|
179
|
+
},
|
180
|
+
}
|
181
|
+
},
|
182
|
+
"$schema": "http://example.com/schema",
|
183
|
+
},
|
184
|
+
{
|
185
|
+
"definitions": {
|
186
|
+
"info": {
|
187
|
+
"description": "A description",
|
188
|
+
"properties": {
|
189
|
+
"name": {"title": "Name Title", "type": "string"},
|
190
|
+
"$schema": {"type": "string"},
|
191
|
+
},
|
192
|
+
}
|
193
|
+
}
|
194
|
+
},
|
195
|
+
),
|
196
|
+
# Test 4: List of schemas
|
197
|
+
(
|
198
|
+
[
|
199
|
+
{
|
200
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
201
|
+
"type": "object",
|
202
|
+
},
|
203
|
+
{"title": "Should be removed", "type": "array"},
|
204
|
+
],
|
205
|
+
[{"type": "object"}, {"type": "array"}],
|
206
|
+
),
|
207
|
+
],
|
208
|
+
)
|
209
|
+
def test_cleanup_schema(schema, expected):
|
210
|
+
# Use a deep copy so the original test data remains unchanged.
|
211
|
+
result = cleanup_schema(schema)
|
212
|
+
assert result == expected
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|