Skip to content

Instantly share code, notes, and snippets.

@jph00
Last active January 21, 2026 00:31
Show Gist options
  • Select an option

  • Save jph00/9e7b444aba5ecf6d14295ba2cee890c3 to your computer and use it in GitHub Desktop.

Select an option

Save jph00/9e7b444aba5ecf6d14295ba2cee890c3 to your computer and use it in GitHub Desktop.
Solveit reference

Solveit Reference

What is Solveit?

Solveit is a "Dialog Engineering" web application for interactive development. Unlike ChatGPT (pure chat) or Jupyter (pure code), Solveit combines three message types in one workspace: code execution, markdown notes, and AI prompts. Users build solutions incrementally—writing a few lines, understanding them, then continuing—rather than generating large code blocks.

The AI sees the full dialog context (code, outputs, notes, prompts) when responding -- but only those ABOVE the current message. Users can edit any message at any time, including AI responses—the dialog is a living document, not an append-only log.

The dialog is a running ipykernel instance. A "dialog" is like a "Jupyter notebook", and uses a compatible ipynb file format, but provides a superset of functionality (in particular, "prompt messages"). A "message" is like a "Jupyter cell", with additional attributes stored as ipynb cell metadata. Most standard jupyter functionality is supported (including cell magics like %%js, %%html, %%bash, and custom magics via @line_magic/@cell_magic decorators), except for ipywidgets.

Architecture

  • Instance: A persistent Linux container (virtual private server) with home dir at /app/data. Each user can have multiple instances. Instances have private URLs (for the solveit interface) and public URLs (for hosting apps on port 8000).
  • Dialog: An .ipynb file containing messages. Each open dialog runs its own Python kernel (ipykernel). Dialogs can be organized into folders.
  • Kernel: A running Python 3.12 interpreter maintaining state. Variables persist between code messages. Each dialog has its own isolated kernel. Kernels keep running when navigating away; must explicitly stop via UI or shutdown. Use %load_ext autoreload and %autoreload 2 to auto-reload modules when files change.

CRAFT and TEMPLATE Files

CRAFT.ipynb files provide reusable AI context and auto-executed code for a folder:

  • Note/prompt messages are prepended to the AI's context for all dialogs in that folder and subfolders
  • Code messages are automatically executed in the kernel when opening a dialog

TEMPLATE.ipynb files serve as dialog templates—their cells are prepended to new dialogs created in that folder.

Both use path hierarchy: files from parent folders are included too, letting you build layered configurations (e.g., org-wide settings in root, project-specific in subfolders).

Message Types

Type Purpose Input Output
code Python execution Python source ipynb-format output list (stream, execute_result, display_data, error)
note Documentation Markdown with optional attachments None
prompt AI interaction User question/instruction AI response (markdown string)
raw Frontmatter/metadata Raw text (no processing, no variable injection) None

Output Editing

  • Prompt outputs: Editable via n key or clicking title bar. Can undo AI responses with Cmd+Z.
  • Code outputs: NOT directly editable. Clear with Backspace, or re-run message.

AI Context System

When a user sends a prompt, solveit builds context for the AI:

  1. Message Collection: Gather all messages up to and including the current prompt
  2. Filtering: Exclude messages where skipped=True (hidden via h key or 👁️ button). Hiding propagates to children when applied to a collapsed section.
  3. Truncation: If total tokens exceed model limit, oldest non-pinned messages are dropped
  4. History: Messages grouped into chunks by prompt boundaries and LLM history recreated

Pinning (p key)

Pinned messages serve three purposes:

  • Context preservation: Pinned messages stay available even when long dialogs get truncated
  • Export control: Pinned messages are excluded from exports (Python files, gists, published dialogs)
  • Bulk management: Pinning a collapsed header pins all child messages too

Use for API docs, examples, and reference materials that should persist but not be exported.

Context Window Implications: The AI only sees messages ABOVE the current prompt. Working at the bottom of a dialog includes MORE context (all messages above). Working higher up includes LESS context. Adding messages earlier in the dialog doesn't increase context for prompts below them.

Variable and Expression Injection

Users can inject Python values into AI context using $name syntax in prompts. This works with:

  • Variables: $myvar`` — injects the current value
  • Expressions: $len(items)**, $df.shape, $random()` — evaluated fresh each prompt

When the AI sees the prompt, values are fetched from the kernel and included in a separate section of the chat history. Expressions are re-evaluated on every prompt, so $random()`** gives a new value each time.

