The AI's Tools¶
When a model works on your project, it does not just write code. It calls tools: reading a file, searching the project, editing one function, running the app, looking at its window, looking something up on the web. Each call appears as a short line in the chat while it works. This page lists every tool, what it does, and when it is offered.
Changed in v2.6.0: every backend is offered the same tools. Which ones a model gets depends on its capability record and your settings, never on who sells the model.
Reading outside the project¶
New in v2.6.0. The model can read files outside the open project when you name them, for
example "check how we did controller support in C:\Users\you.whittl\projects\Brick Breaker".
read_code, list_files(path) and search_code take an absolute path. The first read in a
folder asks you in the chat; Allow covers that folder for the rest of the session (another
Whittl project is asked about as a whole). What the model reads is sent to its provider.
- It never writes outside the project: the editing tools refuse any path outside it.
- Some files are never read, allowed folder or not: SSH and cloud keys, credential and
.envfiles, key and certificate files, browser profiles, and Whittl's own settings and logs. - A question that names an outside folder gets the read-only tools, so the model can look around before it answers.
The full list¶
| Tool | What it does | Offered |
|---|---|---|
list_files(path) |
The project's file tree with line counts. Skips build output, archives and virtual environments. With path, a folder outside the project instead (see below). |
Always |
glob(pattern) |
Find files by name pattern, for example ui/**/*.py. |
Always |
search_code(pattern, file) |
Grep-style search across the project, or one file or folder outside it. | Always |
read_code(file, target) |
Read a whole file, a named function or class, or a line range (offset / limit, the same shape Claude Code uses). The file can be outside the project. |
Always |
edit_code(file, old_text, new_text) |
Replace an exact text span. The workhorse for small changes. | Not on a review |
edit_function(file, function_name, replacement_body) |
Replace one function, found by parsing the file rather than matching text. Keeps the indentation right. | Not on a review |
multi_edit(file, edits) |
Several exact replacements in one file in one call. | Not on a review |
create_file(path, content) |
Add a new file to the project. It streams into the editor as it is written. | Not on a review |
delete_file(path) |
Remove a file, so a refactor can retire what it replaced instead of leaving it to be imported by mistake. | Not on a review |
syntax_check(file) |
Compile a file and report the first syntax error. Cheap; the model is told to use it after edits. | Always |
run_code |
Run the project the way Test Run does and return the output and any traceback. | Always |
probe_app(actions) |
Build the app offscreen and report every widget: class, name, text, size, position, visibility, and anything with no size or outside the window. Can click a button or type into a field first. Its picture of the window is shown in the chat. PySide6 projects. | Always |
run_script(source) |
Run a short Python script against the whittl API (read, search, edit, write, run, tests) in a separate process, so one call can do what a dozen rounds would. A script that fails leaves the project unchanged. With Agent Mode on, the script may use all of Python and the project's own modules. |
Always (unless code mode is switched off) |
load_skill(name) |
Pull the full text of a skill listed in the skill index. | Whenever such skills exist |
question(question, options) |
Ask you a structured question mid-task instead of guessing; you answer by clicking. Three per task. | Outside Agent Mode, not during an auto-fix |
bash(command) |
Run a shell command in the project folder, with a deny-list, a time limit and capped output. See Agent Mode. | Agent Mode |
web_search(query) |
Search the web. | Agent Mode |
web_fetch(url) |
Fetch a URL. A web page comes back as text with its HTML stripped; a raw file (an SVG, a JSON file, a Python module) comes back exactly as it is. It saves nothing. | Agent Mode |
download_file(url, path) |
Save a file from the web into the project: an icon, an image, a font, a sound, a data file. The bytes go to disk, never through the conversation; a text file joins the project like one the model wrote, and an image under assets shows up in the Assets tab. Refuses anything the operating system would run, a file over 25 MB, the data folder, and overwriting a source file. Downloads have their own budget. |
Agent Mode, not on a review |
| your plugins | An enabled plugin tool appears under its own name, and the model calls it like any of these. | When enabled, not on a review |
On Claude, Anthropic's own file editor takes the place of edit_code, alongside the rest.
On a review (a message that asks for no changes, such as "review the code, do not change anything"), the editing tools, download_file and plugin tools are not offered, and any call to one is refused. The model can still read, search and run.
A small model (a window under 64K tokens, or a low tier) is offered a core set of about ten tools: read_code, search_code, edit_code, create_file, syntax_check, run_code, run_script, probe_app, question and load_skill. A long tool list crowds out the code on a small window.
You do not have to give the model an address to download from. "Replace the toolbar icons with the Phosphor ones, grab them online" is enough: when you name a source without an address, the model looks it up, confirms the real path and downloads from it. If it cannot find what you asked for, it says so and names the address that failed. It does not quietly draw a replacement of its own.
Three kinds of loop¶
Which loop a model gets is decided by its capability record, not by its backend.
Multi-turn. The model gets the tools above and works agentically: read, search, edit, check, run, look at the window, repeat. Any model whose record says it calls tools natively and reliably uses this loop. The round cap comes from the tier: 10, or with Agent Mode on, 20 for tier-A and 50 for tier-S.
Code mode. A model that cannot call tools reliably writes a short script against the whittl API instead, and Whittl runs it. The same loop in a different shape; see code mode.
Single-turn. The capped fallback: the relevant code is put in the message up front, and only edit_code, edit_function, create_file, syntax_check, question and load_skill are offered. Used when a model has no tool calling at all and code mode is off.
Large projects: index-only context¶
Putting a whole project in every round is fine at ten files and ruinous at sixty. Above a size that scales with the model's window, Whittl sends an index instead: every file the project holds, Python first, with line counts, and the model reads what it needs with read_code and search_code. You will see this in the log:
The same applies to auto-fix. On one field project this took a fix round from 364,000 input tokens to about 15,000, and made a model with a 200K window able to attempt the fix at all.
Reading the chat¶
Each call shows as the call and one indented line saying what came back:
→ Reading canvas.py
348 lines
→ Editing CanvasWidget.auto_detect_all_objects() in canvas.py
Edit applied to canvas.py.
→ Looking at the app
5 widgets, 2 worth knowing about, clicked 'Next'
→ Editing align_panel.py (failed: old_text not found ...)
The full result goes to the model, never to the chat. A failed edit is not an error in Whittl: the model's old_text did not match the file exactly, usually because the file changed since it last read it. The loop tells it so, with the closest matching lines, and it reads again and retries.
What the tools cannot do¶
- Leave the project. Every path is checked against the project folder;
../and absolute paths are refused. - Touch
data/. Runtime and user data underdata/is never written by a tool. - Download into the wrong place. A download never lands outside the project, in
data/, or over a file you or the model wrote, and files the operating system would run are refused. - Substitute an asset. A file you asked Whittl to fetch is either the real file or an honest "I could not find it".
Those guarantees cover Whittl's own tools. A plugin is code you chose to enable: a plugin tool runs in its own process, so it cannot freeze or crash Whittl, and it cannot replace a built-in tool, but it is not sandboxed and the path rules above do not apply to it. Read a plugin before you enable it. The same goes for bash: its deny-list stops the obvious mistakes, but the shell runs with your access.
What's next¶
- The Agent Loop: the capability record, code mode, seeing the app
- Agent Mode: round caps, the
bashtool, the web tools - Web Research: the web tools in detail
- Skills System: skills and
load_skill - Plugins: adding tools of your own