mirascope 1.21.0__py3-none-any.whl → 1.21.2__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.
@@ -70,41 +70,50 @@ class GoogleTool(BaseTool):
70
70
  fn["parameters"] = model_schema
71
71
 
72
72
  if "parameters" in fn:
73
- # Resolve $defs and $ref
73
+ # Define a function to handle both ref resolution and examples conversion
74
+ def resolve_refs_and_fix_examples(
75
+ schema: dict[str, Any], defs: dict[str, Any] | None = None
76
+ ) -> dict[str, Any]:
77
+ """Recursively resolve $ref references and fix examples/example fields."""
78
+ # If this is a reference, resolve it
79
+ if "$ref" in schema:
80
+ ref = schema["$ref"]
81
+ if ref.startswith("#/$defs/") and defs:
82
+ ref_key = ref.replace("#/$defs/", "")
83
+ if ref_key in defs:
84
+ # Merge the definition with the current schema (excluding $ref)
85
+ resolved = {
86
+ **{k: v for k, v in schema.items() if k != "$ref"},
87
+ **resolve_refs_and_fix_examples(defs[ref_key], defs),
88
+ }
89
+ return resolved
90
+
91
+ # Handle examples -> example conversion
92
+ result = {}
93
+ for key, value in schema.items():
94
+ # Convert "examples" to "example" for Google Schema
95
+ if key == "examples":
96
+ result["example"] = value
97
+ elif isinstance(value, dict):
98
+ result[key] = resolve_refs_and_fix_examples(value, defs)
99
+ elif isinstance(value, list):
100
+ result[key] = [
101
+ resolve_refs_and_fix_examples(item, defs)
102
+ if isinstance(item, dict)
103
+ else item
104
+ for item in value
105
+ ]
106
+ else:
107
+ result[key] = value
108
+ return result
109
+
110
+ # Extract $defs if they exist
111
+ defs = {}
74
112
  if "$defs" in fn["parameters"]:
75
113
  defs = fn["parameters"].pop("$defs")
76
114
 
77
- def resolve_refs(schema: dict[str, Any]) -> dict[str, Any]:
78
- """Recursively resolve $ref references using the $defs dictionary."""
79
- # If this is a reference, resolve it
80
- if "$ref" in schema:
81
- ref = schema["$ref"]
82
- if ref.startswith("#/$defs/"):
83
- ref_key = ref.replace("#/$defs/", "")
84
- if ref_key in defs:
85
- # Merge the definition with the current schema (excluding $ref)
86
- resolved = {
87
- **{k: v for k, v in schema.items() if k != "$ref"},
88
- **resolve_refs(defs[ref_key]),
89
- }
90
- return resolved
91
-
92
- # Process all other keys recursively
93
- result = {}
94
- for key, value in schema.items():
95
- if isinstance(value, dict):
96
- result[key] = resolve_refs(value)
97
- elif isinstance(value, list):
98
- result[key] = [
99
- resolve_refs(item) if isinstance(item, dict) else item
100
- for item in value
101
- ]
102
- else:
103
- result[key] = value
104
- return result
105
-
106
- # Resolve all references in the parameters
107
- fn["parameters"] = resolve_refs(fn["parameters"])
115
+ # Resolve all references in the parameters and fix examples
116
+ fn["parameters"] = resolve_refs_and_fix_examples(fn["parameters"], defs)
108
117
 
109
118
  def handle_enum_schema(prop_schema: dict[str, Any]) -> dict[str, Any]:
110
119
  if "enum" in prop_schema:
@@ -112,6 +121,7 @@ class GoogleTool(BaseTool):
112
121
  return prop_schema
113
122
 
114
123
  # Process properties after resolving references
124
+ # We're already handling examples -> example conversion recursively above
115
125
  fn["parameters"]["properties"] = {
116
126
  prop: {
117
127
  key: value
@@ -120,6 +130,7 @@ class GoogleTool(BaseTool):
120
130
  }
121
131
  for prop, prop_schema in fn["parameters"]["properties"].items()
122
132
  }