Images stored in variables (as bytes) are also supported and sent as base64, as are message image attachments if referred to in the content in a link with a #ai hash.

Tools System

Tools let the AI call Python functions to accomplish tasks. This is the mechanism for AI to read files, search code, modify the dialog, etc.

Exposing Tools

Users declare tools in any message using & followed by function_name or followed by [func1, func2, func3]. Solveit then:

  1. Finds the function in the kernel's namespace
  2. Extracts the schema from type annotations and docstring
  3. Sends the schema to the AI via standard tool calling mechanisms
  4. When AI calls the tool, solveit executes function_name(**kwargs) in the kernel
  5. Returns the result to the AI

Tool Requirements

A function becomes a valid tool if it has:

  • Type annotations for ALL parameters
  • A docstring describing what it does
  • Fastcore param docments are passed in the json schema if present
def get_user(user_id: int) -> dict:
    "Fetch user data by ID."
    return {"id": user_id, "name": "Alice"}

Built-in Tools (dialoghelper.stdtools)

When use_tools setting is enabled (🔧 wrench icon), tools from dialoghelper.stdtools are added. This includes:

  • File tools: view, create, insert, str_replace, strs_replace, replace_lines
  • Search tools: rg, sed, ast_grep
  • Dialog tools: add_msg, update_msg, find_msgs, read_msg, read_msgid
  • Inspection tools: symsrc, getval, getdir, gettype, symlen, symslice, symsearch
  • Web tools: read_url, web_search

dialoghelper Module

The dialoghelper module provides functions for programmatic dialog manipulation:

  • add_msg(content, msg_type='note') - Add message below current
  • update_msg(idx, content, msg_type=None) - Update existing message
  • del_msg(idx) - Delete message
  • find_msgs(pattern) - Search messages by content
  • read_msg() - Read message at index
  • url2note(url) - Fetch URL and add as markdown note
  • tool_info() - Show available tools in a note for AI

Tool Choice Modes

  • use_tools=True + use_fence=False: AI can call tools directly (tool_choice=auto)
  • use_tools=True + use_fence=True: AI writes fenced code blocks instead; only read_url available as direct tool (tool_choice=read_url for Claude, none for Gemini)

Tool Result Handling

Tool results are truncated if too long, to 2000 chars. The ToolResponse class can wrap results with metadata.

File System

  • datapath: /app/data (production) or current working directory (local/test)
  • Dialogs stored at: {datapath}/some/folders/{dialog_name}.ipynb
  • Static files served at: /static/some/folders/ → maps to {datapath}/some/folders/
  • Per-dialog Python modules: {datapath}/some/folders/{dialog_name}.py (auto-generated from exported messages)

Dialog Persistence

Dialogs are saved as Jupyter notebooks (.ipynb). Solveit converts messages to notebook cells when saving:

  • note/prompt → markdown cells
    • Prompt responses stored by appending to message content with separator
  • code/raw → code/raw cells
  • Metadata stored in cell metadata (skipped, pinned, collapsed states, etc.)

Keyboard Shortcuts (Selection Mode)

