Repository navigation
Jev Images
This page gives the results of ten live calls, each with one image.
Seven calls answered, and three were rejected with HTTP 400.
The calls ran on 2026-10-20 against the TypeSafe API.
They are the evidence of task 6.1 of the openspec change jev-images.
It is for a maintainer who checks the --image flag and the verb box of the decide slice.
- The
yescall answeredP(yes) = 0.99. The request namedjev-latest, and the reply namedjev-1.13.0. - The reply of the first
boxcall put the box within 0.01 of the true box on each edge. The request and the reply both namedjev-1.14.0. - The reply of the
boxcall has a nested shape. The CLI of this commit expected a flat shape, so it rejected the reply, and the verbboxprinted no box. The fix is commit38d39b78. - After the fix, a second
boxcall printed the same box, with a pixel suffix. - The shipped command,
plugins/claudetto/bin/claudetto-decide, ran end to end with exit code0and printed a box. - Three calls on a browser screenshot of 1554 by 2000 pixels got HTTP
400, with the messageInvalid image dimensions.The height of 2000 pixels is over the 1568-pixel bound in the docs. See the section on the pixel bound below. Since commitc411962e, the CLI stops such a file with exit code2, before the request. - The same screenshot, scaled to 1218 by 1568 pixels, got HTTP
200for each of the three calls. Eachboxedge was within about0.025of a reference box read by eye. - The seven answered calls used about
20277input tokens, about$0.00085at the price in design D3. The input tokens of the shipped-command call are counted, not logged.
| Item | Value |
|---|---|
| Date | 2026-10-20. The server date header of the run says Tue, 20 Oct 2026 23:41:01 GMT, and all calls ran within a few minutes of it |
| Claude Code | Not applicable, because the calls ran the CLI code through a wrapper script |
| Code | The shipped CLI in plugins/claudetto/slices/decide/adapters/cli.ts
|
| Check |
just generate --check passed before the run, so plugins/ matched src/
|
| Functions |
parseArgs, buildBody, readImage, imageSize, post, and render
|
| Wrapper | A small script outside the repository. It passed a logging fetchFn to post, to record the model of each request and the full reply |
| Key |
TYPESAFE_API_KEY, read from the git-ignored .env. The key is in no log |
| Commands |
yes --image red.png -- "Does the image show a red rectangle on a white background?" and box --image red.png -- "the red rectangle"
|
The post-fix wrapper call used the same method, the same image, and the same question.
The wrapper runs call post and render directly, and not the launcher.
The shipped-command call in the section below is the only end-to-end run of the shipped command.
Running cli.ts directly does nothing, because only plugins/claudetto/bin/claudetto-decide calls main.
All results on this page are measured on 2026-10-20.
The test image is a PNG of 640 by 480 pixels and 2201 bytes.
A short Python script made it with zlib and struct, and no image library.
It is white, with one solid red rectangle (#dc143c) at x 160..479 and y 48..239.
The true box is top 0.10, bottom 0.50, left 0.25, and right 0.75, in fractions of the height and the width.
| Item | Value |
|---|---|
| Request model | jev-latest |
| Request body | Multipart, with the part request and the part img1
|
| Header | TypeSafe-Danger-Zone-Images: true |
| Asset entry | {"<uuid>":{"type":"image","part":"img1"}} |
| State line | Image img1: <uuid> |
| HTTP |
200, in 287 ms |
| Request ID | req_01a15bb09504746285a7ca8491df480d |
| Input and output tokens |
1143 and 20
|
| CLI output | P(yes) = 0.99 |
The reply, with line breaks added for this page:
{
"model": "jev-1.13.0",
"answers": {
"q": {
"type": "noul",
"noul": 0.99
}
},
"usage": {
"input_tokens": 1143,
"output_tokens": 20
}
}The API accepted the asset entry, with no 400 about assets.
| Item | Value |
|---|---|
| Request model | jev-1.14.0 |
| Request body | Multipart, as in the yes call |
| Header | TypeSafe-Danger-Zone-Images: true |
| HTTP |
200, in 245 ms |
| Request ID | req_01a15bb0962873f4bac94d0dcb5ad848 |
| Input and output tokens |
1134 and 20
|
| CLI output | None, because the CLI rejected the reply |
The reply, with line breaks added for this page:
{
"model": "jev-1.14.0",
"answers": {
"q": {
"type": "box",
"box": {
"top": 0.1,
"bottom": 0.51,
"left": 0.25,
"right": 0.76
},
"confidence": 0.92
}
},
"usage": {
"input_tokens": 1134,
"output_tokens": 20
}
}| Edge | True | Found | Difference |
|---|---|---|---|
| Top | 0.10 |
0.10 |
0.00 |
| Bottom | 0.50 |
0.51 |
0.01 |
| Left | 0.25 |
0.25 |
0.00 |
| Right | 0.75 |
0.76 |
0.01 |
The confidence was 0.92.
The box is within 0.01 of the true box on each edge.
The values come from the logging wrapper, because the CLI rejected the reply.
The post-fix call ran after the fix in commit 38d39b78.
It used jev-1.14.0, and it returned the same box as the first call.
| Item | Value |
|---|---|
| Request model | jev-1.14.0 |
| HTTP | 200 |
| Input and output tokens |
1135 and 20
|
| CLI output | top 0.10, bottom 0.51, left 0.25, right 0.76 (confidence 0.92), px x 160..486 y 48..245 of 640x480 |
The reply, with line breaks added for this page:
{
"model": "jev-1.14.0",
"answers": {
"q": {
"type": "box",
"box": {
"top": 0.1,
"bottom": 0.51,
"left": 0.25,
"right": 0.76
},
"confidence": 0.92
}
},
"usage": {
"input_tokens": 1135,
"output_tokens": 20
}
}The pixel suffix puts the right edge at 486 and the bottom edge at 245.
The true pixel box is x 160..479 and y 48..239.
So the error is at most 7 px on the right edge and 6 px on the bottom edge.
This call ran the shipped command, with the key in the environment only.
| Item | Value |
|---|---|
| Command | plugins/claudetto/bin/claudetto-decide box --image red.png -- "the red rectangle" |
| Exit code |
0, with no pipe after the command |
| Key | In the environment only, and not in the output |
| Input tokens | Not logged, because the command does not print usage. About 1135 is counted |
| CLI output | top 0.10, bottom 0.52, left 0.25, right 0.75 (confidence 0.93), px x 160..480 y 48..250 of 640x480 |
The pixel suffix puts the bottom edge at 250 and the right edge at 480.
Against the true bottom edge at 239 and right edge at 479, the errors are 11 px and 1 px.
- Task
4.1assumed a flat answer, withq.top,q.bottom,q.left,q.right, andq.confidence. The API nests the four fractions underq.box, and it putsq.confidencebesideq.box. Theyesreply is flat, and its value is atq.noul. - The CLI of this commit expected the flat shape.
It rejected the reply with the message
The reply of the TypeSafe API has no valid box. Try again.and exit code1. - The fix to
boxOfis commit38d39b78, with the subjectdecide: read the nested box answer of jev-1.14.0.
| Call | Input tokens | Output tokens |
|---|---|---|
yes |
1143 |
20 |
box, before the fix |
1134 |
20 |
box, after the fix |
1135 |
20 |
box, shipped command |
1135, counted and not logged |
Not logged |
Three rejected calls (HTTP 400) |
Not known, no usage came back | Not known |
yes, scaled screenshot |
5244 |
20 |
box, scaled screenshot, logo |
5245 |
20 |
box, scaled screenshot, connector |
5241 |
20 |
| Total, answered calls | 20277 |
120 for the six logged calls |
At $0.042 per million input tokens, the seven answered calls cost about $0.00085.
The rejected calls returned no usage, so their cost is not known.
The price comes from design D3 of jev-images, and it is not checked again.
Output is free in that design, so the output tokens add no cost.
This section gives three calls that were rejected for the pixel size of the image.
The image is a browser screenshot.
It is a PNG of 1554 by 2000 pixels, with 8-bit RGBA.
The calls used the same wrapper method as the earlier calls.
They were one yes question with model jev-latest, and two box questions with model jev-1.14.0.
Each call got HTTP 400 with this body, shown with line breaks added:
{
"detail": {
"error_type": "api_usage_error",
"message": "Invalid image dimensions."
}
}The CLI printed TypeSafe API 400: <body> and exited with code 1.
The checks of the CLI before the call passed, which are the magic bytes and IMAGE_BYTES_MAX.
Design D4 leaves the pixel bounds to the API.
The docs give the bounds as 280 to 1568 pixels per side, and 78,400 to 2,458,624 pixels in total.
The height of 2000 pixels is over 1568.
The total of 3,108,000 pixels is also over 2,458,624.
No usage came back, so the input tokens of these calls are not known.
They are probably 0, but this page does not check it.
Commit c411962e adds a check of the pixel bounds to the CLI, which the user chose.
The CLI now reads the size from the header of the file, and it stops a file outside the bounds with exit code 2, before the request.
A run of the shipped command on the same screenshot, with a dummy key, printed this message and exited with code 2:
The image file `shot.png` is 1554x2000 px, which is over 1568 px on a side.
The API takes 280 to 1568 px per side, and it answers a larger or smaller image with a `400`.
Scale the image so that its longest side is at most 1568 px and its shortest side
is at least 280 px, then send it again.
The last sentence of the message is one line in the output. This page breaks it to keep the block within 100 columns.
The macOS command sips -Z 1568 made a copy of the screenshot at 1218 by 1568 pixels.
The longest side is then at the bound.
The same three questions ran on the copy, with the same wrapper method.
Each call got HTTP 200.
| Call | Model of the reply | Answer | Confidence | Input and output tokens | Time | Request ID |
|---|---|---|---|---|---|---|
yes, a circuit schematic |
jev-1.13.0 |
P(yes) = 1.00 |
Not applicable |
5244 and 20
|
917 ms | req_01a15bb5d3c87cd5906c12574723e859 |
box, the YouTube logo |
jev-1.14.0 |
top 0.13, bottom 0.18, left 0.10, right 0.19
|
0.91 |
5245 and 20
|
452 ms | req_01a15bb5d7777afba22eccbc49a560f8 |
box, the USB-C connector symbol |
jev-1.14.0 |
top 0.26, bottom 0.31, left 0.29, right 0.33
|
0.81 |
5241 and 20
|
411 ms | req_01a15bb5d941799cb2e49b2ab1a224de |
The request of the yes call named jev-latest, and the requests of the box calls named jev-1.14.0.
The CLI printed px x 122..231 y 204..282 of 1218x1568 for the logo, and px x 353..402 y 408..486 of 1218x1568 for the connector.
The reference boxes come from the original screenshot, read by eye, so they are approximate.
| Target | Reference box | Found box | Largest difference |
|---|---|---|---|
| YouTube logo | top 0.135, bottom 0.158, left 0.108, right 0.214
|
top 0.13, bottom 0.18, left 0.10, right 0.19
|
0.024 on the right edge |
| USB-C connector symbol | top 0.274, bottom 0.317, left 0.280, right 0.322
|
top 0.26, bottom 0.31, left 0.29, right 0.33
|
0.014 on the top edge |
For the logo, the box stops short on the right and goes too low at the bottom.
For the connector, each edge is within about 0.015.
An image near the bound used about 5240 input tokens, and the test image of 640 by 480 pixels used about 1135.
- Each answered call ran once. This page gives no rate and no spread.
- The images are one synthetic image and one browser screenshot. The reference boxes of the screenshot are read by eye.
- The pixel-bound section tests one image over the bound. It does not find the exact limit.
- The synthetic image has one high-contrast rectangle on white. The page does not show the accuracy on photographs.
- The page does not test a target that is absent from the image.
The text of the verb
boxsays that a box can come back for such a target. - The first
boxcall ran before the fix in commit38d39b78. The post-fix call ran after it. - Answers vary slightly between calls, for the same image and question.
The bottom edge was
0.51or0.52, the right edge was0.76or0.75, and the confidence was0.92or0.93.
claudetto
- Start
- Slices
- Add-Ons
- Reference
- Rationale
- Evidence
- Development
Claude Code