toolslm 0.2.0__tar.gz → 0.2.2__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.
- {toolslm-0.2.0/toolslm.egg-info → toolslm-0.2.2}/PKG-INFO +1 -1
- {toolslm-0.2.0 → toolslm-0.2.2}/settings.ini +2 -2
- toolslm-0.2.2/toolslm/__init__.py +1 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/download.py +10 -10
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/funccall.py +45 -34
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/shell.py +5 -5
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/xml.py +10 -10
- {toolslm-0.2.0 → toolslm-0.2.2/toolslm.egg-info}/PKG-INFO +1 -1
- toolslm-0.2.0/toolslm/__init__.py +0 -1
- {toolslm-0.2.0 → toolslm-0.2.2}/LICENSE +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/MANIFEST.in +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/README.md +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/pyproject.toml +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/setup.cfg +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/setup.py +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/_modidx.py +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm/md_hier.py +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/SOURCES.txt +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/dependency_links.txt +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/entry_points.txt +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/not-zip-safe +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/requires.txt +0 -0
- {toolslm-0.2.0 → toolslm-0.2.2}/toolslm.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[DEFAULT]
|
|
2
2
|
repo = toolslm
|
|
3
3
|
lib_name = toolslm
|
|
4
|
-
version = 0.2.
|
|
4
|
+
version = 0.2.2
|
|
5
5
|
min_python = 3.9
|
|
6
6
|
license = apache2
|
|
7
7
|
black_formatting = False
|
|
@@ -35,7 +35,7 @@ clean_ids = True
|
|
|
35
35
|
clear_all = False
|
|
36
36
|
conda_user = fastai
|
|
37
37
|
console_scripts = folder2ctx=toolslm.xml:folder2ctx_cli
|
|
38
|
-
cell_number =
|
|
38
|
+
cell_number = False
|
|
39
39
|
skip_procs =
|
|
40
40
|
update_pyproject = True
|
|
41
41
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.2"
|
|
@@ -3,26 +3,26 @@
|
|
|
3
3
|
# %% auto 0
|
|
4
4
|
__all__ = ['clean_md', 'read_md', 'html2md', 'read_html', 'get_llmstxt', 'split_url', 'find_docs', 'read_docs']
|
|
5
5
|
|
|
6
|
-
# %% ../03_download.ipynb
|
|
6
|
+
# %% ../03_download.ipynb
|
|
7
7
|
from fastcore.utils import *
|
|
8
8
|
from httpx import get
|
|
9
9
|
from fastcore.meta import delegates
|
|
10
10
|
from urllib.parse import urlparse, urljoin
|
|
11
11
|
|
|
12
|
-
# %% ../03_download.ipynb
|
|
12
|
+
# %% ../03_download.ipynb
|
|
13
13
|
def clean_md(text, rm_comments=True, rm_details=True):
|
|
14
14
|
"Remove comments and `<details>` sections from `text`"
|
|
15
15
|
if rm_comments: text = re.sub(r'\n?<!--.*?-->\n?', '', text, flags=re.DOTALL)
|
|
16
16
|
if rm_details: text = re.sub(r'\n?<details>.*?</details>\n?', '', text, flags=re.DOTALL)
|
|
17
17
|
return text
|
|
18
18
|
|
|
19
|
-
# %% ../03_download.ipynb
|
|
19
|
+
# %% ../03_download.ipynb
|
|
20
20
|
@delegates(get)
|
|
21
21
|
def read_md(url, rm_comments=True, rm_details=True, **kwargs):
|
|
22
22
|
"Read text from `url` and clean with `clean_docs`"
|
|
23
23
|
return clean_md(get(url, **kwargs).text, rm_comments=rm_comments, rm_details=rm_details)
|
|
24
24
|
|
|
25
|
-
# %% ../03_download.ipynb
|
|
25
|
+
# %% ../03_download.ipynb
|
|
26
26
|
def html2md(s:str, ignore_links=True):
|
|
27
27
|
"Convert `s` from HTML to markdown"
|
|
28
28
|
import html2text
|
|
@@ -32,7 +32,7 @@ def html2md(s:str, ignore_links=True):
|
|
|
32
32
|
o.ignore_images = True
|
|
33
33
|
return o.handle(s)
|
|
34
34
|
|
|
35
|
-
# %% ../03_download.ipynb
|
|
35
|
+
# %% ../03_download.ipynb
|
|
36
36
|
def read_html(url, # URL to read
|
|
37
37
|
sel=None, # Read only outerHTML of CSS selector `sel`
|
|
38
38
|
rm_comments=True, # Removes HTML comments
|
|
@@ -54,7 +54,7 @@ def read_html(url, # URL to read
|
|
|
54
54
|
if wrap_tag: return '\n'.join([f"\n<{wrap_tag}>\n{o}</{wrap_tag}>\n" for o in mds])
|
|
55
55
|
else: return'\n'.join(mds)
|
|
56
56
|
|
|
57
|
-
# %% ../03_download.ipynb
|
|
57
|
+
# %% ../03_download.ipynb
|
|
58
58
|
def get_llmstxt(url, optional=False, n_workers=None):
|
|
59
59
|
"Get llms.txt file from and expand it with `llms_txt.create_ctx()`"
|
|
60
60
|
if not url.endswith('llms.txt'): return None
|
|
@@ -63,7 +63,7 @@ def get_llmstxt(url, optional=False, n_workers=None):
|
|
|
63
63
|
if resp.status_code!=200: return None
|
|
64
64
|
return llms_txt.create_ctx(resp.text, optional=optional, n_workers=n_workers)
|
|
65
65
|
|
|
66
|
-
# %% ../03_download.ipynb
|
|
66
|
+
# %% ../03_download.ipynb
|
|
67
67
|
def split_url(url):
|
|
68
68
|
"Split `url` into base, path, and file name, normalising name to '/' if empty"
|
|
69
69
|
parsed = urlparse(url.strip('/'))
|
|
@@ -73,13 +73,13 @@ def split_url(url):
|
|
|
73
73
|
if not path and not fname: path='/'
|
|
74
74
|
return base,path,fname
|
|
75
75
|
|
|
76
|
-
# %% ../03_download.ipynb
|
|
76
|
+
# %% ../03_download.ipynb
|
|
77
77
|
def _tryget(url):
|
|
78
78
|
"Return response from `url` if `status_code!=404`, otherwise `None`"
|
|
79
79
|
res = get(url)
|
|
80
80
|
return None if res.status_code==404 else url
|
|
81
81
|
|
|
82
|
-
# %% ../03_download.ipynb
|
|
82
|
+
# %% ../03_download.ipynb
|
|
83
83
|
def find_docs(url):
|
|
84
84
|
"If available, return LLM-friendly llms.txt context or markdown file location from `url`"
|
|
85
85
|
base,path,fname = split_url(url)
|
|
@@ -99,7 +99,7 @@ def find_docs(url):
|
|
|
99
99
|
if parsed_url.path == '/' or not parsed_url.path: return None
|
|
100
100
|
return find_docs(urljoin(url, '..'))
|
|
101
101
|
|
|
102
|
-
# %% ../03_download.ipynb
|
|
102
|
+
# %% ../03_download.ipynb
|
|
103
103
|
def read_docs(url, optional=False, n_workers=None, rm_comments=True, rm_details=True):
|
|
104
104
|
"If available, return LLM-friendly llms.txt context or markdown file response for `url`"
|
|
105
105
|
url = find_docs(url)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# %% auto 0
|
|
4
4
|
__all__ = ['empty', 'custom_types', 'get_schema', 'PathArg', 'python', 'mk_ns', 'call_func', 'call_func_async']
|
|
5
5
|
|
|
6
|
-
# %% ../01_funccall.ipynb
|
|
6
|
+
# %% ../01_funccall.ipynb
|
|
7
7
|
import inspect
|
|
8
8
|
from collections import abc
|
|
9
9
|
from fastcore.utils import *
|
|
@@ -11,10 +11,10 @@ from fastcore.docments import docments
|
|
|
11
11
|
from typing import get_origin, get_args, Dict, List, Optional, Tuple, Union
|
|
12
12
|
from types import UnionType
|
|
13
13
|
|
|
14
|
-
# %% ../01_funccall.ipynb
|
|
14
|
+
# %% ../01_funccall.ipynb
|
|
15
15
|
empty = inspect.Parameter.empty
|
|
16
16
|
|
|
17
|
-
# %% ../01_funccall.ipynb
|
|
17
|
+
# %% ../01_funccall.ipynb
|
|
18
18
|
def _types(t:type)->tuple[str,Optional[str]]:
|
|
19
19
|
"Tuple of json schema type name and (if appropriate) array item name."
|
|
20
20
|
if t is empty: raise TypeError('Missing type')
|
|
@@ -31,7 +31,7 @@ def _types(t:type)->tuple[str,Optional[str]]:
|
|
|
31
31
|
# if t is the type itself like int, use the __name__ representation as the key
|
|
32
32
|
else: return tmap.get(t.__name__, "object"), None
|
|
33
33
|
|
|
34
|
-
# %% ../01_funccall.ipynb
|
|
34
|
+
# %% ../01_funccall.ipynb
|
|
35
35
|
def _param(name, info):
|
|
36
36
|
"json schema parameter given `name` and `info` from docments full dict."
|
|
37
37
|
paramt,itemt = _types(info.anno)
|
|
@@ -40,19 +40,20 @@ def _param(name, info):
|
|
|
40
40
|
if info.default is not empty: pschema["default"] = info.default
|
|
41
41
|
return pschema
|
|
42
42
|
|
|
43
|
-
# %% ../01_funccall.ipynb
|
|
43
|
+
# %% ../01_funccall.ipynb
|
|
44
44
|
custom_types = {Path}
|
|
45
45
|
|
|
46
46
|
def _handle_type(t, defs):
|
|
47
47
|
"Handle a single type, creating nested schemas if necessary"
|
|
48
48
|
if t is NoneType: return {'type': 'null'}
|
|
49
49
|
if t in custom_types: return {'type':'string', 'format':t.__name__}
|
|
50
|
+
if t in (dict, list, tuple, set): return {'type': _types(t)[0]}
|
|
50
51
|
if isinstance(t, type) and not issubclass(t, (int, float, str, bool)) or inspect.isfunction(t):
|
|
51
52
|
defs[t.__name__] = _get_nested_schema(t)
|
|
52
53
|
return {'$ref': f'#/$defs/{t.__name__}'}
|
|
53
54
|
return {'type': _types(t)[0]}
|
|
54
55
|
|
|
55
|
-
# %% ../01_funccall.ipynb
|
|
56
|
+
# %% ../01_funccall.ipynb
|
|
56
57
|
def _is_container(t):
|
|
57
58
|
"Check if type is a container (list, dict, tuple, set, Union)"
|
|
58
59
|
origin = get_origin(t)
|
|
@@ -62,7 +63,7 @@ def _is_parameterized(t):
|
|
|
62
63
|
"Check if type has arguments (e.g. list[int] vs list, dict[str, int] vs dict)"
|
|
63
64
|
return _is_container(t) and (get_args(t) != ())
|
|
64
65
|
|
|
65
|
-
# %% ../01_funccall.ipynb
|
|
66
|
+
# %% ../01_funccall.ipynb
|
|
66
67
|
def _handle_container(origin, args, defs):
|
|
67
68
|
"Handle container types like dict, list, tuple, set, and Union"
|
|
68
69
|
if origin is Union or origin is UnionType:
|
|
@@ -83,7 +84,7 @@ def _handle_container(origin, args, defs):
|
|
|
83
84
|
return schema
|
|
84
85
|
return None
|
|
85
86
|
|
|
86
|
-
# %% ../01_funccall.ipynb
|
|
87
|
+
# %% ../01_funccall.ipynb
|
|
87
88
|
def _process_property(name, obj, props, req, defs):
|
|
88
89
|
"Process a single property of the schema"
|
|
89
90
|
p = _param(name, obj)
|
|
@@ -91,12 +92,12 @@ def _process_property(name, obj, props, req, defs):
|
|
|
91
92
|
if obj.default is empty: req[name] = True
|
|
92
93
|
|
|
93
94
|
if _is_container(obj.anno) and _is_parameterized(obj.anno):
|
|
94
|
-
|
|
95
|
+
p.update(_handle_container(get_origin(obj.anno), get_args(obj.anno), defs))
|
|
95
96
|
else:
|
|
96
97
|
# Non-container type or container without arguments
|
|
97
98
|
p.update(_handle_type(obj.anno, defs))
|
|
98
99
|
|
|
99
|
-
# %% ../01_funccall.ipynb
|
|
100
|
+
# %% ../01_funccall.ipynb
|
|
100
101
|
def _get_nested_schema(obj):
|
|
101
102
|
"Generate nested JSON schema for a class or function"
|
|
102
103
|
d = docments(obj, full=True)
|
|
@@ -111,9 +112,10 @@ def _get_nested_schema(obj):
|
|
|
111
112
|
if defs: schema['$defs'] = defs
|
|
112
113
|
return schema
|
|
113
114
|
|
|
114
|
-
# %% ../01_funccall.ipynb
|
|
115
|
-
def get_schema(f:callable, pname='input_schema')->dict:
|
|
115
|
+
# %% ../01_funccall.ipynb
|
|
116
|
+
def get_schema(f:Union[callable,dict], pname='input_schema')->dict:
|
|
116
117
|
"Generate JSON schema for a class, function, or method"
|
|
118
|
+
if isinstance(f, dict): return f
|
|
117
119
|
schema = _get_nested_schema(f)
|
|
118
120
|
desc = f.__doc__
|
|
119
121
|
assert desc, "Docstring missing!"
|
|
@@ -122,16 +124,16 @@ def get_schema(f:callable, pname='input_schema')->dict:
|
|
|
122
124
|
if ret.anno is not empty: desc += f'\n\nReturns:\n- type: {_types(ret.anno)[0]}'
|
|
123
125
|
return {"name": f.__name__, "description": desc, pname: schema}
|
|
124
126
|
|
|
125
|
-
# %% ../01_funccall.ipynb
|
|
127
|
+
# %% ../01_funccall.ipynb
|
|
126
128
|
def PathArg(
|
|
127
129
|
path: str # A filesystem path
|
|
128
130
|
): return Path(path)
|
|
129
131
|
|
|
130
|
-
# %% ../01_funccall.ipynb
|
|
132
|
+
# %% ../01_funccall.ipynb
|
|
131
133
|
import ast, time, signal, traceback
|
|
132
134
|
from fastcore.utils import *
|
|
133
135
|
|
|
134
|
-
# %% ../01_funccall.ipynb
|
|
136
|
+
# %% ../01_funccall.ipynb
|
|
135
137
|
def _copy_loc(new, orig):
|
|
136
138
|
"Copy location information from original node to new node and all children."
|
|
137
139
|
new = ast.copy_location(new, orig)
|
|
@@ -140,7 +142,7 @@ def _copy_loc(new, orig):
|
|
|
140
142
|
elif isinstance(o, list): setattr(new, field, [_copy_loc(value, orig) for value in o])
|
|
141
143
|
return new
|
|
142
144
|
|
|
143
|
-
# %% ../01_funccall.ipynb
|
|
145
|
+
# %% ../01_funccall.ipynb
|
|
144
146
|
def _run(code:str, glb:dict=None, loc:dict=None):
|
|
145
147
|
"Run `code`, returning final expression (similar to IPython)"
|
|
146
148
|
tree = ast.parse(code)
|
|
@@ -163,14 +165,14 @@ def _run(code:str, glb:dict=None, loc:dict=None):
|
|
|
163
165
|
if _result is not None: return _result
|
|
164
166
|
return stdout_buffer.getvalue().strip()
|
|
165
167
|
|
|
166
|
-
# %% ../01_funccall.ipynb
|
|
167
|
-
def python(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
# %% ../01_funccall.ipynb
|
|
169
|
+
def python(
|
|
170
|
+
code:str, # Code to execute
|
|
171
|
+
glb:Optional[dict]=None, # Globals namespace
|
|
172
|
+
loc:Optional[dict]=None, # Locals namespace
|
|
173
|
+
timeout:int=3600 # Maximum run time in seconds
|
|
174
|
+
):
|
|
175
|
+
"Executes python `code` with `timeout` and returning final expression (similar to IPython)."
|
|
174
176
|
def handler(*args): raise TimeoutError()
|
|
175
177
|
if glb is None: glb = inspect.currentframe().f_back.f_globals
|
|
176
178
|
if loc is None: loc=glb
|
|
@@ -180,7 +182,7 @@ def python(code:str, # Code to execute
|
|
|
180
182
|
except Exception as e: return traceback.format_exc()
|
|
181
183
|
finally: signal.alarm(0)
|
|
182
184
|
|
|
183
|
-
# %% ../01_funccall.ipynb
|
|
185
|
+
# %% ../01_funccall.ipynb
|
|
184
186
|
def mk_ns(*funcs_or_objs):
|
|
185
187
|
merged = {}
|
|
186
188
|
for o in funcs_or_objs:
|
|
@@ -189,16 +191,25 @@ def mk_ns(*funcs_or_objs):
|
|
|
189
191
|
if callable(o) and hasattr(o, '__name__'): merged |= {o.__name__: o}
|
|
190
192
|
return merged
|
|
191
193
|
|
|
192
|
-
# %% ../01_funccall.ipynb
|
|
193
|
-
def call_func(fc_name, fc_inputs, ns):
|
|
194
|
+
# %% ../01_funccall.ipynb
|
|
195
|
+
def call_func(fc_name, fc_inputs, ns, raise_on_err=True):
|
|
194
196
|
"Call the function `fc_name` with the given `fc_inputs` using namespace `ns`."
|
|
195
197
|
if not isinstance(ns, abc.Mapping): ns = mk_ns(*ns)
|
|
196
198
|
func = ns[fc_name]
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
# Clean up bad param names
|
|
200
|
+
inps = {re.sub(r'\W', '', k):v for k,v in fc_inputs.items()}
|
|
201
|
+
try: return func(**fc_inputs)
|
|
202
|
+
except Exception as e:
|
|
203
|
+
if raise_on_err: raise e from None
|
|
204
|
+
else: return traceback.format_exc()
|
|
205
|
+
|
|
206
|
+
# %% ../01_funccall.ipynb
|
|
207
|
+
async def call_func_async(fc_name, fc_inputs, ns, raise_on_err=True):
|
|
201
208
|
"Awaits the function `fc_name` with the given `fc_inputs` using namespace `ns`."
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)
|
|
210
|
+
if inspect.iscoroutine(res):
|
|
211
|
+
try: res = await res
|
|
212
|
+
except Exception as e:
|
|
213
|
+
if raise_on_err: raise e from None
|
|
214
|
+
else: return traceback.format_exc()
|
|
215
|
+
return res
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
# %% auto 0
|
|
4
4
|
__all__ = ['get_shell']
|
|
5
5
|
|
|
6
|
-
# %% ../02_shell.ipynb
|
|
6
|
+
# %% ../02_shell.ipynb
|
|
7
7
|
import ast, time, signal, traceback
|
|
8
8
|
from fastcore.utils import *
|
|
9
9
|
|
|
10
|
-
# %% ../02_shell.ipynb
|
|
10
|
+
# %% ../02_shell.ipynb
|
|
11
11
|
from IPython.terminal.interactiveshell import TerminalInteractiveShell
|
|
12
12
|
from IPython.utils.capture import capture_output
|
|
13
13
|
|
|
14
|
-
# %% ../02_shell.ipynb
|
|
14
|
+
# %% ../02_shell.ipynb
|
|
15
15
|
TerminalInteractiveShell.orig_run = TerminalInteractiveShell.run_cell
|
|
16
16
|
|
|
17
|
-
# %% ../02_shell.ipynb
|
|
17
|
+
# %% ../02_shell.ipynb
|
|
18
18
|
@patch
|
|
19
19
|
def run_cell(self:TerminalInteractiveShell, cell, timeout=None):
|
|
20
20
|
"Wrapper for original `run_cell` which adds timeout and output capture"
|
|
@@ -31,7 +31,7 @@ def run_cell(self:TerminalInteractiveShell, cell, timeout=None):
|
|
|
31
31
|
finally:
|
|
32
32
|
if timeout: signal.alarm(0)
|
|
33
33
|
|
|
34
|
-
# %% ../02_shell.ipynb
|
|
34
|
+
# %% ../02_shell.ipynb
|
|
35
35
|
def get_shell()->TerminalInteractiveShell:
|
|
36
36
|
"Get a `TerminalInteractiveShell` with minimal functionality"
|
|
37
37
|
sh = TerminalInteractiveShell()
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# %% auto 0
|
|
4
4
|
__all__ = ['doctype', 'json_to_xml', 'mk_doctype', 'mk_doc', 'docs_xml', 'files2ctx', 'folder2ctx', 'folder2ctx_cli']
|
|
5
5
|
|
|
6
|
-
# %% ../00_xml.ipynb
|
|
6
|
+
# %% ../00_xml.ipynb
|
|
7
7
|
import hashlib,xml.etree.ElementTree as ET
|
|
8
8
|
from collections import namedtuple
|
|
9
9
|
|
|
@@ -15,7 +15,7 @@ from fastcore.script import call_parse
|
|
|
15
15
|
try: from IPython import display
|
|
16
16
|
except: display=None
|
|
17
17
|
|
|
18
|
-
# %% ../00_xml.ipynb
|
|
18
|
+
# %% ../00_xml.ipynb
|
|
19
19
|
def json_to_xml(d:dict, # JSON dictionary to convert
|
|
20
20
|
rnm:str # Root name
|
|
21
21
|
)->str:
|
|
@@ -31,10 +31,10 @@ def json_to_xml(d:dict, # JSON dictionary to convert
|
|
|
31
31
|
ET.indent(root)
|
|
32
32
|
return ET.tostring(root, encoding='unicode')
|
|
33
33
|
|
|
34
|
-
# %% ../00_xml.ipynb
|
|
34
|
+
# %% ../00_xml.ipynb
|
|
35
35
|
doctype = namedtuple('doctype', ['src', 'content'])
|
|
36
36
|
|
|
37
|
-
# %% ../00_xml.ipynb
|
|
37
|
+
# %% ../00_xml.ipynb
|
|
38
38
|
def _add_nls(s):
|
|
39
39
|
"Add newlines to start and end of `s` if missing"
|
|
40
40
|
if not s: return s
|
|
@@ -42,7 +42,7 @@ def _add_nls(s):
|
|
|
42
42
|
if s[-1]!='\n': s = s+'\n'
|
|
43
43
|
return s
|
|
44
44
|
|
|
45
|
-
# %% ../00_xml.ipynb
|
|
45
|
+
# %% ../00_xml.ipynb
|
|
46
46
|
def mk_doctype(content:str, # The document content
|
|
47
47
|
src:Optional[str]=None # URL, filename, etc; defaults to `md5(content)` if not provided
|
|
48
48
|
) -> namedtuple:
|
|
@@ -50,7 +50,7 @@ def mk_doctype(content:str, # The document content
|
|
|
50
50
|
if src is None: src = hashlib.md5(content.encode()).hexdigest()[:8]
|
|
51
51
|
return doctype(_add_nls(str(src).strip()), _add_nls(content.strip()))
|
|
52
52
|
|
|
53
|
-
# %% ../00_xml.ipynb
|
|
53
|
+
# %% ../00_xml.ipynb
|
|
54
54
|
def mk_doc(index:int, # The document index
|
|
55
55
|
content:str, # The document content
|
|
56
56
|
src:Optional[str]=None, # URL, filename, etc; defaults to `md5(content)` if not provided
|
|
@@ -62,7 +62,7 @@ def mk_doc(index:int, # The document index
|
|
|
62
62
|
src = Src(NotStr(dt.src))
|
|
63
63
|
return Document(src, content, index=index, **kwargs)
|
|
64
64
|
|
|
65
|
-
# %% ../00_xml.ipynb
|
|
65
|
+
# %% ../00_xml.ipynb
|
|
66
66
|
def docs_xml(docs:list[str], # The content of each document
|
|
67
67
|
srcs:Optional[list]=None, # URLs, filenames, etc; each one defaults to `md5(content)` if not provided
|
|
68
68
|
prefix:bool=True, # Include Anthropic's suggested prose intro?
|
|
@@ -75,7 +75,7 @@ def docs_xml(docs:list[str], # The content of each document
|
|
|
75
75
|
docs = (mk_doc(i+1, d, s, **kw) for i,(d,s,kw) in enumerate(zip(docs,srcs,details)))
|
|
76
76
|
return pre + to_xml(Documents(docs))
|
|
77
77
|
|
|
78
|
-
# %% ../00_xml.ipynb
|
|
78
|
+
# %% ../00_xml.ipynb
|
|
79
79
|
def files2ctx(
|
|
80
80
|
fnames:list[Union[str,Path]], # List of file names to add to context
|
|
81
81
|
prefix:bool=True # Include Anthropic's suggested prose intro?
|
|
@@ -84,7 +84,7 @@ def files2ctx(
|
|
|
84
84
|
contents = [o.read_text() for o in fnames]
|
|
85
85
|
return docs_xml(contents, fnames, prefix=prefix)
|
|
86
86
|
|
|
87
|
-
# %% ../00_xml.ipynb
|
|
87
|
+
# %% ../00_xml.ipynb
|
|
88
88
|
@delegates(globtastic)
|
|
89
89
|
def folder2ctx(
|
|
90
90
|
folder:Union[str,Path], # Folder name containing files to add to context
|
|
@@ -94,7 +94,7 @@ def folder2ctx(
|
|
|
94
94
|
fnames = globtastic(folder, **kwargs)
|
|
95
95
|
return files2ctx(fnames, prefix=prefix)
|
|
96
96
|
|
|
97
|
-
# %% ../00_xml.ipynb
|
|
97
|
+
# %% ../00_xml.ipynb
|
|
98
98
|
@call_parse
|
|
99
99
|
@delegates(folder2ctx)
|
|
100
100
|
def folder2ctx_cli(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|