When not editing (blue border shows selected message):

  • ↑/↓ or j/k: Navigate messages
  • a/b: Add message above/below
  • x/c/v: Cut/copy/paste messages (c also copies to system clipboard as markdown)
  • ,: Copy message input to clipboard
  • .: Copy message output to clipboard
  • h: Toggle hidden from AI (skipped)
  • p: Toggle pinned
  • e: Toggle export
  • 1-6: Set heading level (converts to ## Heading etc.)
  • Enter: Edit selected message
  • Cmd+Enter: Run code or send prompt (stay on message)
  • Shift+Enter: Run and go to next message
  • Opt+Enter: Run and create new message
  • Shift+R: Restart kernel
  • Shift+T: Open terminal
  • Shift+S: Stop AI/code execution
  • Shift+A/B: Run all code above/below (skips prompts)
  • Cmd+Slash: Toggle comments on code messages
  • w: Extract fenced code blocks to new code messages
  • n: Edit AI response (output) of prompt message
  • Cmd+Shift+J/K/L/;: Switch to code/note/prompt/raw mode
  • ←/→: Collapse/expand section (based on markdown headers)
  • r: Re-run all code messages in dialog (skips prompts)
  • m: Copy code blocks from AI response
  • d: Duplicate dialog (opens duplicate with bomb icon 💣 to discard)
  • s: Save dialog (commits to git if versioning enabled)
  • 0: Jump to last edited message
  • /: Focus bottom editor/input field
  • Shift+Esc: Focus back on message list
  • Home/End: Jump to first/last message
  • Cmd+A: Select all messages
  • F: Open find/search modal (Shift+F to clear filters)
  • Backspace: Clear outputs from selected message(s)
  • i/o: Toggle collapse on message input/output
  • Shift+O: Clamp output height

Editor Shortcuts

When editing a message:

  • Shift+Tab: Show parameter info/documentation
  • Cmd+I: Manually trigger symbol dropdown
  • Ctrl+Shift+Minus: Split message at cursor
  • Cmd+Shift+Comma: Screenshot last output into context
  • Cmd+Shift+Period: Super completion (prefill in prompts) or super edit (with selection)
  • Cmd+Shift+S: Save file (in full-page editor view)
  • ESC: Save changes and exit edit mode
  • (Right Arrow): Accept ghost text suggestion
  • Tab: Select from symbol dropdown

AI Modes

Set per-dialog, affects AI behavior:

Mode Behavior Ghost Text
learning Pedagogical, asks clarifying questions, explains step-by-step Disabled by default
concise Minimal responses, compact code, no boilerplate Enabled
standard Default Claude behavior, verbose explanations Enabled

Ghost Text / Completions

Ghost Text

Inline AI suggestions as you type (faded gray text). Uses smaller/faster FIM model. Press to accept.

Super Completions (Cmd+Shift+.)

Uses main model for larger completions. Can prefill AI response start in prompt messages.

Super Edits

Select text + Cmd+Shift+. + instruction → AI rewrites selection. Uses edit_call() with GPT-4.1.

Export System

Message Export

Press e on code message to mark is_exported=True. Adds #| export marker. When dialog is saved, exported messages are combined into {dialog_name}.py.

Publish

See "Publishing and Sharing" section for full details. Creates shareable view at share.solve.it.com. Pinned messages excluded.

Download Options

  • .ipynb: Full notebook
  • .py (Full Script): All code messages concatenated
  • .py (Exported): Only is_exported=True messages
  • .md: Markdown format
  • GitHub Gist: Upload to gist

FastHTML Integration

Solveit is built with FastHTML. Users can also build FastHTML apps inside dialogs:

from fasthtml.common import *
from fasthtml.jupyter import JupyUvi

app = FastHTML()
rt = app.route

@rt
def index(): return H1("Hello")

srv = JupyUvi(app)  # Serves on port 8000 → accessible at public URL

JupyUvi runs uvicorn in a way compatible with notebook contexts. Changes to routes take effect immediately without restart.

Note: The root route / is used by Solveit itself. Use different routes like @rt def homepage() for your app's entry point.

Rendering Components

  • render_ft() - Render FastHTML components as HTML in message outputs
  • show() - Alternative with optional iframe wrapping and HTMX processing

Feature Flags (Secrets)

Stored in solveit_settings.json under secrets key. Accessed via get_secret(name).

Flag Values Effect
USE_KATEX 1/true Enable LaTeX with safe delimiters ($$, \[, \()
USE_KATEX dollar Also enable $...$ inline math
USE_VIM any truthy Vim keybindings in editor

Image Handling

Pasted Images

Paste into note/prompt → stored as message attachment → visible to AI automatically.

If the clipboard contains both an image AND HTML (e.g., from a DOM screenshot tool), solveit automatically appends the HTML in a fenced code block after the image link—useful for sharing UI screenshots with their underlying markup.

Attachments are stored in notebook message metadata (standard Jupyter format), referenced as ![name](attachment:uuid). Attachments are message-specific—cannot be referenced from other messages.

Markdown Images

  • ![alt](path) in notes → displays but NOT sent to AI
  • ![alt](path#ai) → displays AND sent to AI
  • For reusable images, save to /app/data/ and use /static/ URLs

Code Output Images

Images in code output (matplotlib, PIL) are captured and can be sent to AI.

Static Images

Use /static/ URLs to reference files in /app/data/. Example: Img(src='/static/myapp/image.png') for FastHTML, or ![alt](/static/image.png) in markdown.

Collapsible Sections

Markdown headings (# H1 through ###### H6) create collapsible sections:

  • heading_collapsed=True on heading message → children have hidden=True
  • Token count shows: heading_tokens + hidden_content_tokens
  • Cut/copy on collapsed heading includes all children
  • jumps to section start, to section end

Token Counting

Token counts estimated and used for:

  • Display in UI (message headers show token counts)
  • Context truncation decisions
  • Image tokens calculated separately

Error Handling

  • Errors trigger msg.uncollapse() to show the problematic message

Settings

Stored in {datapath}/solveit_settings.json. Common settings:

  • use_tools: Enable standard tools (🔧 wrench icon in navbar)
  • use_fence: Use fenced code mode (AI writes code blocks instead of tool calls)
  • use_thinking: Enable extended thinking mode (🧠 brain icon in navbar, or Cmd+Shift+D)
  • default_code: After AI response, default to code mode (not prompt)

Feature Flags (Secrets)

Stored in solveit_settings.json under secrets key. Accessed via get_secret(name).

Flag Values Effect
USE_KATEX 1/true Enable LaTeX with safe delimiters ($$, \[, \()
USE_KATEX dollar Also enable $...$ inline math
USE_VIM any truthy Vim keybindings in editor

UI Controls

Header Bar

From left to right:

Left section:

Element Description
📚 solveit Logo/home link - closes dialog, returns to dialog list
🟢 Green dot WebSocket connection indicator
Dialog name Editable - click to rename dialog

Mode dropdown:

Element Description
learning/standard/concise AI mode selector - affects response style and ghost text

Toggle group (blue when active):

Icon Tooltip Setting Shortcut
<> "Default new message type to code?" default_code
🔧 "Include dialoghelper standard tools in prompts?" use_tools
🧠 "Use reasoning model" use_thinking Cmd+Shift+D
Fence "Use fenced blocks instead of tools?" use_fence

Action buttons:

Icon Tooltip Action Shortcut
? "Keyboard Shortcuts" Open info modal ?
Git "Checkpoint" Create git checkpoint Shift+C
Share "Share your dialog" Publish to share.solve.it.com
Cloud ↑ "Upload File" Open upload modal
"Stop" Stop AI/code execution Shift+S
"Run all" Run all code messages r
"Restart" Restart Python kernel Shift+R
"Settings" Open settings modal
Copy+ "Duplicate Dialog" Duplicate and open d
💣 "DELETE and close" Delete duplicate (hidden until duplicated)
Terminal "Open Terminal" Open terminal in new tab Shift+T
TOC "Contents" Toggle sidebar Ctrl+Shift+V
"Dialogs" Open dialog list in new tab

Message Bar

Each message has a header bar for input (and optionally output). Click the header text to edit.

Left side:

Element Description
Message type Code, Note, Prompt, or Raw
Token count Estimated tokens for this message

Button bar (left to right):

Icon Tooltip Shortcut Action
📋 "Copy" , Copy message to clipboard
"Run Message" Cmd+Enter Execute code or send prompt (code/prompt only)
👁 "Toggle AI visibility" h Hide/show message from AI context
🔖 "Toggle message export" e Mark for export to .py file
🗑 "Delete Message" Shift+D Delete this message
↑⚡ "Delete above" Delete all messages above (confirms)
↓⚡ "Delete below" Delete all messages below (confirms)
"Run Above" Shift+A Run all code messages above
"Run Below" Shift+B Run all code messages below
"Add Above" a Insert new message above
"Add Below" b Insert new message below
📖↑ "Shift up" Move message up
📖↓ "Shift down" Move message down
💬+ "Add copy of message" q Duplicate this message
🔀 "Merge with message below" Shift+M Combine with next message
✂️ "Split note based on headings" Ctrl+Shift+Minus Split into multiple messages
📌 "Toggle message pin" p Pin/unpin message
🔗 "Copy link to message" Copy URL with message anchor
"Collapse contents" i Collapse/expand input
"Open in new tab" t View message in standalone tab

Message Output Bar

Only code and prompt messages have outputs. Click the header text to edit (prompt outputs only—code outputs are not editable).

Left side:

Element Description
Label Output (code) or Assistant (prompt)
Token count Estimated tokens for this output

Button bar (left to right):

Icon Tooltip Shortcut Action
📋 "Copy" . Copy output to clipboard
📋 "Copy code" m Copy fenced code blocks to clipboard
💬+ "Add fenced block messages" w Extract fenced blocks to new code messages
"Re-run AI" Re-send prompt to AI (prompt outputs only)
"Collapse contents" o Collapse/expand output
"Open in new tab" t View output in standalone tab

Terminal

Press Shift+T to open an integrated terminal in the current dialog's folder. Useful for:

  • File operations (ls, mv, rm, etc.)
  • Git commands
  • Package installation (pip install)
  • Running shell scripts

Find/Search

Press F to open find modal (selection mode, not editing). Features:

  • Regex search across message content and outputs
  • Filter by message type (colored buttons match UI colors)
  • Filter by whether changed in git diff
  • Searches inside collapsed sections (auto-expands on match)
  • Shift+F clears all filters

Dialog Duplication and Branching

Press d to duplicate current dialog. The duplicate opens immediately, with a bomb icon (💣) added to the navbar. This supports a "branching" workflow:

  • Duplicate before experimenting with risky changes
  • If the branch is useful, keep it
  • If not, click the bomb icon to delete and return to the original

Git/Versioning System

Solveit integrates git for version control at the folder level.

Enabling Versioning

Click "Enable versioning" button in any folder to initialize a git repo there. Can create nested repos (repo-in-repo) at any directory level.

Saving and Committing

  • Press s to save the dialog and auto-commit with Solveit's distinctive message template
  • Dialogs auto-save on most actions (submit, cancel edit, etc.) but do not commit without s or checkpoint

Checkpoints

Click "checkpoint" button (appears after versioning enabled) to create a manual commit with a custom message. Useful for marking significant milestones.

Squashing

Solveit automatically squashes commits that match its auto-save message template. This keeps history clean—many small saves become one commit, while checkpoint commits with custom messages are preserved.

Publish Button

Creates a read-only shareable view at https://share.solve.it.com/d/[hash]. Pinned messages are excluded from published output.

URL suffixes:

  • .html - Blog-style rendered view
  • .md - Raw markdown

Dialog index page

The dialog index page lists dialogs and folders in the current folder, along with clickable breadcrumb path.

Click "show all files" to also show non ipynb files, which can be opened in the file editor. By each file or folder are buttons to duplicate or delete it.

Other features of this page:

  • Secrets management (API keys stored as environment variables)
  • Running dialogs (can shut down here)
  • Upload files/folders (zip and unzip for folders)

Keyboard Shortcuts

Key Action
↑/↓ Navigate rows
Enter Open dialog/folder
N Focus "new dialog" input
T Open terminal
D Delete selected
C Duplicate selected

Secrets

Add name-value pairs in Secrets section. Common secrets:

  • ANTHROPIC_API_KEY, OPENAI_API_KEY - LLM API access
  • AOC_SESSION - Advent of Code session cookie
  • USE_KATEX, USE_VIM - Feature flags (see Feature Flags section)

Secrets load when opening a dialog or terminal; add secret then open new dialog to use it.

Show All Files

Toggle in dialog list view to see all files, not just .ipynb dialogs. Enables:

  • Click text files to open in Monaco editor (VS Code-based)
  • Download files via three-dot menu

Folder Operations

  • Create folders: mkdir in terminal, or create dialog with path like newfolder/dialogname
  • Move dialogs to folders: Rename dialog to include folder path (e.g., myfolder/mydialog)

Dashboard

The dashboard at solve.it.com/dashboard provides:

  • Instance management (start/stop/restart; rename public instance and get URL; share; allow guests)
  • Live session times for courses
  • Version updates (stop → wait → start to upgrade)

Instance Sharing (Dashboard)

  • Copy Public URL: Get URL for apps running on port 8000 (one URL per instance, all dialogs share it)
  • Share button: Add collaborators by email (requires Solveit account)
  • Lock icon (Allow Guests): Enable public access to entire instance without authentication

Raw Message Type

Raw messages (Cmd+Shift+;) are for content that shouldn't be processed:

  • Large documents as AI context (no sidebar headings, no variable injection)
  • Quarto/YAML frontmatter
  • Content with special characters that might interfere with markdown

Access any message content programmatically in dialoghelper: read_msg()['msg']['content'] from code message below it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment