lm-deluge 0.0.63__tar.gz → 0.0.65__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 (81) hide show
  1. {lm_deluge-0.0.63/src/lm_deluge.egg-info → lm_deluge-0.0.65}/PKG-INFO +1 -1
  2. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/pyproject.toml +1 -1
  3. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/tool.py +57 -1
  4. {lm_deluge-0.0.63 → lm_deluge-0.0.65/src/lm_deluge.egg-info}/PKG-INFO +1 -1
  5. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/LICENSE +0 -0
  6. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/README.md +0 -0
  7. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/setup.cfg +0 -0
  8. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/__init__.py +0 -0
  9. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/__init__.py +0 -0
  10. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/anthropic.py +0 -0
  11. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/base.py +0 -0
  12. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/bedrock.py +0 -0
  13. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/common.py +0 -0
  14. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
  15. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
  16. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
  17. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
  18. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
  19. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/gemini.py +0 -0
  20. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/mistral.py +0 -0
  21. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/openai.py +0 -0
  22. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/api_requests/response.py +0 -0
  23. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/batches.py +0 -0
  24. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
  25. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
  26. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
  27. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
  28. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/base.py +0 -0
  29. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/built_in_tools/openai.py +0 -0
  30. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/cache.py +0 -0
  31. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/cli.py +0 -0
  32. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/client.py +0 -0
  33. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/config.py +0 -0
  34. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/embed.py +0 -0
  35. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/errors.py +0 -0
  36. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/file.py +0 -0
  37. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/image.py +0 -0
  38. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/__init__.py +0 -0
  39. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/classify.py +0 -0
  40. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/extract.py +0 -0
  41. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/locate.py +0 -0
  42. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/ocr.py +0 -0
  43. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/score.py +0 -0
  44. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/llm_tools/translate.py +0 -0
  45. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/__init__.py +0 -0
  46. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/anthropic.py +0 -0
  47. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/bedrock.py +0 -0
  48. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/cerebras.py +0 -0
  49. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/cohere.py +0 -0
  50. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/deepseek.py +0 -0
  51. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/fireworks.py +0 -0
  52. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/google.py +0 -0
  53. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/grok.py +0 -0
  54. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/groq.py +0 -0
  55. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/meta.py +0 -0
  56. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/mistral.py +0 -0
  57. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/openai.py +0 -0
  58. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/openrouter.py +0 -0
  59. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/models/together.py +0 -0
  60. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/presets/cerebras.py +0 -0
  61. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/presets/meta.py +0 -0
  62. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/prompt.py +0 -0
  63. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/request_context.py +0 -0
  64. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/rerank.py +0 -0
  65. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/tracker.py +0 -0
  66. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/usage.py +0 -0
  67. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/harmony.py +0 -0
  68. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/json.py +0 -0
  69. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/logprobs.py +0 -0
  70. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/spatial.py +0 -0
  71. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/validation.py +0 -0
  72. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/util/xml.py +0 -0
  73. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge/warnings.py +0 -0
  74. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge.egg-info/SOURCES.txt +0 -0
  75. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
  76. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge.egg-info/requires.txt +0 -0
  77. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/src/lm_deluge.egg-info/top_level.txt +0 -0
  78. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/tests/test_builtin_tools.py +0 -0
  79. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/tests/test_file_upload.py +0 -0
  80. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/tests/test_native_mcp_server.py +0 -0
  81. {lm_deluge-0.0.63 → lm_deluge-0.0.65}/tests/test_openrouter_generic.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.63
3
+ Version: 0.0.65
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.63"
6
+ version = "0.0.65"
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"
@@ -239,6 +239,9 @@ async def _load_all_mcp_tools(client: Client) -> list["Tool"]:
239
239
 
240
240
  tools: list[Tool] = []
241
241
  for m in metas:
242
+ # Extract definitions from the schema (could be $defs or definitions)
243
+ definitions = m.inputSchema.get("$defs") or m.inputSchema.get("definitions")
244
+
242
245
  tools.append(
243
246
  Tool(
244
247
  name=m.name,
@@ -246,6 +249,7 @@ async def _load_all_mcp_tools(client: Client) -> list["Tool"]:
246
249
  parameters=m.inputSchema.get("properties", {}),
247
250
  required=m.inputSchema.get("required", []),
248
251
  additionalProperties=m.inputSchema.get("additionalProperties"),
252
+ definitions=definitions,
249
253
  run=make_runner(m.name),
250
254
  )
251
255
  )
@@ -268,6 +272,8 @@ class Tool(BaseModel):
268
272
  is_built_in: bool = False
269
273
  type: str | None = None
270
274
  built_in_args: dict[str, Any] = Field(default_factory=dict)
275
+ # JSON Schema definitions (for $ref support)
276
+ definitions: dict[str, Any] | None = None
271
277
 
272
278
  @field_validator("name")
273
279
  @classmethod
@@ -562,13 +568,42 @@ class Tool(BaseModel):
562
568
  """
563
569
  return _python_type_to_json_schema_enhanced(python_type)
564
570
 
571
+ def _is_strict_mode_compatible(self) -> bool:
572
+ """
573
+ Check if this tool's schema is compatible with OpenAI strict mode.
574
+ Strict mode requires all objects to have defined properties.
575
+ """
576
+
577
+ def has_undefined_objects(schema: dict | list | Any) -> bool:
578
+ """Recursively check for objects without defined properties."""
579
+ if isinstance(schema, dict):
580
+ # Check if this is an object type without properties
581
+ if schema.get("type") == "object":
582
+ # If additionalProperties is True or properties is missing/empty
583
+ if schema.get("additionalProperties") is True:
584
+ return True
585
+ if "properties" not in schema or not schema["properties"]:
586
+ return True
587
+ # Recursively check nested schemas
588
+ for value in schema.values():
589
+ if has_undefined_objects(value):
590
+ return True
591
+ elif isinstance(schema, list):
592
+ for item in schema:
593
+ if has_undefined_objects(item):
594
+ return True
595
+ return False
596
+
597
+ return not has_undefined_objects(self.parameters or {})
598
+
565
599
  def _json_schema(
566
600
  self, include_additional_properties=False, remove_defaults=False
567
601
  ) -> dict[str, Any]:
568
602
  def _add_additional_properties_recursive(
569
603
  schema: dict | list | Any, remove_defaults: bool = False
570
604
  ) -> dict | list | Any:
571
- """Recursively add additionalProperties: false to all object-type schemas."""
605
+ """Recursively add additionalProperties: false to all object-type schemas.
606
+ In strict mode (when remove_defaults=True), also makes all properties required."""
572
607
  if isinstance(schema, dict):
573
608
  # Copy the dictionary to avoid modifying the original
574
609
  new_schema = schema.copy()
@@ -584,6 +619,10 @@ class Tool(BaseModel):
584
619
  if new_schema.get("type") == "object":
585
620
  new_schema["additionalProperties"] = False
586
621
 
622
+ # In strict mode, all properties must be required
623
+ if remove_defaults and "properties" in new_schema:
624
+ new_schema["required"] = list(new_schema["properties"].keys())
625
+
587
626
  # Remove default values if requested (for strict mode)
588
627
  if remove_defaults and "default" in new_schema:
589
628
  del new_schema["default"]
@@ -614,6 +653,14 @@ class Tool(BaseModel):
614
653
  else:
615
654
  processed_parameters = self.parameters
616
655
 
656
+ # Process definitions too
657
+ if self.definitions and include_additional_properties:
658
+ processed_definitions = _add_additional_properties_recursive(
659
+ self.definitions, remove_defaults
660
+ )
661
+ else:
662
+ processed_definitions = self.definitions
663
+
617
664
  res = {
618
665
  "type": "object",
619
666
  "properties": processed_parameters,
@@ -623,6 +670,10 @@ class Tool(BaseModel):
623
670
  if include_additional_properties:
624
671
  res["additionalProperties"] = False
625
672
 
673
+ # Include definitions if present (for $ref support)
674
+ if processed_definitions:
675
+ res["$defs"] = processed_definitions
676
+
626
677
  return res
627
678
 
628
679
  # ---------- dumpers ----------
@@ -631,6 +682,11 @@ class Tool(BaseModel):
631
682
  ) -> dict[str, Any]:
632
683
  if self.is_built_in:
633
684
  return {"type": self.type, **self.built_in_args, **kwargs}
685
+
686
+ # Check if schema is compatible with strict mode
687
+ if strict and not self._is_strict_mode_compatible():
688
+ strict = False
689
+
634
690
  if strict:
635
691
  # For strict mode, remove defaults and make all parameters required
636
692
  schema = self._json_schema(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.63
3
+ Version: 0.0.65
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