lm-deluge 0.0.47__tar.gz → 0.0.48__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.

Potentially problematic release.


This version of lm-deluge might be problematic. Click here for more details.

Files changed (80) hide show
  1. {lm_deluge-0.0.47/src/lm_deluge.egg-info → lm_deluge-0.0.48}/PKG-INFO +1 -1
  2. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/pyproject.toml +1 -1
  3. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/cache.py +10 -1
  4. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/client.py +6 -0
  5. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/image.py +21 -0
  6. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/prompt.py +20 -9
  7. {lm_deluge-0.0.47 → lm_deluge-0.0.48/src/lm_deluge.egg-info}/PKG-INFO +1 -1
  8. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/LICENSE +0 -0
  9. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/README.md +0 -0
  10. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/setup.cfg +0 -0
  11. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/__init__.py +0 -0
  12. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/agent.py +0 -0
  13. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/__init__.py +0 -0
  14. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/anthropic.py +0 -0
  15. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/base.py +0 -0
  16. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/bedrock.py +0 -0
  17. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/common.py +0 -0
  18. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
  19. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
  20. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
  21. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
  22. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
  23. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/gemini.py +0 -0
  24. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/mistral.py +0 -0
  25. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/openai.py +0 -0
  26. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/api_requests/response.py +0 -0
  27. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/batches.py +0 -0
  28. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
  29. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
  30. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
  31. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
  32. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/base.py +0 -0
  33. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/built_in_tools/openai.py +0 -0
  34. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/cli.py +0 -0
  35. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/config.py +0 -0
  36. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/embed.py +0 -0
  37. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/errors.py +0 -0
  38. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/file.py +0 -0
  39. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/gemini_limits.py +0 -0
  40. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/__init__.py +0 -0
  41. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/classify.py +0 -0
  42. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/extract.py +0 -0
  43. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/locate.py +0 -0
  44. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/ocr.py +0 -0
  45. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/score.py +0 -0
  46. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/llm_tools/translate.py +0 -0
  47. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/__init__.py +0 -0
  48. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/anthropic.py +0 -0
  49. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/bedrock.py +0 -0
  50. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/cerebras.py +0 -0
  51. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/cohere.py +0 -0
  52. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/deepseek.py +0 -0
  53. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/fireworks.py +0 -0
  54. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/google.py +0 -0
  55. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/grok.py +0 -0
  56. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/groq.py +0 -0
  57. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/meta.py +0 -0
  58. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/mistral.py +0 -0
  59. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/openai.py +0 -0
  60. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/openrouter.py +0 -0
  61. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/models/together.py +0 -0
  62. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/presets/cerebras.py +0 -0
  63. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/presets/meta.py +0 -0
  64. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/request_context.py +0 -0
  65. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/rerank.py +0 -0
  66. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/tool.py +0 -0
  67. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/tracker.py +0 -0
  68. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/usage.py +0 -0
  69. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/harmony.py +0 -0
  70. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/json.py +0 -0
  71. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/logprobs.py +0 -0
  72. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/spatial.py +0 -0
  73. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/validation.py +0 -0
  74. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge/util/xml.py +0 -0
  75. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge.egg-info/SOURCES.txt +0 -0
  76. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
  77. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge.egg-info/requires.txt +0 -0
  78. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/src/lm_deluge.egg-info/top_level.txt +0 -0
  79. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/tests/test_builtin_tools.py +0 -0
  80. {lm_deluge-0.0.47 → lm_deluge-0.0.48}/tests/test_native_mcp_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: Python utility for using LLM API models.
5
5
  Author-email: Benjamin Anderson <ben@trytaylor.ai>
6
6
  Requires-Python: >=3.10
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "lm_deluge"
6
- version = "0.0.47"
6
+ version = "0.0.48"
7
7
  authors = [{ name = "Benjamin Anderson", email = "ben@trytaylor.ai" }]
8
8
  description = "Python utility for using LLM API models."
9
9
  readme = "README.md"
@@ -78,9 +78,18 @@ class LevelDBCache:
78
78
  Get an API response from the cache.
