toolslm 0.2.1__tar.gz → 0.2.3__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.1/toolslm.egg-info → toolslm-0.2.3}/PKG-INFO +1 -1
- {toolslm-0.2.1 → toolslm-0.2.3}/settings.ini +2 -2
- toolslm-0.2.3/toolslm/__init__.py +1 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/download.py +10 -10
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/funccall.py +39 -34
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/shell.py +5 -5
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/xml.py +10 -10
- {toolslm-0.2.1 → toolslm-0.2.3/toolslm.egg-info}/PKG-INFO +1 -1
- toolslm-0.2.1/toolslm/__init__.py +0 -1
- {toolslm-0.2.1 → toolslm-0.2.3}/LICENSE +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/MANIFEST.in +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/README.md +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/pyproject.toml +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/setup.cfg +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/setup.py +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/_modidx.py +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm/md_hier.py +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm.egg-info/SOURCES.txt +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm.egg-info/dependency_links.txt +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm.egg-info/entry_points.txt +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm.egg-info/not-zip-safe +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/toolslm.egg-info/requires.txt +0 -0
- {toolslm-0.2.1 → toolslm-0.2.3}/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.3
|
|
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.3"
|
|
@@ -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,7 +112,7 @@ def _get_nested_schema(obj):
|
|
|
111
112
|
if defs: schema['$defs'] = defs
|
|
112
113
|
return schema
|
|
113
114
|
|
|
114
|
-
# %% ../01_funccall.ipynb
|
|
115
|
+
# %% ../01_funccall.ipynb
|
|
115
116
|
def get_schema(f:Union[callable,dict], pname='input_schema')->dict:
|
|
116
117
|
"Generate JSON schema for a class, function, or method"
|
|
117
118
|
if isinstance(f, dict): return f
|
|
@@ -123,16 +124,16 @@ def get_schema(f:Union[callable,dict], pname='input_schema')->dict:
|
|
|
123
124
|
if ret.anno is not empty: desc += f'\n\nReturns:\n- type: {_types(ret.anno)[0]}'
|
|
124
125
|
return {"name": f.__name__, "description": desc, pname: schema}
|
|
125
126
|
|
|
126
|
-
# %% ../01_funccall.ipynb
|
|
127
|
+
# %% ../01_funccall.ipynb
|
|
127
128
|
def PathArg(
|
|
128
129
|
path: str # A filesystem path
|
|
129
130
|
): return Path(path)
|
|
130
131
|
|
|
131
|
-
# %% ../01_funccall.ipynb
|
|
132
|
+
# %% ../01_funccall.ipynb
|
|
132
133
|
import ast, time, signal, traceback
|
|
133
134
|
from fastcore.utils import *
|
|
134
135
|
|
|
135
|
-
# %% ../01_funccall.ipynb
|
|
136
|
+
# %% ../01_funccall.ipynb
|
|
136
137
|
def _copy_loc(new, orig):
|
|
137
138
|
"Copy location information from original node to new node and all children."
|
|
138
139
|
new = ast.copy_location(new, orig)
|
|
@@ -141,7 +142,7 @@ def _copy_loc(new, orig):
|
|
|
141
142
|
elif isinstance(o, list): setattr(new, field, [_copy_loc(value, orig) for value in o])
|
|
142
143
|
return new
|
|
143
144
|
|
|
144
|
-
# %% ../01_funccall.ipynb
|
|
145
|
+
# %% ../01_funccall.ipynb
|
|
145
146
|
def _run(code:str, glb:dict=None, loc:dict=None):
|
|
146
147
|
"Run `code`, returning final expression (similar to IPython)"
|
|
147
148
|
tree = ast.parse(code)
|
|
@@ -164,14 +165,14 @@ def _run(code:str, glb:dict=None, loc:dict=None):
|
|
|
164
165
|
if _result is not None: return _result
|
|
165
166
|
return stdout_buffer.getvalue().strip()
|
|
166
167
|
|
|
167
|
-
# %% ../01_funccall.ipynb
|
|
168
|
-
def python(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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)."
|
|
175
176
|
def handler(*args): raise TimeoutError()
|
|
176
177
|
if glb is None: glb = inspect.currentframe().f_back.f_globals
|
|
177
178
|
if loc is None: loc=glb
|
|
@@ -181,32 +182,36 @@ def python(code:str, # Code to execute
|
|
|
181
182
|
except Exception as e: return traceback.format_exc()
|
|
182
183
|
finally: signal.alarm(0)
|
|
183
184
|
|
|
184
|
-
# %% ../01_funccall.ipynb
|
|
185
|
-
def mk_ns(
|
|
185
|
+
# %% ../01_funccall.ipynb
|
|
186
|
+
def mk_ns(fs):
|
|
187
|
+
if isinstance(fs, abc.Mapping): return fs
|
|
186
188
|
merged = {}
|
|
187
|
-
for o in
|
|
188
|
-
if isinstance(o,
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
for o in listify(fs):
|
|
190
|
+
if isinstance(o, dict): merged |= o
|
|
191
|
+
elif isinstance(o, type): merged |= {n:getattr(o,n) for n,m in o.__dict__.items() if isinstance(m, (staticmethod, classmethod))}
|
|
192
|
+
elif callable(o) and hasattr(o, '__name__'): merged |= {o.__name__: o}
|
|
193
|
+
merged |= {n:getattr(o,n) for n, m in inspect.getmembers(o, inspect.ismethod)} | {n:m for n,m in o.__class__.__dict__.items() if isinstance(m, staticmethod)}
|
|
191
194
|
return merged
|
|
192
195
|
|
|
193
|
-
# %% ../01_funccall.ipynb
|
|
196
|
+
# %% ../01_funccall.ipynb
|
|
194
197
|
def call_func(fc_name, fc_inputs, ns, raise_on_err=True):
|
|
195
198
|
"Call the function `fc_name` with the given `fc_inputs` using namespace `ns`."
|
|
196
|
-
if not isinstance(ns, abc.Mapping): ns = mk_ns(
|
|
199
|
+
if not isinstance(ns, abc.Mapping): ns = mk_ns(ns)
|
|
197
200
|
func = ns[fc_name]
|
|
201
|
+
# Clean up bad param names
|
|
202
|
+
inps = {re.sub(r'\W', '', k):v for k,v in fc_inputs.items()}
|
|
198
203
|
try: return func(**fc_inputs)
|
|
199
204
|
except Exception as e:
|
|
200
|
-
if raise_on_err: raise e
|
|
205
|
+
if raise_on_err: raise e from None
|
|
201
206
|
else: return traceback.format_exc()
|
|
202
207
|
|
|
203
|
-
# %% ../01_funccall.ipynb
|
|
208
|
+
# %% ../01_funccall.ipynb
|
|
204
209
|
async def call_func_async(fc_name, fc_inputs, ns, raise_on_err=True):
|
|
205
210
|
"Awaits the function `fc_name` with the given `fc_inputs` using namespace `ns`."
|
|
206
211
|
res = call_func(fc_name, fc_inputs, ns, raise_on_err=raise_on_err)
|
|
207
212
|
if inspect.iscoroutine(res):
|
|
208
213
|
try: res = await res
|
|
209
214
|
except Exception as e:
|
|
210
|
-
if raise_on_err: raise e
|
|
215
|
+
if raise_on_err: raise e from None
|
|
211
216
|
else: return traceback.format_exc()
|
|
212
217
|
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.1"
|
|
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
|