Skip to content

Commit e318b39

Browse files
committed
fixes #22
1 parent 02dade7 commit e318b39

3 files changed

Lines changed: 273 additions & 501 deletions

File tree

dialoghelper/_modidx.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,22 @@
66
'git_url': 'https://github.com/AnswerDotAI/dialoghelper',
77
'lib_path': 'dialoghelper'},
88
'syms': { 'dialoghelper.core': { 'dialoghelper.core._add_msg_unsafe': ('core.html#_add_msg_unsafe', 'dialoghelper/core.py'),
9-
'dialoghelper.core._msg': ('core.html#_msg', 'dialoghelper/core.py'),
109
'dialoghelper.core._umsg': ('core.html#_umsg', 'dialoghelper/core.py'),
1110
'dialoghelper.core.add_html': ('core.html#add_html', 'dialoghelper/core.py'),
1211
'dialoghelper.core.add_msg': ('core.html#add_msg', 'dialoghelper/core.py'),
12+
'dialoghelper.core.call_endp': ('core.html#call_endp', 'dialoghelper/core.py'),
1313
'dialoghelper.core.del_msg': ('core.html#del_msg', 'dialoghelper/core.py'),
14-
'dialoghelper.core.export_dialog': ('core.html#export_dialog', 'dialoghelper/core.py'),
15-
'dialoghelper.core.find_dialog_id': ('core.html#find_dialog_id', 'dialoghelper/core.py'),
1614
'dialoghelper.core.find_msg_id': ('core.html#find_msg_id', 'dialoghelper/core.py'),
1715
'dialoghelper.core.find_msgs': ('core.html#find_msgs', 'dialoghelper/core.py'),
1816
'dialoghelper.core.find_var': ('core.html#find_var', 'dialoghelper/core.py'),
19-
'dialoghelper.core.get_db': ('core.html#get_db', 'dialoghelper/core.py'),
2017
'dialoghelper.core.gist_file': ('core.html#gist_file', 'dialoghelper/core.py'),
21-
'dialoghelper.core.import_dialog': ('core.html#import_dialog', 'dialoghelper/core.py'),
2218
'dialoghelper.core.import_gist': ('core.html#import_gist', 'dialoghelper/core.py'),
2319
'dialoghelper.core.import_string': ('core.html#import_string', 'dialoghelper/core.py'),
2420
'dialoghelper.core.is_usable_tool': ('core.html#is_usable_tool', 'dialoghelper/core.py'),
2521
'dialoghelper.core.load_gist': ('core.html#load_gist', 'dialoghelper/core.py'),
2622
'dialoghelper.core.mk_toollist': ('core.html#mk_toollist', 'dialoghelper/core.py'),
2723
'dialoghelper.core.msg_idx': ('core.html#msg_idx', 'dialoghelper/core.py'),
2824
'dialoghelper.core.read_msg': ('core.html#read_msg', 'dialoghelper/core.py'),
29-
'dialoghelper.core.read_msg_ids': ('core.html#read_msg_ids', 'dialoghelper/core.py'),
3025
'dialoghelper.core.tool_info': ('core.html#tool_info', 'dialoghelper/core.py'),
3126
'dialoghelper.core.update_msg': ('core.html#update_msg', 'dialoghelper/core.py')},
3227
'dialoghelper.db_dc': {}}}

dialoghelper/core.py

Lines changed: 46 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.
22

33
# %% auto 0
4-
__all__ = ['Placements', 'empty', 'get_db', 'find_var', 'find_dialog_id', 'find_msgs', 'find_msg_id', 'read_msg_ids', 'msg_idx',
5-
'read_msg', 'add_html', 'del_msg', 'add_msg', 'update_msg', 'load_gist', 'gist_file', 'import_string',
6-
'is_usable_tool', 'mk_toollist', 'import_gist', 'export_dialog', 'import_dialog', 'tool_info', 'asdict']
4+
__all__ = ['Placements', 'empty', 'find_var', 'call_endp', 'find_msgs', 'find_msg_id', 'msg_idx', 'read_msg', 'add_html',
5+
'del_msg', 'add_msg', 'update_msg', 'load_gist', 'gist_file', 'import_string', 'is_usable_tool',
6+
'mk_toollist', 'import_gist', 'tool_info', 'asdict']
77

88
# %% ../nbs/00_core.ipynb
99
import json, importlib, linecache
@@ -26,17 +26,6 @@
2626
# %% ../nbs/00_core.ipynb
2727
_all_ = ["asdict"]
2828

29-
# %% ../nbs/00_core.ipynb
30-
def get_db(ns:dict=None):
31-
app_path = Path('/app') if Path('/.dockerenv').exists() else Path('.')
32-
if os.environ.get('IN_SOLVEIT', False): dataparent,nm = app_path, 'data.db'
33-
else: dataparent,nm = Path('..'),'dev_data.db'
34-
db = database(dataparent/'data'/nm)
35-
dcs = [o for o in all_dcs(db) if o.__name__[0]!='_']
36-
if ns:
37-
for o in dcs: ns[o.__name__]=o
38-
return db
39-
4029
# %% ../nbs/00_core.ipynb
4130
def find_var(var:str):
4231
"Search for var in all frames of the call stack"
@@ -48,22 +37,20 @@ def find_var(var:str):
4837
raise ValueError(f"Could not find {var} in any scope")
4938

5039
# %% ../nbs/00_core.ipynb
51-
def find_dialog_id():
52-
"Get the dialog id by searching the call stack for __dialog_id."
53-
return find_var('__dialog_id')
40+
def call_endp(path, json=False, raiseex=False, **data):
41+
res = xpost(f'http://localhost:5001/{path}', data=data)
42+
if raiseex: res.raise_for_status()
43+
return res.json() if json else res.text
5444

5545
# %% ../nbs/00_core.ipynb
5646
def find_msgs(
57-
pattern:str='', # Optional text to search for
47+
re_pattern:str='', # Optional regex to search for (re.DOTALL+re.MULTILINE is used)
5848
msg_type:str=None, # optional limit by message type ('code', 'note', or 'prompt')
5949
limit:int=None, # Optionally limit number of returned items
6050
include_output:bool=True # Include output in returned dict?
6151
)->list[dict]:
62-
"Find `list[dict]` of messages in current specific dialog that contain the given information. To refer to a message found later, use its `sid` field (which is the pk)."
63-
did = find_dialog_id()
64-
db = get_db()
65-
res = db.t.message('did=? AND content LIKE ? ORDER BY mid', [did, f'%{pattern}%'], limit=limit)
66-
res = [asdict(o) for o in res if not msg_type or (msg_type==o.msg_type)]
52+
"Find `list[dict]` of messages in current specific dialog that contain the given information. To refer to a message found later, use its `id` field."
53+
res = call_endp('find_msgs_', json=True, re_pattern=re_pattern, msg_type=msg_type, limit=limit)['msgs']
6754
if not include_output:
6855
for o in res: o.pop('output', None)
6956
return res
@@ -74,83 +61,61 @@ def find_msg_id():
7461
return find_var('__msg_id')
7562

7663
# %% ../nbs/00_core.ipynb
77-
def read_msg_ids()->list[str]:
78-
"Get all ids in current dialog."
79-
did = find_dialog_id()
80-
db = get_db()
81-
return [o.sid for o in db.t.message('did=?', [did], select='sid', order_by='mid')]
82-
83-
# %% ../nbs/00_core.ipynb
84-
def msg_idx():
85-
"Get relative index of current message in dialog."
86-
ids = read_msg_ids()
87-
return ids,ids.index(find_msg_id())
64+
def msg_idx(
65+
msgid=None # Message id to find (defaults to current message)
66+
):
67+
"Get relative index of message in dialog."
68+
if not msgid: msgid = find_msg_id()
69+
return call_endp('msg_idx_', json=True, msgid=msgid)['msgid']
8870

8971
# %% ../nbs/00_core.ipynb
90-
def read_msg(n:int=-1, # Message index (if relative, +ve is downwards)
91-
relative:bool=True # Is `n` relative to current message (True) or absolute (False)?
72+
def read_msg(
73+
n:int=-1, # Message index (if relative, +ve is downwards)
74+
msgid=None, # Message id to find (defaults to current message)
75+
relative:bool=True # Is `n` relative to current message (True) or absolute (False)?
9276
):
9377
"Get the `Message` object indexed in the current dialog."
94-
ids,idx = msg_idx()
95-
if relative:
96-
idx = idx+n
97-
if not 0<=idx<len(ids): return None
98-
else: idx = n
99-
db = get_db()
100-
return db.t.message.selectone('sid=?', [ids[idx]])
78+
if not msgid: msgid = find_msg_id()
79+
return call_endp('read_msg_', json=True, msgid=msgid, n=n, relative=relative)['msg']
10180

10281
# %% ../nbs/00_core.ipynb
10382
def add_html(
10483
content:str, # The HTML to send to the client (generally should include hx-swap-oob)
10584
):
10685
"Send HTML to the browser to be swapped into the DOM"
107-
xpost('http://localhost:5001/add_html_', data=dict(content=to_xml(content)))
86+
call_endp('add_html_', content=to_xml(content))
10887

10988
# %% ../nbs/00_core.ipynb
11089
def del_msg(
111-
sid:str=None, # sid (stable id -- pk) of message that placement is relative to (if None, uses current message)
90+
msgid:str=None, # id of message that placement is relative to (if None, uses current message)
11291
):
11392
"Delete a message from the dialog. Be sure to pass a `sid`, not a `mid`."
114-
xpost('http://localhost:5001/rm_msg_', data=dict(msid=sid)).raise_for_status()
93+
call_endp('rm_msg_', raiseex=True, msid=msgid)
94+
95+
# %% ../nbs/00_core.ipynb
96+
Placements = str_enum('Placements', 'add_after', 'add_before', 'at_start', 'at_end')
11597

11698
# %% ../nbs/00_core.ipynb
117-
def _msg(
99+
def add_msg(
100+
content:str, # Content of the message (i.e the message prompt, code, or note text)
101+
placement:str='add_after', # Can be 'add_after', 'add_before', 'at_start', 'at_end'
102+
msgid:str=None, # id of message that placement is relative to (if None, uses current message)
118103
msg_type: str='note', # Message type, can be 'code', 'note', or 'prompt'
119104
output:str='', # For prompts/code, initial output
120105
time_run: str | None = '', # When was message executed
121106
is_exported: int | None = 0, # Export message to a module?
122107
skipped: int | None = 0, # Hide message from prompt?
123108
i_collapsed: int | None = 0, # Collapse input?
124109
o_collapsed: int | None = 0, # Collapse output?
125-
header_collapsed: int | None = 0, # Collapse heading section?
126-
pinned: int | None = 0 # Pin to context?
127-
): ...
128-
129-
Placements = str_enum('Placements', 'add_after', 'add_before', 'update', 'at_start', 'at_end')
130-
131-
# %% ../nbs/00_core.ipynb
132-
@delegates(_msg)
133-
def add_msg(
134-
content:str, # Content of the message (i.e the message prompt, code, or note text)
135-
placement:str='add_after', # Can be 'add_after', 'add_before', 'update', 'at_start', 'at_end'
136-
sid:str=None, # sid (stable id -- pk) of message that placement is relative to (if None, uses current message)
137-
**kwargs
138-
):
139-
"""Add/update a message to the queue to show after code execution completes.
140-
Be sure to pass a `sid` (stable id) not a `mid` (which is used only for sorting, and can change).
141-
Sets msg_type to 'note' by default if not update placement."""
142-
if 'msg_type' not in kwargs and placement!='update': kwargs['msg_type']='note'
143-
mt = kwargs.get('msg_type',None)
144-
ot = kwargs.get('output',None)
145-
if mt and mt not in ('note', 'code', 'prompt'): return "msg_type must be 'code', 'note', or 'prompt'."
146-
if mt=='note' and ot: return "note messages cannot have an output."
147-
if mt=='code':
148-
try: json.loads(ot or '[]')
149-
except: return "Code output must be valid json"
150-
if not sid: sid = find_msg_id()
151-
data = dict(placement=placement, sid=sid, **kwargs)
152-
if content is not None: data['content'] = content
153-
return xpost('http://localhost:5001/add_relative_', data=data).text
110+
heading_collapsed: int | None = 0, # Collapse heading section?
111+
pinned: int | None = 0, # Pin to context?
112+
**kwargs):
113+
"Add/update a message to the queue to show after code execution completes."
114+
if placement not in ('at_start','at_end') and not msgid: msgid = find_msg_id()
115+
return call_endp(
116+
'add_relative_', content=content, placement=placement, msgid=msgid, msg_type=msg_type, output=output,
117+
time_run=time_run, is_exported=is_exported, skipped=skipped, pinned=pinned,
118+
i_collapsed=i_collapsed, o_collapsed=o_collapsed, heading_collapsed=heading_collapsed, **kwargs)
154119

155120
# %% ../nbs/00_core.ipynb
156121
@delegates(add_msg)
@@ -172,26 +137,22 @@ def _umsg(
172137
skipped: int | None = None, # Hide message from prompt?
173138
i_collapsed: int | None = None, # Collapse input?
174139
o_collapsed: int | None = None, # Collapse output?
175-
header_collapsed: int | None = None, # Collapse heading section?
140+
heading_collapsed: int | None = None, # Collapse heading section?
176141
pinned: int | None = None # Pin to context?
177142
): ...
178143

179144
# %% ../nbs/00_core.ipynb
180145
@delegates(_umsg)
181146
def update_msg(
182-
sid:str=None, # sid (stable id -- pk) of message to update (if None, uses current message)
147+
msgid:str=None, # id of message to update (if None, uses current message)
183148
content:str|None=None, # Content of the message (i.e the message prompt, code, or note text)
184149
msg:Optional[Dict]=None, # Dictionary of field keys/values to update
185150
**kwargs):
186151
"""Update an existing message. Provide either `msg` OR field key/values to update.
187-
Use `content` param to update contents. Be sure to pass a `sid` (stable id -- the pk) not a `mid`
188-
(which is used only for sorting, and can change).
152+
Use `content` param to update contents.
189153
Only include parameters to update--missing ones will be left unchanged."""
190-
kw = (msg or {}) | kwargs
191-
sid = kw.pop('sid', sid)
192-
if not sid: raise TypeError("update_msg needs either a dict message or `sid=...`")
193-
kw.pop('did', None)
194-
return add_msg(content, placement='update', sid=sid, **kw)
154+
if not msgid and not msg: raise TypeError("update_msg needs either a dict message or `msgid=`")
155+
return call_endp('add_relative_', content=content, placement='update', msgid=msgid, **kwargs)
195156

196157
# %% ../nbs/00_core.ipynb
197158
def load_gist(gist_id:str):
@@ -259,32 +220,6 @@ def import_gist(
259220
add_msg(f"{pref}\n\n{mk_toollist(syms)}")
260221
return module
261222

262-
# %% ../nbs/00_core.ipynb
263-
__EXPORT_FIELDS = set('content output input_tokens output_tokens msg_type is_exported skipped pinned i_collapsed o_collapsed header_collapsed'.split())
264-
265-
__REQUIRED_FIELDS = set('content output msg_type'.split())
266-
267-
# %% ../nbs/00_core.ipynb
268-
def export_dialog(filename: str, did:int=None):
269-
"Export dialog messages and optionally attachments to JSON"
270-
if did is None: did = find_dialog_id()
271-
db = get_db()
272-
msgs = db.t.message('did=? and (pinned=0 or pinned is null)', [did], order_by='mid')
273-
msg_data = [{k:getattr(msg,k) for k in __EXPORT_FIELDS if hasattr(msg, k)}
274-
for msg in msgs]
275-
result = {'messages': msg_data, 'dialog_name': db.t.dialog[did].name}
276-
with open(filename, 'w') as f: json.dump(result, f, indent=2)
277-
278-
# %% ../nbs/00_core.ipynb
279-
def import_dialog(fname, add_header=True):
280-
"Import dialog messages from JSON file using `add_msg`"
281-
data = json.loads(Path(fname).read_text())
282-
for msg in data['messages'][::-1]:
283-
opts = {k:msg[k] for k in __EXPORT_FIELDS - __REQUIRED_FIELDS if k in msg}
284-
add_msg(msg.get('content',''), msg.get('msg_type','note'), msg.get('output',''), 'at_end', **opts)
285-
if add_header: add_msg(f"# Imported Dialog `{fname}`", 'note', placement='at_end')
286-
return f"Imported {len(data['messages'])} messages"
287-
288223
# %% ../nbs/00_core.ipynb
289224
def tool_info():
290225
cts='''Tools available from `dialoghelper`:

0 commit comments

Comments
 (0)