79
79
  """
80
80
  key = f"{self.cache_key}:{prompt.fingerprint}"
81
+ # print(f"DEBUG: Cache.get() looking for key: {key}")
81
82
  data = self.db.get(key.encode())
82
83
  if data is not None:
83
- return decode_api_response(data)
84
+ # print(f"DEBUG: Cache.get() FOUND data, calling decode_api_response")
85
+ try:
86
+ result = decode_api_response(data)
87
+ # print(f"DEBUG: Cache.get() decode_api_response returned: {type(result)}")
88
+ return result
89
+ except Exception:
90
+ # print(f"DEBUG: Cache.get() ERROR in decode_api_response: {e}")
91
+ return None
92
+ # print(f"DEBUG: Cache.get() NO data found, returning None")
84
93
  return None
85
94
 
86
95
  def put(self, prompt: Conversation, response: APIResponse):
@@ -250,12 +250,17 @@ class _LLMClient(BaseModel):
250
250
  return response
251
251
 
252
252
  if self.cache:
253
+ # print(f"DEBUG: Checking cache for prompt with {len(context.prompt.messages)} messages")
253
254
  cached = self.cache.get(context.prompt)
254
255
  if cached:
256
+ # print(f"DEBUG: Cache HIT! Returning cached response")
255
257
  cached.local_cache_hit = True
256
258
  if context.status_tracker:
257
259
  context.status_tracker.task_succeeded(context.task_id)
258
260
  return _maybe_postprocess(cached)
261
+ else:
262
+ # print(f"DEBUG: Cache MISS")
263
+ pass
259
264
 
260
265
  # Execute single request
261
266
  assert context.status_tracker
@@ -267,6 +272,7 @@ class _LLMClient(BaseModel):
267
272
  context.status_tracker.task_succeeded(context.task_id)
268
273
  # Cache successful responses immediately
269
274
  if self.cache and response.completion:
275
+ # print(f"DEBUG: Caching successful response")
270
276
  self.cache.put(context.prompt, response)
271
277
  # Call callback if provided
272
278
  context.maybe_callback(response, context.status_tracker)
@@ -23,6 +23,16 @@ class Image:
23
23
  _fingerprint_cache: str | None = field(init=False, default=None)
24
24
  _size_cache: tuple[int, int] | None = field(init=False, default=None)
25
25
 
26
+ # def __post_init__(self):
27
+ # DEBUG: Track image data at creation
28
+ # data_type = type(self.data)
29
+ # data_preview = (
30
+ # str(self.data)[:100]
31
+ # if isinstance(self.data, str)
32
+ # else f"[{data_type.__name__}]"
33
+ # )
34
+ # print(f"DEBUG: Image.__post_init__: id={id(self)}, data={data_type}, preview={data_preview}")
35
+
26
36
  def __repr__(self):
27
37
  return f"Image(data=[{type(self.data)}], media_type={self.media_type}, detail={self.detail})"
28
38
 
@@ -58,6 +68,15 @@ class Image:
58
68
 
59
69
  # helpers -----------------------------------------------------------------
60
70
  def _bytes(self) -> bytes:
71
+ # DEBUG: Track when _bytes is called and what data we have
72
+ # data_type = type(self.data)
73
+ # data_preview = (
74
+ # str(self.data)[:100]
75
+ # if isinstance(self.data, str)
76
+ # else f"[{data_type.__name__}]"
77
+ # )
78
+ # print(f"DEBUG: Image._bytes called: id={id(self)}, data={data_type}, preview={data_preview}")
79
+
61
80
  if isinstance(self.data, bytes):
62
81
  return self.data
63
82
  elif isinstance(self.data, io.BytesIO):
@@ -82,6 +101,7 @@ class Image:
82
101
  content = "[raw bytes]"
83
102
  else:
84
103
  content = f"[raw {type(self.data)}]"
104
+ # print(f"DEBUG: Image._bytes ERROR PATH: type={type(self.data)}, content={content}")
85
105
  raise ValueError(
86
106
  f"unreadable image format. type: {type(self.data)}. content: {content}"
87
107
  )
@@ -164,6 +184,7 @@ class Image:
164
184
  @property
165
185
  def fingerprint(self) -> str:
166
186
  # return base64 of a very small version of the image
187
+ # print(f"DEBUG: Image.fingerprint called, data type: {type(self.data)}")
167
188
  if self._fingerprint_cache is None:
168
189
  small_image = self._resize_longer(max_size=48) # longer side = 48px
169
190
  self._fingerprint_cache = base64.b64encode(small_image).decode("utf-8")
@@ -333,6 +333,15 @@ class Message:
333
333
  """
334
334
  Return a JSON-serialisable dict that fully captures the message.
335
335
  """
336
+
337
+ # DEBUG: Track when to_log is called
338
+ # print(f"DEBUG: Message.to_log called on {self.role} message with {len(self.parts)} parts")
339
+ # for i, part in enumerate(self.parts):
340
+ # print(f" Part {i}: {type(part)} - {part.type if hasattr(part, 'type') else 'no type'}")
341
+ # if hasattr(part, 'type') and part.type == 'image':
342
+ # print(f" Image data type: {type(part.data)}")
343
+ # data_preview = str(part.data)[:50] if isinstance(part.data, str) else f"[{type(part.data).__name__}]"
344
+ # print(f" Image data preview: {data_preview}")
336
345
  def _json_safe(value):
337
346
  if isinstance(value, (str, int, float, bool)) or value is None:
338
347
  return value
@@ -385,6 +394,8 @@ class Message:
385
394
  @classmethod
386
395
  def from_log(cls, data: dict) -> "Message":
387
396
  """Re-hydrate a Message previously produced by `to_log()`."""
397
+ # DEBUG: Track when from_log is called
398
+ # print(f"DEBUG: Message.from_log called for {data['role']} message with {len(data['content'])} content blocks")
388
399
  role: Role = data["role"]
389
400
  parts: list[Part] = []
390
401
 
@@ -392,11 +403,12 @@ class Message:
392
403
  if p["type"] == "text":
393
404
  parts.append(Text(p["text"]))
394
405
  elif p["type"] == "image":
395
- # We only stored a placeholder tag, so keep that placeholder.
396
- parts.append(Image(p["tag"], detail="low"))
406
+ # We only stored a placeholder tag; rehydrate as inert text to avoid byte access.
407
+ # print(f"DEBUG: Message.from_log creating Text placeholder for image: {p['tag']}")
408
+ parts.append(Text(p["tag"]))
397
409
  elif p["type"] == "file":
398
- # We only stored a placeholder tag, so keep that placeholder.
399
- parts.append(File(p["tag"]))
410
+ # We only stored a placeholder tag; rehydrate as inert text to avoid byte access.
411
+ parts.append(Text(p["tag"]))
400
412
  elif p["type"] == "tool_call":
401
413
  parts.append(
402
414
  ToolCall(id=p["id"], name=p["name"], arguments=p["arguments"])
@@ -974,12 +986,11 @@ class Conversation:
974
986
  if p["type"] == "text":
975
987
  parts.append(Text(p["text"]))
976
988
  elif p["type"] == "image":
977
- # We only stored a placeholder tag, so keep that placeholder.
978
- # You could raise instead if real image bytes are required.
979
- parts.append(Image(p["tag"], detail="low"))
989
+ # We only stored a placeholder tag; rehydrate as inert text to avoid byte access.
990
+ parts.append(Text(p["tag"]))
980
991
  elif p["type"] == "file":
981
- # We only stored a placeholder tag, so keep that placeholder.
982
- parts.append(File(p["tag"]))
992
+ # We only stored a placeholder tag; rehydrate as inert text to avoid byte access.
993
+ parts.append(Text(p["tag"]))
983
994
  elif p["type"] == "tool_call":
984
995
  parts.append(
985
996
  ToolCall(id=p["id"], name=p["name"], arguments=p["arguments"])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.47
3
+ Version: 0.0.48
4
4
  Summary: Python utility for using LLM API models.
5
5
  Author-email: Benjamin Anderson <ben@trytaylor.ai>
6
6
  Requires-Python: >=3.10
File without changes
File without changes
File without changes