stores 0.1.0__py3-none-any.whl → 0.1.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.
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import functools
3
2
  import inspect
4
3
  import logging
5
4
  import re
@@ -18,6 +17,8 @@ from typing import (
18
17
  get_type_hints,
19
18
  )
20
19
 
20
+ from makefun import create_function
21
+
21
22
  from stores.format import ProviderFormat, format_tools
22
23
  from stores.parse import llm_parse_json
23
24
  from stores.utils import check_duplicates
@@ -209,8 +210,15 @@ def wrap_tool(tool: Callable):
209
210
  # Inject default values within wrapper
210
211
  bound_args = original_signature.bind(*args, **kwargs)
211
212
  bound_args.apply_defaults()
212
- _cast_bound_args(bound_args)
213
213
  # Inject correct Literals
214
+ for k, v in bound_args.arguments.items():
215
+ if (
216
+ v is None
217
+ and original_signature.parameters[k].default is not Parameter.empty
218
+ ):
219
+ bound_args.arguments[k] = original_signature.parameters[k].default
220
+
221
+ _cast_bound_args(bound_args)
214
222
  for k, v in bound_args.arguments.items():
215
223
  if k in literal_maps:
216
224
  param = original_signature.parameters[k]
@@ -219,11 +227,17 @@ def wrap_tool(tool: Callable):
219
227
  )
220
228
  return tool(*bound_args.args, **bound_args.kwargs)
221
229
 
222
- functools.update_wrapper(wrapper, tool)
223
- wrapper.__signature__ = new_sig
224
- wrapper._wrapped = True
230
+ wrapped = create_function(
231
+ new_sig,
232
+ wrapper,
233
+ qualname=tool.__name__,
234
+ doc=inspect.getdoc(tool),
235
+ )
236
+
237
+ wrapped.__name__ = tool.__name__
238
+ wrapped._wrapped = True
225
239
 
226
- return wrapper
240
+ return wrapped
227
241
 
228
242
 
229
243
  class BaseIndex:
stores/indexes/index.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import os
3
3
  from pathlib import Path
4
- from typing import Callable
4
+ from typing import Callable, Optional
5
5
 
6
6
  from stores.indexes.base_index import BaseIndex
7
7
  from stores.indexes.local_index import LocalIndex
@@ -17,6 +17,8 @@ class Index(BaseIndex):
17
17
  self,
18
18
  tools: list[Callable, os.PathLike] | None = None,
19
19
  env_var: dict[str, dict] | None = None,
20
+ cache_dir: Optional[os.PathLike] = None,
21
+ reset_cache=False,
20
22
  ):
21
23
  self.env_var = env_var or {}
22
24
  tools = tools or []
@@ -38,7 +40,10 @@ class Index(BaseIndex):
38
40
  # Load RemoteIndex
39
41
  try:
40
42
  loaded_index = RemoteIndex(
41
- index_name, env_var=self.env_var.get(index_name)
43
+ index_name,
44
+ env_var=self.env_var.get(index_name),
45
+ cache_dir=cache_dir,
46
+ reset_cache=reset_cache,
42
47
  )
43
48
  except Exception:
44
49
  logger.warning(
@@ -1,7 +1,10 @@
1
1
  import json
2
2
  import logging
3
+ import shutil
3
4
  import venv
5
+ from os import PathLike
4
6
  from pathlib import Path
7
+ from typing import Optional
5
8
 
6
9
  import requests
7
10
  from git import Repo
@@ -21,6 +24,10 @@ INDEX_LOOKUP_URL = (
21
24
  )
22
25
 
23
26
 
27
+ def clear_default_cache():
28
+ shutil.rmtree(CACHE_DIR)
29
+
30
+
24
31
  def lookup_index(index_id: str, index_version: str | None = None):
25
32
  response = requests.post(
26
33
  INDEX_LOOKUP_URL,
@@ -39,11 +46,24 @@ def lookup_index(index_id: str, index_version: str | None = None):
39
46
 
40
47
 
41
48
  class RemoteIndex(BaseIndex):
42
- def __init__(self, index_id: str, env_var: dict | None = None):
49
+ def __init__(
50
+ self,
51
+ index_id: str,
52
+ env_var: dict | None = None,
53
+ cache_dir: Optional[PathLike] = None,
54
+ reset_cache=False,
55
+ ):
43
56
  self.index_id = index_id
44
- self.index_folder = CACHE_DIR / self.index_id
57
+ if cache_dir is None:
58
+ cache_dir = CACHE_DIR
59
+ else:
60
+ cache_dir = Path(cache_dir)
61
+ if reset_cache:
62
+ shutil.rmtree(cache_dir)
63
+ self.index_folder = cache_dir / self.index_id
45
64
  self.env_var = env_var or {}
46
65
  if not self.index_folder.exists():
66
+ logger.info(f"Installing {index_id}...")
47
67
  commit_like = None
48
68
  if ":" in index_id:
49
69
  index_id, commit_like = index_id.split(":")
@@ -115,44 +115,49 @@ from typing import Any, Dict, List, Literal, Tuple, Union, get_args, get_origin,
115
115
  import types as T
116
116
 
117
117
 
118
- def extract_type_info(typ):
118
+ def extract_type_info(typ, custom_types: list[str] | None = None):
119
+ custom_types = custom_types or []
120
+ if hasattr(typ, "__name__") and typ.__name__ in custom_types:
121
+ return typ.__name__
119
122
  origin = get_origin(typ)
120
123
  args = list(get_args(typ))
121
124
  if origin is Literal:
122
125
  return {{"type": "Literal", "values": args}}
123
126
  elif inspect.isclass(typ) and issubclass(typ, enum.Enum):
127
+ custom_types.append(typ.__name__)
124
128
  return {{
125
129
  "type": "Enum",
126
130
  "type_name": typ.__name__,
127
131
  "values": {{v.name: v.value for v in typ}},
128
132
  }}
129
133
  elif isinstance(typ, type) and typ.__class__.__name__ == "_TypedDictMeta":
134
+ custom_types.append(typ.__name__)
130
135
  hints = get_type_hints(typ)
131
136
  return {{
132
137
  "type": "TypedDict",
133
138
  "type_name": typ.__name__,
134
- "fields": {{k: extract_type_info(v) for k, v in hints.items()}}
139
+ "fields": {{k: extract_type_info(v, custom_types) for k, v in hints.items()}}
135
140
  }}
136
141
  elif origin in (list, List) or typ is list:
137
142
  return {{
138
143
  "type": "List",
139
- "item_type": extract_type_info(args[0]) if args else {{"type": Any}}
144
+ "item_type": extract_type_info(args[0], custom_types) if args else {{"type": Any}}
140
145
  }}
141
146
  elif origin in (dict, Dict) or typ is dict:
142
147
  return {{
143
148
  "type": "Dict",
144
- "key_type": extract_type_info(args[0]) if args else {{"type": Any}},
145
- "value_type": extract_type_info(args[1]) if len(args) > 1 else {{"type": Any}}
149
+ "key_type": extract_type_info(args[0], custom_types) if args else {{"type": Any}},
150
+ "value_type": extract_type_info(args[1], custom_types) if len(args) > 1 else {{"type": Any}}
146
151
  }}
147
152
  elif origin in (tuple, Tuple) or typ is tuple:
148
153
  return {{
149
154
  "type": "Tuple",
150
- "item_types": [extract_type_info(arg) for arg in args] if args else [{{"type": Any}}]
155
+ "item_types": [extract_type_info(arg, custom_types) for arg in args] if args else [{{"type": Any}}]
151
156
  }}
152
157
  elif origin is Union or origin is T.UnionType:
153
158
  return {{
154
159
  "type": "Union",
155
- "options": [extract_type_info(arg) for arg in args]
160
+ "options": [extract_type_info(arg, custom_types) for arg in args]
156
161
  }}
157
162
  else:
158
163
  return {{"type": typ}}
@@ -205,33 +210,39 @@ except Exception as e:
205
210
  raise RuntimeError(f"Error loading tool {tool_id}:\n{response['error']}")
206
211
 
207
212
 
208
- def parse_param_type(param_info: dict):
213
+ def parse_param_type(param_info: dict, custom_types: list[str] | None = None):
214
+ custom_types = custom_types or []
215
+ # Support ForwardRef
209
216
  param_type = param_info["type"]
217
+ if param_type in custom_types:
218
+ return param_type
210
219
  if not isinstance(param_type, str):
211
220
  return param_type
212
221
  if param_type == "Literal":
213
222
  return Literal.__getitem__(tuple(param_info["values"]))
214
223
  elif param_type == "Enum":
224
+ custom_types.append(param_info["type_name"])
215
225
  return Enum(param_info["type_name"], param_info["values"])
216
226
  elif param_type == "TypedDict":
227
+ custom_types.append(param_info["type_name"])
217
228
  properties = {}
218
229
  for k, v in param_info["fields"].items():
219
- properties[k] = parse_param_type(v)
230
+ properties[k] = parse_param_type(v, custom_types)
220
231
  return TypedDict(param_info["type_name"], properties)
221
232
  elif param_type == "List":
222
- return list[parse_param_type(param_info["item_type"])]
233
+ return list[parse_param_type(param_info["item_type"], custom_types)]
223
234
  elif param_type == "Dict":
224
235
  return Dict[
225
- parse_param_type(param_info["key_type"]),
226
- parse_param_type(param_info["value_type"]),
236
+ parse_param_type(param_info["key_type"], custom_types),
237
+ parse_param_type(param_info["value_type"], custom_types),
227
238
  ]
228
239
  elif param_type == "Tuple":
229
240
  return Tuple.__getitem__(
230
- tuple([parse_param_type(i) for i in param_info["item_types"]])
241
+ tuple([parse_param_type(i, custom_types) for i in param_info["item_types"]])
231
242
  )
232
243
  elif param_type == "Union":
233
244
  return Union.__getitem__(
234
- tuple([parse_param_type(i) for i in param_info["options"]])
245
+ tuple([parse_param_type(i, custom_types) for i in param_info["options"]])
235
246
  )
236
247
  else:
237
248
  raise TypeError(f"Invalid param type {param_type} in param info {param_info}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stores
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Repository of Python functions and tools for LLMs
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.10
@@ -0,0 +1,15 @@
1
+ stores/__init__.py,sha256=KYpKkNrMLx6ssVUbxHnn9wFBq5F5KnaFchcimIfDf9g,186
2
+ stores/constants.py,sha256=7WqFmoGCtmUKHA5WHxOJvvK7g-yYu_KGoqnuVFADNao,57
3
+ stores/format.py,sha256=LduYBVDiUDB1J1HDyu9jHrRG1V97pw6C5g76OirpJJY,7792
4
+ stores/parse.py,sha256=HYPNPzQod2vpu1Cln7yQ8aVkZT1Mw2IN0sZ2A1DIaqE,4967
5
+ stores/utils.py,sha256=GPWT6lCoGobwP3PlEOHyJfKyd0dobamjyErcR7lgm7M,242
6
+ stores/indexes/__init__.py,sha256=s-RNqml8uGREQhxwSdDoxcbcxeD8soB9BcL5dBKsQfI,215
7
+ stores/indexes/base_index.py,sha256=K4--_OAFyPNESaisD0JPNRIEffCnjw9nziahDgjdZHU,10708
8
+ stores/indexes/index.py,sha256=X8q2Pe6PCmzQ9j0KVvJmqZid1A1RB0jUe-JugcOrl7o,2330
9
+ stores/indexes/local_index.py,sha256=NS4AWzeMVZ51YPo0eJ_udbF5aASuksG-88YXLDn41fQ,2880
10
+ stores/indexes/remote_index.py,sha256=dp84keyEDyL-cQrmshwHd4QqDGMw0CTSJcQxqZQiULY,2983
11
+ stores/indexes/venv_utils.py,sha256=Nakh2L7gMXpP_0_g7pnjQkB1g-P-jUCxpWSxg68JjbQ,12388
12
+ stores-0.1.2.dist-info/METADATA,sha256=GDKpmD4EPbitZaIA2BSEu7r-CWBoo9Y7bO-90f79u6k,3076
13
+ stores-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
+ stores-0.1.2.dist-info/licenses/LICENSE,sha256=VTidYE7_Dam0Dwyq095EhhDIqi47g03oVpLAHQgKws0,1066
15
+ stores-0.1.2.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- stores/__init__.py,sha256=KYpKkNrMLx6ssVUbxHnn9wFBq5F5KnaFchcimIfDf9g,186
2
- stores/constants.py,sha256=7WqFmoGCtmUKHA5WHxOJvvK7g-yYu_KGoqnuVFADNao,57
3
- stores/format.py,sha256=LduYBVDiUDB1J1HDyu9jHrRG1V97pw6C5g76OirpJJY,7792
4
- stores/parse.py,sha256=HYPNPzQod2vpu1Cln7yQ8aVkZT1Mw2IN0sZ2A1DIaqE,4967
5
- stores/utils.py,sha256=GPWT6lCoGobwP3PlEOHyJfKyd0dobamjyErcR7lgm7M,242
6
- stores/indexes/__init__.py,sha256=s-RNqml8uGREQhxwSdDoxcbcxeD8soB9BcL5dBKsQfI,215
7
- stores/indexes/base_index.py,sha256=1DP3cb1njE-MHuVXHVlyQlao2APeyWjRA2VT4RwW6BU,10293
8
- stores/indexes/index.py,sha256=ckyisaoD_0Uw3dWXpMYYhNWxMXcfykwJIY8lUdpNntA,2113
9
- stores/indexes/local_index.py,sha256=NS4AWzeMVZ51YPo0eJ_udbF5aASuksG-88YXLDn41fQ,2880
10
- stores/indexes/remote_index.py,sha256=-iKO0q9MS1CiyzY1lu90FxHs0pVR6z82_7Lk7jX9wFk,2523
11
- stores/indexes/venv_utils.py,sha256=odeKBphn6H2Jwz6pyy4pvEZFB48Kd1rroAuMiJjcPLE,11696
12
- stores-0.1.0.dist-info/METADATA,sha256=EyJIq_xAsOTaBc0h5dh3H_N58qlXS5CvP4BwIakuOK8,3076
13
- stores-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
- stores-0.1.0.dist-info/licenses/LICENSE,sha256=VTidYE7_Dam0Dwyq095EhhDIqi47g03oVpLAHQgKws0,1066
15
- stores-0.1.0.dist-info/RECORD,,
File without changes