dialoghelper

from dialoghelper import *
from fastcore import tools

Helpers


source

add_styles

 add_styles (s:str, cls_map:dict=None)

Add solveit styles to s

import mistletoe
from fasthtml.common import show
s = mistletoe.markdown("### hi\n\n- first\n- *second*")
s
'<h3>hi</h3>\n<ul>\n<li>first</li>\n<li><em>second</em></li>\n</ul>\n'
show(s)

hi

  • first
  • second
show(add_styles(s))

hi

  • first
  • second

Basics


source

set_var

 set_var (var:str, val)

Set var to val after finding it in all frames of the call stack


source

find_var

 find_var (var:str)

Search for var in all frames of the call stack

a = 1
find_var('a')
1
set_var('a', 42)
a
42
# dh_settings = {'port':6001}

source

find_msg_id

 find_msg_id ()

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


source

find_dname

 find_dname (dname=None)

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

find_dname()
'aai-ws/dialoghelper/nbs/00_core'
find_dname('index')
'aai-ws/dialoghelper/nbs/index'
find_dname('../index')
'aai-ws/dialoghelper/index'
find_dname('/foo/bar')
'foo/bar'

source

call_endp

 call_endp (path, dname='', json=False, raiseex=False, id=None, **data)
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 Dialog to get info for; defaults to current dialog

source

msg_idx

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

Get absolute index of message in dialog.

Type Default Details
id NoneType None Message id to find (defaults to current message)
dname str Dialog to get message index from; defaults to current dialog
msg_idx()
26

source

add_scr

 add_scr (scr, oob='beforeend:#js-script')

Swap a script element to the end of the js-script element


source

iife

 iife (code:str)

Wrap javascript code string in an IIFE and execute it via add_html


source

pop_data

 pop_data (idx, timeout=15)

source

fire_event

 fire_event (evt:str, data=None)

source

event_get

 event_get (evt:str, timeout=15, data=None)

Call fire_event and then pop_data to get a response

View/edit 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 requested dialog that contain the given information. Call with no args to see the full dialog. Often it is more efficient to call once with no re_pattern to see the whole dialog at once, so you can then use the full context from then on. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension. Message ids are identical to those in LLM chat history, so do NOT call this to view a specific message if it’s in the chat history–instead use read_msgid. Note that LLM chat history only includes messages above the current prompt, whereas find_msgs can access all messages. To refer to a found message from code or tools, 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 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']
'import json,importlib,linecache,re,inspect,uuid\nfrom typing import Dict\nfrom tempfile import TemporaryDirectory\nfrom ipykernel_helper import *\nfrom dataclasses import dataclass\nfrom os.path import normpath\nfrom fastcore.xml import to_xml\n\nfrom fastcore.utils import *\nfrom fastcore.meta import delegates\nfrom ghapi.all import *\nfrom fastcore.xtras import asdict\nfrom inspect import currentframe,Parameter,signature\nfrom httpx import get as xget, post as xpost\nfrom IPython.display import display,Markdown\nfrom monsterui.all import franken_class_map,apply_classes\nfrom fasthtml.common import Safe,Script,Div\nfrom toolslm.xml import *'

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 Dialog to get info for; defaults to current dialog
from fasthtml.common import *
add_html(Div(P('Hi'), hx_swap_oob='beforeend:#dialog-container'))
{'success': 'Content added to DOM'}

source

read_msg

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

Get the message indexed in the current dialog. - To get the exact message use n=0 and relative=True together with id. - To get a relative message use n (relative position index). - To get the nth message use n with relative=False, e.g n=0 first message, n=-1 last message. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

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)?
id 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 Dialog to get info for; defaults to current dialog

source

read_msgid

 read_msgid (id:str, view_range:list[int,int]=None, nums:bool=False,
             dname:str='')

Get message id. Message IDs can be view directly in LLM chat history/context, or found in find_msgs results. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str Message id to find
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 Dialog to get message from; defaults to current dialog

source

