Skip to content

Instantly share code, notes, and snippets.

@fredguth
Created November 20, 2025 15:59
Show Gist options
  • Select an option

  • Save fredguth/a86aff093fc1b664c253494f1ff559e0 to your computer and use it in GitHub Desktop.

Select an option

Save fredguth/a86aff093fc1b664c253494f1ff559e0 to your computer and use it in GitHub Desktop.
solveish_v3
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from fastcore.utils import *\n",
"from fasthtml.common import *\n",
"from fasthtml.jupyter import *\n",
"import fasthtml.components as fc\n",
"from toolslm.shell import get_shell\n",
"from lisette import *\n",
"import random"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Setup\n",
"daisy_hdrs = (\n",
" Link(href='https://cdn.jsdelivr.net/npm/daisyui@5', rel='stylesheet', type='text/css'),\n",
" Script(src='https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4'),\n",
" Link(href='https://cdn.jsdelivr.net/npm/daisyui@5/themes.css', rel='stylesheet', type='text/css')\n",
")\n",
"app = FastHTML(hdrs=daisy_hdrs, session_cookie='mysessioncookie')\n",
"rt = app.route\n",
"preview = partial(HTMX, app=app, host=None, port=None)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Component wrappers\n",
"def mk_comp(name, compcls):\n",
" comp = getattr(fc, name)\n",
" def wrapper(*args, cls='', **kwargs): return comp(*args, cls=f'{compcls} {cls}', **kwargs)\n",
" globals()[name] = wrapper\n",
"mk_comp('Button', 'btn')\n",
"mk_comp('Input', 'input')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check if string is valid Python code\n",
"def is_code(code):\n",
" try:\n",
" compile(code, '<string>', 'eval')\n",
" return True\n",
" except SyntaxError:\n",
" try:\n",
" compile(code, '<string>', 'exec')\n",
" return True\n",
" except SyntaxError: return False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Execute code in shell\n",
"def ex(s, sh):\n",
" res = sh.run_cell(s)\n",
" return res.result if res.result else res.stdout"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# LLM setup\n",
"sysp = \"You are a chat model, in a chat with a user that also includes code executions. Given the chat history as context, answer the user's current question concisely.\"\n",
"def cts(r): return r.choices[0].message.content"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Store per-user chats and shells\n",
"user_chats = {}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Render a message as HTML\n",
"def render_message(msg):\n",
" color = 'info' if msg['author'] == 'user' else 'accent' if msg['author'] == 'ai' else 'primary'\n",
" align = 'end' if msg['author'] == 'user' else 'start'\n",
" return Div(Div(msg['content'], cls=f'chat-bubble chat-bubble-{color}'), cls=f'chat chat-{align}') if msg['content'] else \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Process submitted code or question\n",
"@rt\n",
"def proc_code(code:str, session):\n",
" if 'userid' not in session: return\n",
" h, sh = user_chats[session['userid']]\n",
" c = is_code(code)\n",
" if c: res = ex(code, sh)\n",
" else:\n",
" ctx = \"Past context/conversation: \" + \"\\n\".join([str(msg['content']) for msg in h])\n",
" res = cts(Chat(model='claude-haiku-4-5', sp=sysp)(ctx + \"\\n\\nCurrent question: \" + code))\n",
" h += {'content': code, 'author': 'user'}, {'content': res, 'author': 'ai' if not c else 'computer'}\n",
" return (render_message({'content': code, 'author': 'user'}), \n",
" render_message({'content': res, 'author': 'ai' if not c else 'computer'}), \n",
" Input(type='text', placeholder='Enter code...', id='code', hx_swap_oob='true', cls='flex-1'))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Clear chat history\n",
"@rt\n",
"def clear_chat(session):\n",
" if 'userid' not in session: return\n",
" if session['userid'] not in user_chats: return\n",
" user_chats[session['userid']] = ([], get_shell())\n",
" return Div(id='chat', cls='mb-4 border rounded-lg p-4 h-[400px] overflow-y-auto')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Main chat page\n",
"@rt\n",
"def chatdemo(session):\n",
" if 'userid' not in session: session['userid'] = random.randint(0, 1_000_000)\n",
" if session['userid'] not in user_chats:\n",
" user_chats[session['userid']] = ([], get_shell())\n",
" h, _ = user_chats[session['userid']]\n",
" bubs = [render_message(m) for m in h]\n",
" return Div(\n",
" H1('Code Chat', cls='text-3xl font-bold mb-4 text-center'),\n",
" Div(*bubs, id='chat', cls='mb-4 border rounded-lg p-4 h-[400px] overflow-y-auto'),\n",
" Form(hx_post=proc_code, hx_target='#chat', hx_swap='beforeend', cls='flex gap-2')(\n",
" Input(type='text', placeholder='Enter code...', id='code', cls='flex-1'),\n",
" Button('Run', type='submit', cls='btn-primary'), \n",
" Button('Clear', type='button', cls='btn-secondary', hx_post=clear_chat, hx_target='#chat', hx_swap='outerHTML')\n",
" ), cls='p-4', style='max-width:600px'\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Start server\n",
"srv = JupyUvi(app, port=3004)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Preview the app\n",
"preview(chatdemo)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.12.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment