Repository navigation
Let a builder that sees open a picture itself - #1183
Draft
youkaicountry wants to merge 46 commits into
Draft
youkaicountry wants to merge 46 commits into
youkaicountry wants to merge 46 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This was referenced Nov 8, 2026
youkaicountry
force-pushed
the
feature/r5.4-builder-opens-pictures
branch
from
November 9, 2026 03:00
f4283e9 to
b96a3de
Compare
3 tasks done
youkaicountry
force-pushed
the
feature/r5.4-builder-opens-pictures
branch
from
November 9, 2026 23:50
b96a3de to
a7f59e5
Compare
Contributor
Author
youkaicountry
force-pushed
the
feature/r5.4-builder-opens-pictures
branch
2 times, most recently
from
November 10, 2026 05:58
7afee70 to
674f00a
Compare
youkaicountry
force-pushed
the
feature/r5.4-builder-opens-pictures
branch
3 times, most recently
from
November 10, 2026 19:01
54cb26f to
7a4a89a
Compare
Add the plan for local models that can do more than the lean defaults assume: the context window read from the server, an Auto/Lean/Full tool list per AI, honest prompts for builders that can't see pictures, and pictures for models that can. The first line is claimed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A model on this computer or its network was budgeted at 24k tokens whatever it could hold, and the real window was only learned from a refusal, which never came once we trimmed first. Before a backend's first request, and once more after it while the server hasn't said, the agent now asks the server for the window it has loaded: the model list (context_length, max_model_len, meta.n_ctx), llama-swap's upstream route for a loaded model, llama.cpp's /props, LM Studio's loaded_context_length and Ollama's /api/ps. Three quarters of it is a local model's budget; it only lowers a paid service's. Each server is a WindowProbe, so a fork can add one. context_tokens gets a field in Settings -> AI (Auto by default) and `ai context <name> <tokens|auto>` in the CLI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ings The gate skipped every service off this network but OpenRouter, while its comment and the docs said they were asked through their model list. OpenAI-compatible services now are (official OpenAI and Gemini, whose lists say no window, still aren't), and Groq's `context_window` field is read. Adds tests for the hub's set_context_tokens, `ai context` and the Settings field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The llama-swap upstream route and Ollama 0.40.15 were asked live; note Ollama's 4096-token default under the line about setting a server's size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The budget was a bare text box that wrapped away from its label and didn't say what Auto meant. It is now a dropdown on its own line (Auto, 8k to 1M, Custom… for any number, so nothing is capped), and under it a note worked out with the agent loop's own rule from the window the server names: "Auto: 393,216 tokens of the server's 524,288", or "196,608 will be used: the server holds 262,144". `ai context` shows the same window and budget. Strings are in all 13 catalogs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fault The 150k cap for a paid service's Auto budget was applied before the person's own budget was compared with the window, so a 390k budget became 150k. Also escape a pipe that split a STATUS table row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
llama-swap starts a model for a /props?model= request too, so the llama.cpp probe swapped out the loaded model whenever the list gave no window for an unloaded one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Estonian (storytold#1205) merged after this branch was made, and every UI string needs it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ollama and LM Studio name their window only once the model is loaded, and Settings kept the first answer for the whole session. Opening Settings now forgets answers without a window. The roadmap gets the ssh case. Both found by CodeRabbit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paced (from storytold#1469) wraps a backend with requests_per_minute, and it didn't pass context_window on, so a paced backend's Auto budget never saw the window its server names. It forwards it now, as Tunneled does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every builder on a local model got the lean list (storytold#417) and a system prompt without the memory steps, whatever its window, so a model with a 262k or 512k window built with the same cut-down tools as a 4k one. Each API backend now has a tool list: `tools` in [[ai.backends]], Settings → AI "Tools for building", and `ai tools <name>`. Lean is the building list, Full is every tool and the memory steps. Auto, the default, is Full on a paid service, and on a local model Full when the conversation's budget is FULL_TOOLS_BUDGET (49,152: a 64k window less its quarter) or more, else Lean. With no window known a local model stays lean, as before. The loop now asks the server for its window before choosing, and chooses again before each turn, rewriting the system prompt when the list changes (Ollama names its window only once the model is loaded). The choice is journaled as `tools`. Chats keep every tool. Stacked on storytold#1155, which reads the server's window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the large-model half of the live-run item was run; the lean run on a small model gets its own open line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Settings showed "(the lean list until its server says it holds more)" for a local AI on Auto tools with no window yet, even when its saved context budget was below the full list's: that budget stays lean whatever the server says. `ServerWindow::lean_until_told` asks whether a server naming a large window would change the choice, and the note follows it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vision = auto | yes | no on each API backend, and ai vision to show and set it. Auto asks the server: a model list's input modalities, llama-swap's upstream /props for a loaded model, llama.cpp's /props modalities, LM Studio's model type and Ollama's capabilities; a Claude model sees. Nothing said is treated as blind. Carries storytold#1155's guard (asking llama-swap about an unloaded model only through its list), which the sight probe needs too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sees_pictures read the model id as written, so anthropic/claude-… and anthropic.claude-… (gateway ids) said nothing and were treated as blind. It now strips them the way effort_for does, through one helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paced didn't pass sees_pictures on, so under Vision Auto a backend with requests_per_minute was taken as blind, even Claude. It forwards it now, as Tunneled does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds Block::Image: PNG, JPEG, GIF or WebP read from the bytes, up to 3.75 MB. OpenAI-style servers get image_url data URIs in the message's content parts, Anthropic an image block with a base64 source; messages without a picture are sent as before. The bytes stay in memory only: transcripts keep the picture's name and a resumed conversation sends a note instead. Pictures count as 1,600 tokens and old ones are trimmed to their note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
image_file reads one byte past the limit, so the size it read isn't the file's, and dividing it as an integer printed "3 MB, more than the 3.75 MB". Found by CodeRabbit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ticked line now names the "Sees pictures" setting (vision: Auto, Yes or No) and drops the "what's left" sentence; the open line that asked for the setting and the attaching, both now done, goes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A website check lists the start page at every width first; with each picture beside the original's, those filled the six a message carries, so a builder that sees was never shown the site's other pages, however unlike they were, and the first message never read capture/routes/. Pictures are now taken by page in turn (least alike first after a check), an original and the build's picture go together or not at all, and what didn't fit is counted in the feed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Try again" after a check that couldn't run checks first, so its first message is the fix after that check. The original's first-message pictures were queued as well and went with it: the original's screenshot twice, and the build's pictures could be cut off at six. They now go only when a builder turn comes first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… starts Settings and `ai vision` don't open an SSH tunnel just to ask a server something, so for an AI on Auto reached over SSH they said "its server doesn't say: not shown pictures". A build does ask through its own tunnel, and its model may then be shown pictures, so that note could be wrong. Settings now says it's asked when a build starts, and `ai vision` gives `sees` as null with `over_ssh`; a set answer is shown as before. BackendConfig::over_ssh is the one place that says a backend is reached over SSH. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rts ones left out, and that Auto is blind on OpenAI's and Gemini's own APIs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…starts (R5.4) Settings doesn't ask a backend over SSH for its window (a tunnel would be opened just for that), so the Auto budget's note said the server doesn't say how much it holds, and the tool list's said the lean list until it does. Both now say it's asked when a build starts, as the Sees pictures line already does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since storytold#1520 a run studies again when its capture is from the other mode. The test checks in Clean room on a fixture marked Deep, so it studied and the scripted model ran out of turns. The capture is now Clean room's, as the run is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Anthropic refuses a picture longer than 8000 px on either side, and a full-page screenshot can be that tall while its PNG is well under 3.75 MB, so fit passed it unchanged and the builder's request could be refused. fit now reads the picture's size from its header (picture_dimensions, any of the formats we take) and scales one over 8000 px down, keeping its shape, as it does one over the byte limit. One that fits both is left exactly as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
youkaicountry
force-pushed
the
feature/r5.4-builder-opens-pictures
branch
from
November 11, 2026 00:09
7a4a89a to
86b8e94
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked: on #1182 (shrinking large pictures) → #1179 (pictures to builders that see) → #1177 → #1161 → #1155. It reuses #1182's shrinking. Only the last two commits are this PR: the claim and
Let a builder that sees open a picture itself. I'll rebase as those merge.Why
With #1179 an API builder whose model sees is shown the pictures the run attaches: the original's with the first message, and each check's after it. It still couldn't look at anything else.
build_file_readrefused any binary file, so a screenshot it saved of its own build, or a seventh picture inreference/, was out of reach.What changes
Engine (
build_file_read).{path, picture, media_type, bytes, note}. Herepictureis the path as shown in the project.web_common::picture_media_type, andmodel::image_media_typecalls it, so there's one copy.Agent loop.
LoopConfig::projectsays which folder the build tools' paths are relative to.picturefield (a typed field, not a tool name) marks the picture as opened.pictures::load, so a big one is shrunk and named with its scale. A step shows at most six, and the rest are named so the model can open them next.Run.
AiHub::start_buildertakes the project folder (its only caller is the run). The sighted builder's note now says it can open other pictures withbuild_file_read.Tests
build_file_readon a PNG (by a root-style path,/app/shot.png) answers withpicture: "app/shot.png",media_type: "image/png"and no text, and other binary files are still refused.a_picture_a_tool_opens_is_shown_after_its_result_to_a_model_that_sees. One step opens a picture, a missing picture and a non-picture result. A sighted model gets the three results, thenPicture: app/shot.pngand the image, then the missing one named as not shown. A blind model gets no image and the note. With the agent no longer noting opened pictures, it fails.cargo xtask toolsleavesdocs/tools.mdas it was.Not tested: the run giving the builder its project folder is one line that no test covers (run tests pass in their own conversation). It hasn't been run live yet.
🤖 Generated with Claude Code