add_msg

 add_msg (content:str, placement:str='add_after', id: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. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

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’
id str None id of message that placement is relative to (if None, uses current message; note: each add_msg updates “current” to the newly created message)
msg_type str note Message type, can be ‘code’, ‘note’, or ‘prompt’
output str Prompt/code output; Code outputs must be .ipynb-compatible JSON array
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 Dialog to get info for; defaults to current dialog
print(__msg_id)
_id = add_msg('testing')
print(__msg_id)
_9c544573
_364a3505
print(read_msg().content)
testing

read_msg (and all endpoints that return json) wrap responses in dict2obj, so you can use either dict or object syntax.

# dh_settings['dname'] = 'tmp'
# _id = add_msg('testing', placement='at_end')
# print(_id)
# del(dh_settings['dname'])

source

del_msg

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

Delete a message from the dialog.

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

source

update_msg

 update_msg (id: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. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str None id of message to update (if None, uses current message)
msg Optional None Dictionary of field keys/values to update
dname str 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 Prompt/code output; Code outputs must be .ipynb-compatible JSON array
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)
msg = read_msgid(_id)
msg['content'] = 'toasted'
update_msg(msg=msg)
'_894a270c'
del_msg(_id)
{'status': 'success'}
_edit_id = add_msg('This message should be found.\n\nThis is a multiline message.')
print(read_msg()['content'])
This message should be found.

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

source

run_msg

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

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

Type Default Details
ids str None Comma-separated ids of message(s) to execute
dname str Running dialog to get info for; defaults to current dialog. (Note dialog must be running for this function)
1+1
2
codeid = read_msg()['id']
run_msg(codeid)
'{"status":"queued"}'

source

copy_msg

 copy_msg (ids:str=None, cut:bool=False, dname:str='')

Add ids to clipboard.

Type Default Details
ids str None Comma-separated ids of message(s) to copy
cut bool False Cut message(s)? (If not, copies)
dname str Running dialog to copy messages from; defaults to current dialog. (Note dialog must be running for this function)

source

paste_msg

 paste_msg (id:str=None, after:bool=True, dname:str='')

Paste clipboard msg(s) after/before the current selected msg (id).

Type Default Details
id str None Message id to paste next to
after bool True Paste after id? (If not, pastes before)
dname str Running dialog to copy messages from; defaults to current dialog. (Note dialog must be running for this function)
copy_msg(codeid)
{'success': 'complete'}
tgt = read_msg()['id']
paste_msg(tgt)
{'success': 'complete'}
newmsg = read_msg(1, id=tgt)
newmsg['content']
'1+1'
del_msg(newmsg['id'])
{'status': 'success'}

source

enable_mermaid

 enable_mermaid ()
enable_mermaid()

source

mermaid

 mermaid (code, cls='mermaid', **kwargs)

A mermaid diagram

mermaid('graph LR; A[Start] --> B[Process]; B --> C[End];')
graph LR; A[Start] --> B[Process]; B --> C[End];

source

toggle_header

 toggle_header (id:str, dname:str='')

Toggle collapsed header state for id

Type Default Details
id str id of markdown header note message to toggle collapsed state
dname str Running dialog to copy messages from; defaults to current dialog. (Note dialog must be running for this function)

test header

hdid = read_msg()['id']

test note

header end

toggle_header(hdid)
{'success': 'complete'}

source

url2note

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

Read URL as markdown, and add note(s) 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)
ai_img bool True Make images visible to the AI
split_re str Regex to split content into multiple notes, set to ’’ for single note
_id = url2note('https://www.example.org')
del_msg(_id)
{'status': 'success'}

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:{dh_settings["port"]}/{path}\', data=data, headers=headers)',
  {'A': {'text': 'f\'http://localhost:{dh_settings["port"]}/{path}\'',
    'range': {'byteOffset': {'start': 3767, 'end': 3815},
     'start': {'line': 97, 'column': 16},
     'end': {'line': 97, 'column': 64}}},
   'B': {'text': 'data',
    'range': {'byteOffset': {'start': 3822, 'end': 3826},
     'start': {'line': 97, 'column': 71},
     'end': {'line': 97, 'column': 75}}}},
  'dialoghelper/core.py')]

Context


source

ctx_folder

 ctx_folder (path:pathlib.Path='.', types:str|list='py,doc', out=False,
             raw=True, prefix:bool=False, include_base:bool=True,
             title:str=None, max_size:int=100000, max_total:int=10000000,
             readme_first:bool=False, files_only:bool=False,
             ids:bool=True, recursive:bool=True, symlinks:bool=True,
             file_glob:str=None, file_re:str=None, folder_re:str=None,
             skip_file_glob:str=None, skip_file_re:str=None,
             skip_folder_re:str=None, func:callable=<function join>,
             ret_folders:bool=False, sort:bool=True, exts:str|list=None)

Convert folder to XML context and place in a new message

Type Default Details
path Path . Path to collect
types str | list py,doc list or comma-separated str of ext types from: py, js, java, c, cpp, rb, r, ex, sh, web, doc, cfg
out bool False Include notebook cell outputs?
raw bool True Add raw message, or note?
prefix bool False Include Anthropic’s suggested prose intro?
include_base bool True Include full path in src?
title str None Optional title attr for Documents element
max_size int 100000 Skip files larger than this (bytes)
max_total int 10000000 Max total output size in bytes
readme_first bool False Prioritize README files at start of context?
files_only bool False Return dict of {filename: size} instead of context?
ids bool True Include cell ids in notebooks?
recursive bool True search subfolders
symlinks bool True follow symlinks?
file_glob str None Only include files matching glob
file_re str None Only include files matching regex
folder_re str None Only enter folders matching regex
skip_file_glob str None Skip files matching glob
skip_file_re str None Skip files matching regex
skip_folder_re str None Skip folders matching regex,
func callable join function to apply to each matched file
ret_folders bool False return folders, not just files
sort bool True sort files by name within each folder
exts str | list None list or comma-separated str of exts to include
Returns L Paths to matched files
# ctx_folder(raw=False, max_total=500)
<documents><document index="1"><src>
00_core.ipynb
</src><document-content>
<notebook><code>#| default_exp core</code><code>from dialoghelper import *</code><md># dialoghelper</md><code>#| export
import json,importlib,linecache,re,inspect,uuid
from typing import Dict
from tempfile import TemporaryDirectory
from ipykernel_helper import *
from dataclasses import dataclass
from fastcore.xml import to_xml

from fastcore.utils import *
from

[TRUNCATED: output size 101206 exceeded max size 500 bytes]

source

ctx_repo

 ctx_repo (owner:str, repo:str, types:str|list='py,doc', out=False,
           raw=True, ref:str=None, folder:str=None,
           show_filters:bool=True, token:str=None, prefix:bool=False,
           include_base:bool=True, title:str=None, max_size:int=100000,
           max_total:int=10000000, readme_first:bool=False,
           files_only:bool=False, ids:bool=True, path:Path|str='.',
           recursive:bool=True, symlinks:bool=True, file_glob:str=None,
           file_re:str=None, folder_re:str=None, skip_file_glob:str=None,
           skip_file_re:str=None, skip_folder_re:str=None,
           func:callable=<function join>, ret_folders:bool=False,
           sort:bool=True, exts:str|list=None)

Convert GitHub repo to XML context and place in a new message

Type Default Details
owner str GitHub repo owner
repo str GitHub repo name
types str | list py,doc list or comma-separated str of ext types from: py, js, java, c, cpp, rb, r, ex, sh, web, doc, cfg
out bool False Include notebook cell outputs?
raw bool True Add raw message, or note?
ref str None Git ref (branch/tag/sha) (get from URL not provided); defaults to repo’s default branch
folder str None Only include files under this path (get from URL not provided)
show_filters bool True Include filter info in title?
token str None GitHub token (uses GITHUB_TOKEN env var if None)
prefix bool False Include Anthropic’s suggested prose intro?
include_base bool True Include full path in src?
title str None Optional title attr for Documents element
max_size int 100000 Skip files larger than this (bytes)
max_total int 10000000 Max total output size in bytes
readme_first bool False Prioritize README files at start of context?
files_only bool False Return dict of {filename: size} instead of context?
ids bool True Include cell ids in notebooks?
path pathlib.Path | str . path to start searching
recursive bool True search subfolders
symlinks bool True follow symlinks?
file_glob str None Only include files matching glob
file_re str None Only include files matching regex
folder_re str None Only enter folders matching regex
skip_file_glob str None Skip files matching glob
skip_file_re str None Skip files matching regex
skip_folder_re str None Skip folders matching regex,
func callable join function to apply to each matched file
ret_folders bool False return folders, not just files
sort bool True sort files by name within each folder
exts str | list None list or comma-separated str of exts to include
Returns Union XML for LM context, or dict of file sizes
# ctx_repo('answerdotai', 'toolslm', types='py', max_total=500, raw=False)
<documents title="GitHub repository contents from answerdotai/toolslm/main (filters applied -- types: py | max_total: 500)"><document index="1"><src>
00_xml.ipynb
</src><document-content>
<notebook><code>#|default_exp xml</code><md># xml source</md><code>#| export
import hashlib, inspect, xml.etree.ElementTree as ET
from collections import namedtuple
from ghapi.all import GhApi

from fastcore.utils import *
from fastcore.meta import de

[TRUNCATED: output size 102343 exceeded max size 500 bytes]

source

ctx_symfile

 ctx_symfile (sym)

Add note with filepath and contents for a symbol’s source file

# ctx_symfile(TemporaryDirectory)

source

ctx_symfolder

 ctx_symfolder (sym, types:str|list='py', skip_file_re='^_mod',
                prefix:bool=False, out:bool=True, include_base:bool=True,
                title:str=None, max_size:int=100000,
                max_total:int=10000000, readme_first:bool=False,
                files_only:bool=False, ids:bool=True, path:Path|str='.',
                recursive:bool=True, symlinks:bool=True,
                file_glob:str=None, file_re:str=None, folder_re:str=None,
                skip_file_glob:str=None, skip_folder_re:str=None,
                func:callable=<function join>, ret_folders:bool=False,
                sort:bool=True, exts:str|list=None)

Add raw message with folder context for a symbol’s source file location

Type Default Details
sym Symbol to get folder context from
types str | list py list or comma-separated str of ext types from: py, js, java, c, cpp, rb, r, ex, sh, web, doc, cfg
skip_file_re str None Skip files matching regex
prefix bool False Include Anthropic’s suggested prose intro?
out bool True Include notebook cell outputs?
include_base bool True Include full path in src?
title str None Optional title attr for Documents element
max_size int 100000 Skip files larger than this (bytes)
max_total int 10000000 Max total output size in bytes
readme_first bool False Prioritize README files at start of context?
files_only bool False Return dict of {filename: size} instead of context?
ids bool True Include cell ids in notebooks?
path pathlib.Path | str . path to start searching
recursive bool True search subfolders
symlinks bool True follow symlinks?
file_glob str None Only include files matching glob
file_re str None Only include files matching regex
folder_re str None Only enter folders matching regex
skip_file_glob str None Skip files matching glob
skip_folder_re str None Skip folders matching regex,
func callable join function to apply to each matched file
ret_folders bool False return folders, not just files
sort bool True sort files by name within each folder
exts str | list None list or comma-separated str of exts to include
Returns L Paths to matched files
# ctx_symfolder(folder2ctx)

source

ctx_sympkg

 ctx_sympkg (sym, types:str|list='py', skip_file_re='^_mod',
             prefix:bool=False, out:bool=True, include_base:bool=True,
             title:str=None, max_size:int=100000, max_total:int=10000000,
             readme_first:bool=False, files_only:bool=False,
             ids:bool=True, path:Path|str='.', recursive:bool=True,
             symlinks:bool=True, file_glob:str=None, file_re:str=None,
             folder_re:str=None, skip_file_glob:str=None,
             skip_folder_re:str=None, func:callable=<function join>,
             ret_folders:bool=False, sort:bool=True, exts:str|list=None)

Add raw message with repo context for a symbol’s root package

Type Default Details
sym Symbol to get folder context from
types str | list py list or comma-separated str of ext types from: py, js, java, c, cpp, rb, r, ex, sh, web, doc, cfg
skip_file_re str None Skip files matching regex
prefix bool False Include Anthropic’s suggested prose intro?
out bool True Include notebook cell outputs?
include_base bool True Include full path in src?
title str None Optional title attr for Documents element
max_size int 100000 Skip files larger than this (bytes)
max_total int 10000000 Max total output size in bytes
readme_first bool False Prioritize README files at start of context?
files_only bool False Return dict of {filename: size} instead of context?
ids bool True Include cell ids in notebooks?
path pathlib.Path | str . path to start searching
recursive bool True search subfolders
symlinks bool True follow symlinks?
file_glob str None Only include files matching glob
file_re str None Only include files matching regex
folder_re str None Only enter folders matching regex
skip_file_glob str None Skip files matching glob
skip_folder_re str None Skip folders matching regex,
func callable join function to apply to each matched file
ret_folders bool False return folders, not just files
sort bool True sort files by name within each folder
exts str | list None list or comma-separated str of exts to include
Returns L Paths to matched files
# ctx_sympkg(folder2ctx)

Text Edit


source

msg_insert_line

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

Insert text at a specific line number in a message. Be sure you’ve called read_msg(..., nums=True) to ensure you know the line numbers. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str Message id to edit
insert_line int The 1-based line number after which to insert the text (0: before 1st line, 1: after 1st line, 2: after 2nd, etc.)
new_str str The text to insert
dname str 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 _16a71d7b'}
print(read_msg(n=0, id=_edit_id, nums=True)['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 (id:str, old_str:str, new_str:str, dname:str='')

Replace first occurrence of old_str with new_str in a message. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str Message id to edit
old_str str Text to find and replace
new_str str Text to replace with
dname str 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 _16a71d7b'}
print(read_msg(n=0, id=_edit_id, nums=True)['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 (id:str, old_strs:list[str], new_strs:list[str],
                   dname:str='')

Replace multiple strings simultaneously in a message. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id 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 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 _16a71d7b'}
print(read_msg(n=0, id=_edit_id, nums=True)['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 (id:str, start_line:int, end_line:int=None,
                    new_content:str='', dname:str='')

Replace a range of lines with new content in a message. Be sure you’ve called read_msg(..., nums=True) to ensure you know the line numbers. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str Message id to edit
start_line int Starting line number to replace (1-based indexing)
end_line int None Ending line number to replace (1-based, inclusive, negative counts from end, None for single line)
new_content str New content to replace the specified lines
dname str 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 _16a71d7b'}
print(read_msg(n=0, id=_edit_id, nums=True)['content'])
     1 │ This should go to the 1st line
     2 │ line 2
     3 │ line 3
     4 │ line 4
     5 │ 5th line
     6 │ last line

source

msg_del_lines

 msg_del_lines (id:str, start_line:int, end_line:int=None, dname:str='')

Delete a range of lines from a message. Be sure you’ve called read_msg(..., nums=True) to ensure you know the line numbers. If dname is None, the current dialog is used. If it is an open dialog, it will be updated interactively with real-time updates to the browser. If it is a closed dialog, it will be updated on disk. Dialog names must be paths relative to the solveit root directory (if starting with /) or relative to the current dialog (if not starting with /), and should not include the .ipynb extension.

Type Default Details
id str Message id to edit
start_line int Starting line number to delete (1-based indexing)
end_line int None Ending line number to delete (1-based, inclusive, negative counts from end, None for single line)
dname str Dialog to get info for; defaults to current dialog
msg_del_lines(_edit_id, 2, 4)
{'success': 'Deleted lines 2 to 4 in message _16a71d7b'}
print(read_msg(n=0, id=_edit_id, nums=True)['content'])
     1 │ This should go to the 1st line
     2 │ 5th line
     3 │ last line
del_msg(_edit_id)
{'status': 'success'}

Gists


source

load_gist

 load_gist (gist_id:str)

Retrieve a gist

gistid = 'jph00/e7cfd4ded593e8ef6217e78a0131960c'
gist = load_gist(gistid)
gist.html_url
'https://gist.github.com/jph00/e7cfd4ded593e8ef6217e78a0131960c'

source

gist_file

 gist_file (gist_id:str)

Get the first file from a gist

gfile = gist_file(gistid)
print(gfile.content[:100]+"…")
"This is a test module which makes some simple tools available."
__all__ = ["hi","whoami"]

testfoo=…

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]))
  • &hi: Say hi to who

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
'testbar'
import_gist.__doc__
'Import gist directly from string without saving to disk'
import_gist(gistid, import_wildcard=True)
importtest.testfoo
'testbar'
hi("Sarah")
'Hello Sarah'
importtest.__all__
['hi', 'whoami']

Tool info

from dialoghelper.core import __all__ as _all

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


source

tool_info

 tool_info ()

source

fc_tool_info

 fc_tool_info ()

source

is_tool

 is_tool (o)

Check if o is a valid tool (has name, docstring, and all params have type annotations)

# Dialoghelper tools
for o in _all:
    s = globals()[o]
    if is_tool(s): print(f'`{s.__name__}`', end=' ')
`add_styles` `find_var` `find_msg_id` `curr_dialog` `iife` `find_msgs` `add_html` `read_msg` `read_msgid` `add_msg` `del_msg` `update_msg` `run_msg` `copy_msg` `paste_msg` `toggle_header` `url2note` `ast_py` `msg_insert_line` `msg_str_replace` `msg_strs_replace` `msg_replace_lines` `msg_del_lines` `load_gist` `gist_file` `is_usable_tool` `import_gist` 
# Fastcore tools
for o in tools.__all__:
    s = getattr(tools, o)
    if is_tool(s): print(f'`{s.__name__}`', end=' ')
`run_cmd` `rg` `sed` `view` `create` `insert` `str_replace` `strs_replace` `replace_lines`