toolslm 0.3.8__py3-none-any.whl → 0.3.10__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.
toolslm/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.8"
1
+ __version__ = "0.3.10"
toolslm/funccall.py CHANGED
@@ -5,7 +5,7 @@ __all__ = ['empty', 'custom_types', 'get_schema', 'python', 'mk_ns', 'call_func'
5
5
  'mk_tool']
6
6
 
7
7
  # %% ../01_funccall.ipynb
8
- import inspect, json
8
+ import inspect, json, ast
9
9
  from collections import abc
10
10
  from fastcore.utils import *
11
11
  from fastcore.docments import docments
@@ -37,12 +37,20 @@ def _types(t:type)->tuple[str,Optional[str]]:
37
37
  else: return tmap.get(t.__name__, "object"), None
38
38
 
39
39
  # %% ../01_funccall.ipynb
40
- def _param(name, info):
41
- "json schema parameter given `name` and `info` from docments full dict."
40
+ def _param(
41
+ name, # param name
42
+ info, # dict from docments
43
+ evalable=False): # stringify defaults that can't be literal_eval'd?
44
+ "json schema parameter given `name` and `info` from docments full dict"
42
45
  paramt,itemt = _types(info.anno)
43
46
  pschema = dict(type=paramt, description=info.docment or "")
44
47
  if itemt: pschema["items"] = {"type": itemt}
45
- if info.default is not empty: pschema["default"] = info.default
48
+ if info.default is not empty:
49
+ if evalable:
50
+ try: ast.literal_eval(repr(info.default))
51
+ except: pschema["default"] = str(info.default)
52
+ else: pschema["default"] = info.default
53
+ else: pschema["default"] = info.default
46
54
  return pschema
47
55
 
48
56
  # %% ../01_funccall.ipynb
@@ -90,9 +98,9 @@ def _handle_container(origin, args, defs):
90
98
  return None
91
99
 
92
100
  # %% ../01_funccall.ipynb
93
- def _process_property(name, obj, props, req, defs):
101
+ def _process_property(name, obj, props, req, defs, evalable=False):
94
102
  "Process a single property of the schema"
95
- p = _param(name, obj)
103
+ p = _param(name, obj, evalable=evalable)
96
104
  props[name] = p
97
105
  if obj.default is empty: req[name] = True
98
106
 
@@ -103,14 +111,14 @@ def _process_property(name, obj, props, req, defs):
103
111
  p.update(_handle_type(obj.anno, defs))
104
112
 
105
113
  # %% ../01_funccall.ipynb
106
- def _get_nested_schema(obj):
114
+ def _get_nested_schema(obj, evalable=False):
107
115
  "Generate nested JSON schema for a class or function"
108
116
  d = docments(obj, full=True)
109
117
  props, req, defs = {}, {}, {}
110
118
 
111
119
  for n, o in d.items():
112
120
  if n != 'return' and n != 'self':
113
- _process_property(n, o, props, req, defs)
121
+ _process_property(n, o, props, req, defs, evalable=evalable)
114
122
 
115
123
  tkw = {}
116
124
  if isinstance(obj, type): tkw['title']=obj.__name__
@@ -120,10 +128,14 @@ def _get_nested_schema(obj):
120
128
  return schema
121
129
 
122
130
  # %% ../01_funccall.ipynb
123
- def get_schema(f:Union[callable,dict], pname='input_schema')->dict:
131
+ def get_schema(
132
+ f:Union[callable,dict], # Function to get schema for
133
+ pname='input_schema', # Key name for parameters
134
+ evalable=False # stringify defaults that can't be literal_eval'd?
135
+ )->dict:
124
136
  "Generate JSON schema for a class, function, or method"
125
137
  if isinstance(f, dict): return f
126
- schema = _get_nested_schema(f)
138
+ schema = _get_nested_schema(f, evalable=evalable)
127
139
  desc = f.__doc__
128
140
  assert desc, "Docstring missing!"
129
141
  d = docments(f, full=True)
