dialoghelper

from fastcore import tools

Re-export asdict:


source

find_var

 find_var (var:str)

Search for var in all frames of the call stack

a = 1
find_var('a')
1

source

call_endp

 call_endp (path, dname='', json=False, raiseex=False, **data)

source

find_dname

 find_dname ()

*Get the message id by searching the call stack for __dialog_id.*


source

find_msg_id

 find_msg_id ()

*Get the message id by searching the call stack for __dialog_id.*

find_msg_id()
'_9cbd170d'

source

curr_dialog

 curr_dialog (with_messages:bool=False, dname:str='')

Get the current dialog info.

Type Default Details
with_messages bool False Include messages as well?
dname str Running dialog to get info for; defaults to current dialog

source

find_msgs

 find_msgs (re_pattern:str='', msg_type:str=None, limit:int=None,
            include_output:bool=True, dname:str='')

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.

Type Default Details
re_pattern str Optional regex to search for (re.DOTALL+re.MULTILINE is used)
msg_type str None optional limit by message type (‘code’, ‘note’, or ‘prompt’)
limit int None Optionally limit number of returned items
include_output bool True Include output in returned dict?
dname str Running dialog to get info for; defaults to current dialog
# NB: must have a dialogue open including a message with this text in its content
txt = 'tools'
found = find_msgs(txt)
found[0]['content']
'from fastcore import tools'

source

msg_idx

 msg_idx (msgid=None, dname:str='')

Get absolute index of message in dialog.

Type Default Details
msgid NoneType None Message id to find (defaults to current message)
dname str Running dialog to get info for; defaults to current dialog
msg_idx()
16

source

add_html

 add_html (content:str, dname:str='')

Send HTML to the browser to be swapped into the DOM

Type Default Details
content str The HTML to send to the client (generally should include hx-swap-oob)
dname str Running dialog to get info for; defaults to current dialog
from fasthtml.common import *
add_html(Div(P('Hi'), hx_swap_oob='beforeend:#dialog-container'))

source

add_msg

 add_msg (content:str, placement:str='add_after', msgid:str=None,
          msg_type:str='note', output:str='', time_run:str|None='',
          is_exported:int|None=0, skipped:int|None=0,
          i_collapsed:int|None=0, o_collapsed:int|None=0,
          heading_collapsed:int|None=0, pinned:int|None=0, dname:str='')

Add/update a message to the queue to show after code execution completes.

Type Default Details
content str Content of the message (i.e the message prompt, code, or note text)
placement str add_after Can be ‘add_after’, ‘add_before’, ‘at_start’, ‘at_end’
msgid str None id of message that placement is relative to (if None, uses current message)
msg_type str note Message type, can be ‘code’, ‘note’, or ‘prompt’
output str For prompts/code, initial output
time_run str | None When was message executed
is_exported int | None 0 Export message to a module?
skipped int | None 0 Hide message from prompt?
i_collapsed int | None 0 Collapse input?
o_collapsed int | None 0 Collapse output?
heading_collapsed int | None 0 Collapse heading section?
pinned int | None 0 Pin to context?
dname str Running dialog to get info for; defaults to current dialog
_id = add_msg('testing')

source

del_msg

 del_msg (msgid:str=None, dname:str='')

Delete a message from the dialog.

Type Default Details
msgid str None id of message to delete
dname str Running dialog to get info for; defaults to current dialog
del_msg(_id)
_id = _add_msg_unsafe('1+1', run=True, msg_type='code')
del_msg(_id)
_id = _add_msg_unsafe('Hi', run=True, msg_type='prompt')
del_msg(_id)

source

update_msg

 update_msg (msgid:str=None, msg:Optional[Dict]=None, dname:str='',
             content:str|None=None, msg_type:str|None=None,
             output:str|None=None, time_run:str|None=None,
             is_exported:int|None=None, skipped:int|None=None,
             i_collapsed:int|None=None, o_collapsed:int|None=None,
             heading_collapsed:int|None=None, pinned:int|None=None)

Update an existing message. Provide either msg OR field key/values to update. Use content param to update contents. Only include parameters to update–missing ones will be left unchanged.

Type Default Details
msgid str None id of message to update (if None, uses current message)
msg Optional None Dictionary of field keys/values to update
dname str Running dialog to get info for; defaults to current dialog
content str | None None Content of the message (i.e the message prompt, code, or note text)
msg_type str | None None Message type, can be ‘code’, ‘note’, or ‘prompt’
output str | None None For prompts/code, the output
time_run str | None None When was message executed
is_exported int | None None Export message to a module?
skipped int | None None Hide message from prompt?
i_collapsed int | None None Collapse input?
o_collapsed int | None None Collapse output?
heading_collapsed int | None None Collapse heading section?
pinned int | None None Pin to context?
_id = add_msg('testing')
_id = update_msg(_id, content='toasting')
_id = update_msg(_id, skipped=1)
del_msg(_id)

