Repository navigation
v0.3.0 (beta)
Pre-releasethunc 0.3.0 lets you watch a program's calls and agent runs live. thunc watch app.py runs your program with a dashboard in the terminal: the calls waiting on a model, retries and why each reply was rejected, timings for each function, each agent's steps as they happen, and the --profile report when the program ends. A program needs nothing added to be watched.
It also brings an experiment, thunc write: a function declared with @thunc.function(write=True) writes its own body into your file on its first call, and runs as plain Python from then on. A program that uses neither behaves exactly as in 0.2.3.
pip install --upgrade "thunc[watch]"thunc watch support_inbox.py --limit 20 # a script and its arguments, as with thunc run
thunc watch -m myapp.triage # a module
thunc watch -- uv run app.py # any command
thunc watch --agents # agent runs in ./.thunc_agents, from any process
thunc watch --plain app.py # one line per event, for CI logs and pipes thunc watch support_inbox.py claude-code/sonnet 00:18.0 ● running
1 Overview 2 Agents 3 Calls 4 Summary
────────────────────────────────────────────────────────────────────────────────────────────
IN FLIGHT 4 running
⠙ draft_reply ticket="Password reset email never… attempt 1 4.2s ████████████
⠙ urgency ticket="Refund still not showing a… attempt 2 4.1s ██████████░░
FUNCTION CALLS CACHED RETRIES FAILED MEAN P95 MODEL RECENT
category 8 0 0 0 1.5s 2.5s 11.7s ▃▄▅█▆▇▃▄
urgency 7 0 1 0 2.4s 4.7s 16.9s ▂▄▄▆▃█▅
AGENTS 0 running
✓ repo-guide tests_for(feature="caching") finished · 6 steps 12.4s
EVENTS
17:38:13 ✓ find_order → Order(id='A-1043') 1.8s
17:38:15 ↻ urgency attempt 1: not valid JSON: 'high' 2.8s
The dashboard (#59)
- Five screens: Overview (calls in flight, a table per function, running agents, results per second, recent events), Agents (each run's steps, time split, changed files and denials), Calls (each attempt of a call: the reply and why it was rejected), Summary (the
thunc run --profiletables, opened when the program ends) and Output (what the program printed). - Mouse or keys. Click a row to select it and again to open it, or use
↑↓and⏎.fshows only retries, failures and denials;ppauses the display while the program keeps running;?lists every key. --agents [DIR]follows the agent runs recorded in a folder, from another terminal, a web app or a worker. A run whose process died partway through shows as interrupted.--save-eventsand--replaykeep a run and play it back, which is a good thing to attach to a bug report.--replayalso plays one agent run's session record.--plainprints one line per result, retry and agent step to stderr, then the report. It's what you get when the output isn't a terminal.
How it's packaged
- The dashboard is a Rust binary in its own package, thunc-watch 0.1, with wheels for macOS, Linux (glibc and musl) and Windows.
thunc[watch]installs it, so thunc itself stays pure Python with no dependencies. It's also on yourPATHasthunc-watch. - Without it,
thunc watchsays how to install it.
THUNC_EVENTS
- When
THUNC_EVENTSnames a file, thunc appends one JSON line to it per call start, model reply, call end, agent tool call and agent end;thunc watchsets it for the program it runs. To watch a program started some other way, set it yourself and runthunc watch --events FILE. - Inputs, replies and values are cut to 120-character previews;
--capture(orTHUNC_EVENTS_CAPTURE=1) sends them whole. Like a trace, they can contain personal data. - When it isn't set, nothing is written.
thunc write, experimental (#63, #64)
Experimental. Its behavior, options and the code it writes may change, or it may be removed, in a later release without a deprecation period. It edits your source files, only while you develop; review each change as a diff before you commit it.
@thunc.function(write=True)
def minutes(duration: str) -> int:
"""Convert a duration like '1h 30m', '90 min' or '2 hours' to whole minutes."""
...
minutes("1h 30m") # -> 90, and minutes() is now Python in your filethunc: writing minutes() in durations.py (first call)
thunc: checked against 6 model answers: all agree
thunc: wrote durations.py lines 5-27 in 14s (answer 4s, draft 11s, test calls 9s; side by side). Removed @thunc.function. Review: git diff durations.py
- On the first call, three requests start side by side: the call's answer, a draft of the body from the docstring and signature, and five test calls, each answered by the model on its own. The draft is linted, run on the call and the test calls, and has to match every answer; one that doesn't goes back with the failing calls, up to three drafts.
- A passing draft goes into the file in place of
..., the decorator is removed, the checked calls become doctest examples, and the call runs the new code. - When it isn't written, because the task needs judgment or no draft passed, the call returns the model's answer and the file is untouched. The reason is kept in
.thunc_write/until the docstring or signature changes. - It's refused, with a warning, in CI or with
THUNC_WRITE=0(set it in production), outside your project, and for read-only, installed or changed files and nested functions. thunc write FILE::FUNCTION [--dry-run]writes one ahead of its first call, or shows the diff.
Tested
- Offline tests run on Python 3.10–3.14 on Ubuntu, and on Windows, including the events and the
thunc watchcommand. CI runs the dashboard'scargo fmt,clippyand tests on Linux, macOS and Windows, and on Linux builds the PyPI wheel and runsthunc watchfrom it. - thunc write: 45 offline tests of the source editing and the writing, end to end against a scripted model, including CRLF files; live,
live_tests/test_writing.pyon Codex wrote a function whose doctests pass. watch/demo/demo_app.pyruns the support-inbox functions and an agent against a scripted backend, with delays and bad replies, and makes no model calls.
Behavior changes
- None.
thunc watch,THUNC_EVENTSandwrite=are new; nothing is written unlessTHUNC_EVENTSis set, and no file is edited unless a function haswrite=True. Nothing is removed.
Known issues: the dashboard only watches: it can't stop a single agent run or approve ask: actions yet. --agents sees one folder, not every project on the machine. On Windows, Ctrl+C and quitting end the program at once, without the KeyboardInterrupt it gets on macOS and Linux. thunc write's checks are only as good as the model's answers, so review the code it writes; thunc write can't write methods ahead of their first call, and it doesn't run on jev. The full list is in CONTRIBUTING.md, and every change is in CHANGELOG.md.
Full changelog: v0.2.3...v0.3.0