llm-gemini 0.13a0__py3-none-any.whl → 0.13.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: llm-gemini
3
- Version: 0.13a0
3
+ Version: 0.13.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
@@ -11,7 +11,7 @@ Project-URL: CI, https://github.com/simonw/llm-gemini/actions
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: llm>=0.23a0
14
+ Requires-Dist: llm>=0.23
15
15
  Requires-Dist: httpx
16
16
  Requires-Dist: ijson
17
17
  Provides-Extra: test
@@ -0,0 +1,7 @@
1
+ llm_gemini.py,sha256=JWaRtT8vJzdxrRbCAgoNrKqes2df_T4gqqeDmiw0oRI,14370
2
+ llm_gemini-0.13.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
3
+ llm_gemini-0.13.1.dist-info/METADATA,sha256=S87OFYnm9K0EVvJIRrJoZT-J0gxhPA4BrnIGkVD8q8c,7016
4
+ llm_gemini-0.13.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
5
+ llm_gemini-0.13.1.dist-info/entry_points.txt,sha256=n544bpgUPIBc5l_cnwsTxPc3gMGJHPtAyqBNp-CkMWk,26
6
+ llm_gemini-0.13.1.dist-info/top_level.txt,sha256=WUQmG6_2QKbT_8W4HH93qyKl_0SUteL4Ra6_PhyNGKU,11
7
+ llm_gemini-0.13.1.dist-info/RECORD,,
llm_gemini.py CHANGED
@@ -65,8 +65,16 @@ def register_models(register):
65
65
  ]:
66
66
  can_google_search = model_id in GOOGLE_SEARCH_MODELS
67
67
  register(
68
- GeminiPro(model_id, can_google_search=can_google_search),
69
- AsyncGeminiPro(model_id, can_google_search=can_google_search),
68
+ GeminiPro(
69
+ model_id,
70
+ can_google_search=can_google_search,
71
+ can_schema="flash-thinking" not in model_id,
72
+ ),
73
+ AsyncGeminiPro(
74
+ model_id,
75
+ can_google_search=can_google_search,
76
+ can_schema="flash-thinking" not in model_id,
77
+ ),
70
78
  )
71
79
 
72
80
 
@@ -82,7 +90,7 @@ def resolve_type(attachment):
82
90
 
83
91
  def cleanup_schema(schema):
84
92
  "Gemini supports only a subset of JSON schema"
85
- keys_to_remove = ("$schema", "additionalProperties")
93
+ keys_to_remove = ("$schema", "additionalProperties", "title")
86
94
  # Recursively remove them
87
95
  if isinstance(schema, dict):
88
96
  for key in keys_to_remove:
@@ -186,9 +194,10 @@ class _SharedGemini:
186
194
  default=None,
187
195
  )
188
196
 
189
- def __init__(self, model_id, can_google_search=False):
197
+ def __init__(self, model_id, can_google_search=False, can_schema=False):
190
198
  self.model_id = model_id
191
199
  self.can_google_search = can_google_search
200
+ self.supports_schema = can_schema
192
201
  if can_google_search:
193
202
  self.Options = self.OptionsWithGoogleSearch
194
203
 
@@ -279,9 +288,17 @@ class _SharedGemini:
279
288
  return f'```\n{part["codeExecutionResult"]["output"].strip()}\n```\n'
280
289
  return ""
281
290
 
291
+ def process_candidates(self, candidates):
292
+ # We only use the first candidate
293
+ for part in candidates[0]["content"]["parts"]:
294
+ yield self.process_part(part)
295
+
282
296
  def set_usage(self, response):
283
297
  try:
284
- usage = response.response_json[-1].pop("usageMetadata")
298
+ # Don't record the "content" key from that last candidate
299
+ for candidate in response.response_json["candidates"]:
300
+ candidate.pop("content", None)
301
+ usage = response.response_json.pop("usageMetadata")
285
302
  input_tokens = usage.pop("promptTokenCount", None)
286
303
  output_tokens = usage.pop("candidatesTokenCount", None)
287
304
  usage.pop("totalTokenCount", None)
@@ -311,17 +328,16 @@ class GeminiPro(_SharedGemini, llm.KeyModel):
311
328
  for chunk in http_response.iter_bytes():
312
329
  coro.send(chunk)
313
330
  if events:
314
- event = events[0]
315
- if isinstance(event, dict) and "error" in event:
316
- raise llm.ModelError(event["error"]["message"])
317
- try:
318
- part = event["candidates"][0]["content"]["parts"][0]
319
- yield self.process_part(part)
320
- except KeyError:
321
- yield ""
322
- gathered.append(event)
331
+ for event in events:
332
+ if isinstance(event, dict) and "error" in event:
333
+ raise llm.ModelError(event["error"]["message"])
334
+ try:
335
+ yield from self.process_candidates(event["candidates"])
336
+ except KeyError:
337
+ yield ""
338
+ gathered.append(event)
323
339
  events.clear()
324
- response.response_json = gathered
340
+ response.response_json = gathered[-1]
325
341
  self.set_usage(response)
326
342
 
327
343
 
@@ -344,17 +360,19 @@ class AsyncGeminiPro(_SharedGemini, llm.AsyncKeyModel):
344
360
  async for chunk in http_response.aiter_bytes():
345
361
  coro.send(chunk)
346
362
  if events:
347
- event = events[0]
348
- if isinstance(event, dict) and "error" in event:
349
- raise llm.ModelError(event["error"]["message"])
350
- try:
351
- part = event["candidates"][0]["content"]["parts"][0]
352
- yield self.process_part(part)
353
- except KeyError:
354
- yield ""
355
- gathered.append(event)
363
+ for event in events:
364
+ if isinstance(event, dict) and "error" in event:
365
+ raise llm.ModelError(event["error"]["message"])
366
+ try:
367
+ for chunk in self.process_candidates(
368
+ event["candidates"]
369
+ ):
370
+ yield chunk
371
+ except KeyError:
372
+ yield ""
373
+ gathered.append(event)
356
374
  events.clear()
357
- response.response_json = gathered
375
+ response.response_json = gathered[-1]
358
376
  self.set_usage(response)
359
377
 
360
378
 
@@ -1,7 +0,0 @@
1
- llm_gemini.py,sha256=M4_OIzaF3ytfrCdQ_md9sS6ViDN38JlP9aaykY5Ct0E,13634
2
- llm_gemini-0.13a0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
3
- llm_gemini-0.13a0.dist-info/METADATA,sha256=_SbfjPGKz4M4Wfvd6p8zyx37qOF99R-aTBxGQ0lnGHY,7018
4
- llm_gemini-0.13a0.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
5
- llm_gemini-0.13a0.dist-info/entry_points.txt,sha256=n544bpgUPIBc5l_cnwsTxPc3gMGJHPtAyqBNp-CkMWk,26
6
- llm_gemini-0.13a0.dist-info/top_level.txt,sha256=WUQmG6_2QKbT_8W4HH93qyKl_0SUteL4Ra6_PhyNGKU,11
7
- llm_gemini-0.13a0.dist-info/RECORD,,