source

url2note

 url2note (url:str, extract_section:bool=True, selector:str=None)

Read URL as markdown, and add a note below current message with the result

Type Default Details
url str URL to read
extract_section bool True If url has an anchor, return only that section
selector str None Select section(s) using BeautifulSoup.select (overrides extract_section)
_id = url2note('https://www.example.org')
del_msg(_id)

source

ast_py

 ast_py (code:str)

Get an SgRoot root node for python code

node = ast_py("print('hello world')")
stmt = node.find(pattern="print($A)")
res = stmt.get_match('A')
res.text(),res.range()
("'hello world'",
 Range(start=Pos(line=0, col=6, index=6), end=Pos(line=0, col=19, index=19)))

source

ast_grep

 ast_grep (pattern:str, path='.', lang='python')

Use the ast-grep command to find pattern in path

Type Default Details
pattern str ast-grep pattern to search
path str . path to recursively search for files
lang str python language to search/scan
res = ast_grep(r"xpost($A, data=$B)", '..')
[(o['text'],o['metaVariables']['single'],o['file']) for o in res]
[("xpost(f'http://localhost:5001/{path}', data=data)",
  {'A': {'text': "f'http://localhost:5001/{path}'",
    'range': {'byteOffset': {'start': 1651, 'end': 1682},
     'start': {'line': 43, 'column': 16},
     'end': {'line': 43, 'column': 47}}},
   'B': {'text': 'data',
    'range': {'byteOffset': {'start': 1689, 'end': 1693},
     'start': {'line': 43, 'column': 54},
     'end': {'line': 43, 'column': 58}}}},
  'dialoghelper/core.py')]

source

read_msg

 read_msg (n:int=-1, relative:bool=True, msgid:str=None,
           view_range:list[int,int]=None, nums:bool=False, dname:str='')

Get the Message object indexed in the current dialog.

Type Default Details
n int -1 Message index (if relative, +ve is downwards)
relative bool True Is n relative to current message (True) or absolute (False)?
msgid str None Message id to find (defaults to current message)
view_range list None Optional 1-indexed (start, end) line range for files, end=-1 for EOF
nums bool False Whether to show line numbers
dname str Running dialog to get info for; defaults to current dialog
_edit_id = add_msg('This message should be found.\n\nThis is a multiline message.')
print(read_msg()['msg']['content'])
This message should be found.

This is a multiline message.
print(read_msg(n=0, msgid=_edit_id, nums=True)['msg']['content'])
     1 │ This message should be found.
     2 │ 
     3 │ This is a multiline message.
print(read_msg(n=0, msgid=_edit_id, nums=True, view_range=[2,3])['msg']['content'])
     2 │ 
     3 │ This is a multiline message.

source

run_msg

 run_msg (msgid:str=None, dname:str='')

Adds a message to the run queue. Use read_msg to see the output once it runs.

Type Default Details
msgid str None id of message to execute
dname str Running dialog to get info for; defaults to current dialog
1+1
2
codeid = read_msg()['msg']['id']
run_msg(codeid)
'{"status":"queued"}'

Text Edit


source

msg_insert_line

 msg_insert_line (msgid:str, insert_line:int, new_str:str, dname:str='')

Insert text at a specific line number in a message

Type Default Details
msgid str Message id to edit
insert_line int The line number after which to insert the text (0 for beginning of file)
new_str str The text to insert
dname str Running dialog to get info for; defaults to current dialog
msg_insert_line(_edit_id, 0, 'This should go to the first line')
msg_insert_line(_edit_id, 3, 'This should go to the 4th line')
msg_insert_line(_edit_id, 5, 'This should go to the last line')
{'success': 'Inserted text after line 5 in message _c3e8e7f8'}
print(read_msg(n=0, msgid=_edit_id, nums=True)['msg']['content'])
     1 │ This should go to the first line
     2 │ This message should be found.
     3 │ 
     4 │ This should go to the 4th line
     5 │ This is a multiline message.
     6 │ This should go to the last line

source

msg_str_replace

 msg_str_replace (msgid:str, old_str:str, new_str:str, dname:str='')

Replace first occurrence of old_str with new_str in a message