toolslm/xml.py CHANGED
@@ -102,48 +102,56 @@ def mk_doc(index:int, # The document index
102
102
  def docs_xml(docs:list[str], # The content of each document
103
103
  srcs:Optional[list]=None, # URLs, filenames, etc; each one defaults to `md5(content)` if not provided
104
104
  prefix:bool=True, # Include Anthropic's suggested prose intro?
105
- details:Optional[list]=None # Optional list of dicts with additional attrs for each doc
105
+ details:Optional[list]=None, # Optional list of dicts with additional attrs for each doc
106
+ title:str=None # Optional title attr for Documents element
106
107
  )->str:
107
108
  "Create an XML string containing `docs` in Anthropic's recommended format"
108
109
  pre = 'Here are some documents for you to reference for your task:\n\n' if prefix else ''
109
110
  if srcs is None: srcs = [None]*len(docs)
110
111
  if details is None: details = [{}]*len(docs)
111
112
  docs = (mk_doc(i+1, d, s, **kw) for i,(d,s,kw) in enumerate(zip(docs,srcs,details)))
112
- return pre + to_xml(Documents(docs), do_escape=False)
113
+ kw = dict(title=title) if title else {}
114
+ return pre + to_xml(Documents(*docs, **kw), do_escape=False)
113
115
 
114
116
  # %% ../00_xml.ipynb
115
- def read_file(fname, out=True):
117
+ def read_file(fname, out=True, max_size=None):
116
118
  "Read file content, converting notebooks to XML if needed"
117
119
  fname = Path(fname)
118
- if fname.suffix == '.ipynb': return nb2xml(fname, out=out)
119
- return fname.read_text()
120
+ if fname.suffix == '.ipynb': res = nb2xml(fname, out=out)
121
+ else: res = fname.read_text()
122
+ if max_size and len(res)>max_size: return f"[Skipped: {fname.name} exceeds {max_size} bytes]"
123
+ return res
120
124
 
121
125
  # %% ../00_xml.ipynb
122
126
  def files2ctx(
123
127
  fnames:list[Union[str,Path]], # List of file names to add to context
124
128
  prefix:bool=True, # Include Anthropic's suggested prose intro?
125
129
  out:bool=True, # Include notebook cell outputs?
126
- srcs:Optional[list]=None # Use the labels instead of `fnames`
130
+ srcs:Optional[list]=None, # Use the labels instead of `fnames`
131
+ title:str=None, # Optional title attr for Documents element
132
+ max_size:int=None # Skip files larger than this (bytes)
127
133
  )->str: # XML for LM context
128
134
  "Convert files to XML context, handling notebooks"
129
135
  fnames = [Path(o) for o in fnames]
130
- contents = [read_file(o, out=out) for o in fnames]
131
- return docs_xml(contents, srcs or fnames, prefix=prefix)
136
+ contents = [read_file(o, out=out, max_size=max_size) for o in fnames]
137
+ return docs_xml(contents, srcs or fnames, prefix=prefix, title=title)
132
138
 
133
139
  # %% ../00_xml.ipynb
134
140
  @delegates(globtastic)
135
141
  def folder2ctx(
136
142
  folder:Union[str,Path],
137
- prefix:bool=True,
138
- out:bool=True,
139
- include_base:bool=True,
143
+ prefix:bool=True, # Include Anthropic's suggested prose intro?
144
+ out:bool=True, # Include notebook cell outputs?
145
+ include_base:bool=True, # Include full path in src?
146
+ title:str=None, # Optional title attr for Documents element
147
+ max_size:int=100_000, # Skip files larger than this (bytes)
140
148
  **kwargs
141
149
  )->str:
142
150
  "Convert folder contents to XML context, handling notebooks"
143
151
  folder = Path(folder)
144
152
  fnames = globtastic(folder, **kwargs)
145
153
  srcs = fnames if include_base else [Path(f).relative_to(folder) for f in fnames]
146
- return files2ctx(fnames, prefix=prefix, out=out, srcs=srcs)
154
+ return files2ctx(fnames, prefix=prefix, out=out, srcs=srcs, title=title, max_size=max_size)
147
155
 
148
156
  # %% ../00_xml.ipynb
149
157
  @delegates(folder2ctx)
@@ -158,11 +166,15 @@ def repo2ctx(
158
166
  api = GhApi()
159
167
  if ref is None: ref = api.repos.get(owner, repo).default_branch
160
168
  data = api.repos.download_tarball_archive(owner, repo, ref)
169
+ parts = ' | '.join(f"{k}: {', '.join(v) if isinstance(v, (list,tuple)) else v}"
170
+ for k,v in kwargs.items() if v)
171
+ title = f"GitHub repository contents from {owner}/{repo} at ref '{ref}'"
172
+ if parts: title += f" (filters applied: {parts})"
161
173
  tf = tarfile.open(fileobj=io.BytesIO(data))
162
174
  with tempfile.TemporaryDirectory() as tmp:
163
175
  tf.extractall(tmp, filter='data')
164
176
  subdir = Path(tmp) / tf.getmembers()[0].name.split('/')[0]
165
- return folder2ctx(subdir, include_base=False, **kwargs)
177
+ return folder2ctx(subdir, include_base=False, title=title, **kwargs)
166
178
 
167
179
  # %% ../00_xml.ipynb
168
180
  @call_parse
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolslm
3
- Version: 0.3.8
3
+ Version: 0.3.10
4
4
  Summary: Tools to make language models a bit easier to use
5
5
  Home-page: https://github.com/AnswerDotAI/toolslm
6
6
  Author: Jeremy Howard
@@ -0,0 +1,13 @@
1
+ toolslm/__init__.py,sha256=h9TycTJK2pK49s87IMbNRq4lTqRt3xctcJl2jxCe3sU,23
2
+ toolslm/_modidx.py,sha256=kpgsDpj-Tvn90wezrHaMttyzhNcyNVgw_dQgK10qotI,5308
3
+ toolslm/download.py,sha256=g3BxUSxylC_575M7RFSJ1GI3Co3EwPDdEeWzxaf2Czk,4451
4
+ toolslm/funccall.py,sha256=KO08GspCaVROb5Z29cxHRz3MaZdTUFj4j08sbbEyUSs,10968
5
+ toolslm/md_hier.py,sha256=r_NPezhgfxjRmSYFlu_ND42hXt1qSbaPWHTcjbviOn4,11010
6
+ toolslm/shell.py,sha256=dGInuRKvexu21VmtZkw_0S3BGiTsbAongUG-yG4YHpc,1566
7
+ toolslm/xml.py,sha256=tAHoqXrTRiX8i3pR-9KpHoBb8QXJ_TKEVyTEOPviudE,8095
8
+ toolslm-0.3.10.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
9
+ toolslm-0.3.10.dist-info/METADATA,sha256=pqfkL4TIn_jnIpuL06aWoCO5WW8k1yorccDYdnHPpfg,2404
10
+ toolslm-0.3.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ toolslm-0.3.10.dist-info/entry_points.txt,sha256=xFz0Eymlo5X7BGpaO6DI9gMxvN5A7faebzrlr8ctp5I,95
12
+ toolslm-0.3.10.dist-info/top_level.txt,sha256=4hRTrFWayz_Kz5221XjvlpCwVFrW3WPi1P0fllkTq9s,8
13
+ toolslm-0.3.10.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- toolslm/__init__.py,sha256=7dTW0A5-FkrEuNOotvR8oW59M2lvIwYouVqfJzvXpKk,22
2
- toolslm/_modidx.py,sha256=kpgsDpj-Tvn90wezrHaMttyzhNcyNVgw_dQgK10qotI,5308
3
- toolslm/download.py,sha256=g3BxUSxylC_575M7RFSJ1GI3Co3EwPDdEeWzxaf2Czk,4451
4
- toolslm/funccall.py,sha256=0OBrx6KzI0KK13L-5Hn69yah9oZhgTsKchmMenCoT0A,10421
5
- toolslm/md_hier.py,sha256=r_NPezhgfxjRmSYFlu_ND42hXt1qSbaPWHTcjbviOn4,11010
6
- toolslm/shell.py,sha256=dGInuRKvexu21VmtZkw_0S3BGiTsbAongUG-yG4YHpc,1566
7
- toolslm/xml.py,sha256=TO3i6QD1g_ya8B7Wxwib2ZWv7pwVpfyaAalw1qrKb74,7148
8
- toolslm-0.3.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
9
- toolslm-0.3.8.dist-info/METADATA,sha256=j4UPSM5q7rP16BlkIQzb8_4czu7-EnLDSqRGeIgPdaU,2403
10
- toolslm-0.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- toolslm-0.3.8.dist-info/entry_points.txt,sha256=xFz0Eymlo5X7BGpaO6DI9gMxvN5A7faebzrlr8ctp5I,95
12
- toolslm-0.3.8.dist-info/top_level.txt,sha256=4hRTrFWayz_Kz5221XjvlpCwVFrW3WPi1P0fllkTq9s,8
13
- toolslm-0.3.8.dist-info/RECORD,,