133
+
123
134
  return Tool(function_declarations=[FunctionDeclaration(**fn)])
124
135
 
125
136
  @classmethod
mirascope/llm/_call.py CHANGED
@@ -50,24 +50,36 @@ _ResultT = TypeVar("_ResultT")
50
50
  def _get_local_provider_call(
51
51
  provider: LocalProvider,
52
52
  client: Any | None, # noqa: ANN401
53
+ is_async: bool,
53
54
  ) -> tuple[Callable, Any | None]:
54
55
  if provider == "ollama":
55
56
  from ..core.openai import openai_call
56
57
 
57
58
  if client:
58
59
  return openai_call, client
59
- from openai import OpenAI
60
+ if is_async:
61
+ from openai import AsyncOpenAI
60
62
 
61
- client = OpenAI(api_key="ollama", base_url="http://localhost:11434/v1")
63
+ client = AsyncOpenAI(api_key="ollama", base_url="http://localhost:11434/v1")
64
+ else:
65
+ from openai import OpenAI
66
+
67
+ client = OpenAI(api_key="ollama", base_url="http://localhost:11434/v1")
62
68
  return openai_call, client
63
69
  else: # provider == "vllm"
64
70
  from ..core.openai import openai_call
65
71
 
66
72
  if client:
67
73
  return openai_call, client
68
- from openai import OpenAI
69
74
 
70
- client = OpenAI(api_key="ollama", base_url="http://localhost:8000/v1")
75
+ if is_async:
76
+ from openai import AsyncOpenAI
77
+
78
+ client = AsyncOpenAI(api_key="ollama", base_url="http://localhost:8000/v1")
79
+ else:
80
+ from openai import OpenAI
81
+
82
+ client = OpenAI(api_key="ollama", base_url="http://localhost:8000/v1")
71
83
  return openai_call, client
72
84
 
73
85
 
@@ -245,7 +257,9 @@ def _call(
245
257
 
246
258
  if effective_provider in get_args(LocalProvider):
247
259
  provider_call, effective_client = _get_local_provider_call(
248
- cast(LocalProvider, effective_provider), effective_client
260
+ cast(LocalProvider, effective_provider),
261
+ effective_client,
262
+ True,
249
263
  )
250
264
  effective_call_args["client"] = effective_client
251
265
  else:
@@ -293,7 +307,9 @@ def _call(
293
307
 
294
308
  if effective_provider in get_args(LocalProvider):
295
309
  provider_call, effective_client = _get_local_provider_call(
296
- cast(LocalProvider, effective_provider), effective_client
310
+ cast(LocalProvider, effective_provider),
311
+ effective_client,
312
+ False,
297
313
  )
298
314
  effective_call_args["client"] = effective_client
299
315
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mirascope
3
- Version: 1.21.0
3
+ Version: 1.21.2
4
4
  Summary: LLM abstractions that aren't obstructions
5
5
  Project-URL: Homepage, https://mirascope.com
6
6
  Project-URL: Documentation, https://mirascope.com/WELCOME
@@ -217,7 +217,7 @@ mirascope/core/google/call_response.py,sha256=8yn1cRtqxhnjjzLltfWMzLbaS1Dg7gmS4I
217
217
  mirascope/core/google/call_response_chunk.py,sha256=oORYaGjOBv4U1IVhsR_ZS-Vr-B58I8G0-9d6Kcj9RM4,3427
218
218
  mirascope/core/google/dynamic_config.py,sha256=O6j8F0fLVFuuNwURneu5OpPuu_bMEtbDEFHhJXRT6V0,857
219
219
  mirascope/core/google/stream.py,sha256=bTxB8OUrKXxzmcX0C7_-LqtBfaAAazA5HjKZGSxxtLw,4466
220
- mirascope/core/google/tool.py,sha256=HPe7CZEn1nPFkvuigpDiTdU9y9cQGp6R68FChjETMAU,4623
220
+ mirascope/core/google/tool.py,sha256=61a9Ejdxz41pwaab9VE2yvP_J1Aebua3BeRPJ_GJSnE,5138
221
221
  mirascope/core/google/_utils/__init__.py,sha256=vL0hx6WKW5lqpUcFTFCFGvmwtR-pts0JzWgCXhaUVrI,388
222
222
  mirascope/core/google/_utils/_convert_common_call_params.py,sha256=KA-z6uvRtdD4WydC0eXd3dzQuSh4x4WKNR8PAqFNUVY,1065
223
223
  mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py,sha256=ig4tb7Zanz-tyZpvc9Ncd47a2FNTOS7-wl1PYBq-4cY,879
@@ -332,7 +332,7 @@ mirascope/integrations/otel/_utils.py,sha256=SCVb3MpcpqLpCpumJEbEdINceNdusnyT6iu
332
332
  mirascope/integrations/otel/_with_hyperdx.py,sha256=f17uxXQk5zZPtyj6zwPwJz5i7atsnUPOoq1LqT8JO0E,1637
333
333
  mirascope/integrations/otel/_with_otel.py,sha256=tbjd6BEbcSfnsm5CWHBoHwbRNrHt6-t4or-SYGQSD-w,1659
334
334
  mirascope/llm/__init__.py,sha256=zo7QD39zQ6HIU_N2yHrzd6bbcT9YmlikZ84JN_r5k4E,397
335
- mirascope/llm/_call.py,sha256=Xv9Ok0gZjLETQUOavYOk4rapnhOqfpNGw0mxlDf-nV4,12585
335
+ mirascope/llm/_call.py,sha256=XyMMZzg_DUW1pZgVcOP0QxyVDCYW8s7Xj_XMDwCzb_w,13068
336
336
  mirascope/llm/_context.py,sha256=Q4M-XRVsAvDW2LPW2XNtCm5HRU36BLFJYuahfGMfTGI,12332
337
337
  mirascope/llm/_override.py,sha256=m4MdOhM-aJRIGP7NBJhscq3ISNct6FBPn3jjmryFo_Q,112292
338
338
  mirascope/llm/_protocols.py,sha256=HXspRAC0PduGqbh2BM0CGe5iVj7CC3ZKMPAYvFvbDNQ,16406
@@ -368,7 +368,7 @@ mirascope/v0/base/ops_utils.py,sha256=1Qq-VIwgHBaYutiZsS2MUQ4OgPC3APyywI5bTiTAmA
368
368
  mirascope/v0/base/prompts.py,sha256=FM2Yz98cSnDceYogiwPrp4BALf3_F3d4fIOCGAkd-SE,1298
369
369
  mirascope/v0/base/types.py,sha256=ZfatJoX0Yl0e3jhv0D_MhiSVHLYUeJsdN3um3iE10zY,352
370
370
  mirascope/v0/base/utils.py,sha256=XREPENRQTu8gpMhHU8RC8qH_am3FfGUvY-dJ6x8i-mw,681
371
- mirascope-1.21.0.dist-info/METADATA,sha256=3RrfjlPJIf5q2D1pf1jx9Pgrp8DBwnQYCNuGDbQ_ciE,8730
372
- mirascope-1.21.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
373
- mirascope-1.21.0.dist-info/licenses/LICENSE,sha256=LAs5Q8mdawTsVdONpDGukwsoc4KEUBmmonDEL39b23Y,1072
374
- mirascope-1.21.0.dist-info/RECORD,,
371
+ mirascope-1.21.2.dist-info/METADATA,sha256=1dvAilky26Nim8aNFd5hQEypMwSS9MfUs0grmn__v9o,8730
372
+ mirascope-1.21.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
373
+ mirascope-1.21.2.dist-info/licenses/LICENSE,sha256=LAs5Q8mdawTsVdONpDGukwsoc4KEUBmmonDEL39b23Y,1072
374
+ mirascope-1.21.2.dist-info/RECORD,,