Type Default Details
msgid str Message id to edit
old_str str Text to find and replace
new_str str Text to replace with
dname str Running dialog to get info for; defaults to current dialog
msg_str_replace(_edit_id, 'This should go to the first line', 'This should go to the 1st line')
{'success': 'Replaced text in message _c3e8e7f8'}
print(read_msg(n=0, msgid=_edit_id, nums=True)['msg']['content'])
     1 │ This should go to the 1st line
     2 │ This message should be found.
     3 │ 
     4 │ This should go to the 4th line
     5 │ This is a multiline message.
     6 │ This should go to the last line

source

msg_strs_replace

 msg_strs_replace (msgid:str, old_strs:list[str], new_strs:list[str],
                   dname:str='')

Replace multiple strings simultaneously in a message

Type Default Details
msgid str Message id to edit
old_strs list List of strings to find and replace
new_strs list List of replacement strings (must match length of old_strs)
dname str Running dialog to get info for; defaults to current dialog
msg_strs_replace(_edit_id, ['This is a multiline message.', 'This should go to the last line'], ['5th line', 'last line'])
{'success': 'Successfully replaced all the strings in message _c3e8e7f8'}
print(read_msg(n=0, msgid=_edit_id, nums=True)['msg']['content'])
     1 │ This should go to the 1st line
     2 │ This message should be found.
     3 │ 
     4 │ This should go to the 4th line
     5 │ 5th line
     6 │ last line

source

msg_replace_lines

 msg_replace_lines (msgid:str, start_line:int, end_line:int,
                    new_content:str, dname:str='')

Replace a range of lines with new content in a message

Type Default Details
msgid str Message id to edit
start_line int Starting line number to replace (1-based indexing)
end_line int Ending line number to replace (1-based indexing, inclusive)
new_content str New content to replace the specified lines
dname str Running dialog to get info for; defaults to current dialog
msg_replace_lines(_edit_id, 2, 4,'line 2\nline 3\nline 4\n')
{'success': 'Replaced lines 2 to 4 in message _c3e8e7f8'}
print(read_msg(n=0, msgid=_edit_id, nums=True)['msg']['content'])
     1 │ This should go to the 1st line
     2 │ line 2
     3 │ line 3
     4 │ line 4
     5 │ 5th line
     6 │ last line
del_msg(_edit_id)

Gists


source

load_gist

 load_gist (gist_id:str)

Retrieve a gist

gistid = 'jph00/e7cfd4ded593e8ef6217e78a0131960c'
gist = load_gist(gistid)
gist.html_url

source

gist_file

 gist_file (gist_id:str)

Get the first file from a gist

gfile = gist_file(gistid)
print(gfile.content[:100]+"…")

source

import_string

 import_string (code:str, name:str)
Type Details
code str Code to import as a module
name str Name of module to create

source

is_usable_tool

 is_usable_tool (func:<built-infunctioncallable>)

True if the function has a docstring and all parameters have types, meaning that it can be used as an LLM tool.

def hi(who:str):
    "Say hi to `who`"
    return f"Hello {who}"

def hi2(who):
    "Say hi to `who`"
    return f"Hello {who}"

def hi3(who:str):
    return f"Hello {who}"

bye = "bye"
assert is_usable_tool(hi)
assert not is_usable_tool(hi2)
assert not is_usable_tool(hi3)
assert not is_usable_tool(bye)

source

mk_toollist

 mk_toollist (syms)
Markdown(mk_toollist([hi]))

source

import_gist

 import_gist (gist_id:str, mod_name:str=None, add_global:bool=True,
              import_wildcard:bool=False, create_msg:bool=False)

Import gist directly from string without saving to disk

Type Default Details
gist_id str user/id or just id of gist to import as a module
mod_name str None module name to create (taken from gist filename if not passed)
add_global bool True add module to caller’s globals?
import_wildcard bool False import all exported symbols to caller’s globals
create_msg bool False Add a message that lists usable tools
import_gist(gistid)
importtest.testfoo
import_gist.__doc__
import_gist(gistid, import_wildcard=True)
importtest.testfoo
hi("Sarah")
importtest.__all__

Tool info

This is how we get a superset of tools to include:


source

tool_info

 tool_info ()
for o in _all:
    s = globals()[o]
    if s.__name__[0]=='_' or not s.__doc__: continue
    print(f'- &`{s.__name__}`: {s.__doc__}')

source

fc_tool_info

 fc_tool_info ()
for o in tools.__all__:
    s = getattr(tools, o)
    print(f'- &`{s.__name__}`: {s.__doc__}')