Repository navigation
Recipes
Whole tasks with aw.py, each run as shown. A batch judged end to end, with the verdict read back by a calling
plugin, is on the Verdict contract page.
Every command prints one JSON object, so a caller runs it and parses stdout. Check the exit code too: 1 means
"ok": false somewhere in the answer, and 2 means a usage mistake with nothing on stdout
(Errors and edge cases).
import json
import subprocess
import sys
def aw(*args):
r = subprocess.run([sys.executable, "aw.py", *args], capture_output=True, text=True, encoding="utf-8")
return r.returncode, json.loads(r.stdout)
code, info = aw("info", "dusk.png", "missing.png")
print("exit", code)
for item in info["items"]:
if item["ok"]:
print(item["file"], item["size"], item["tokens"]["standard"]["tokens"], "tokens")
else:
print(item["file"], "error:", item["error"])prints:
exit 1
dusk.png [2000, 1200] 1500 tokens
missing.png error: no such file: missing.png
Replace "aw.py" with the script's full path when the caller runs from another folder.
for f in renders/*.png; do
python aw.py info "$f" | python -c "import json,sys; i=json.load(sys.stdin)['items'][0]; print(i['file'], i['tokens']['standard']['tokens'])"
doneprints:
renders/render_01.png 25
renders/render_01_copy.png 25
renders/render_02.png 25
renders/render_03.png 25
renders/render_04.png 25
renders/render_05.png 25
renders/render_06.png 25
info takes many files at once, so for one JSON answer pass them all: python aw.py info renders. Seven reads of
25 tokens each are cheap; the habit matters for photographs, where one 2000 x 1200 image is 1500 tokens on the
standard tier and a 1024 px copy is 814.
The pixel skill keeps a fix only when the numbers improve and a blind comparison prefers it. Run pixel on the
sprite before and after the fixer, with the same budget. Before (the resampled sprite):
python aw.py pixel sprite_ai.png --budget 16ends:
"clean_pixel_art": false,
"problems": [
"off-grid pixels (lattice alignment 66.7%)",
"blocks not uniform (66.0%)",
"transitional (blend) pixels 2.95%",
"145 semi-transparent pixels"
]
After (the clean sprite stands in for the fixer's output here):
python aw.py pixel sprite.png --budget 16 --preview sprite_x4.pngends:
"clean_pixel_art": true,
"problems": []
Then judge the two with compare prepare and compare record in both orders, blind, before keeping the fix.
To see whether a judge prefers the right image, pair an image with a damaged copy of itself. degrade is
deterministic, so the same command makes the same pair on any run:
for k in saturate crush crop; do python aw.py degrade dusk.png -o dusk_$k.png --kind $k --seed 7; doneprints:
{
"out": "dusk_saturate.png",
"kind": "saturate",
"seed": 7,
"size": [
2000,
1200
],
"ok": true
}
{
"out": "dusk_crush.png",
"kind": "crush",
"seed": 7,
"size": [
2000,
1200
],
"ok": true
}
{
"out": "dusk_crop.png",
"kind": "crop",
"seed": 7,
"size": [
2000,
1200
],
"ok": true
}
Each dusk.png against dusk_<kind>.png pair has an expected winner. Record the person's pick with cache label
and compare with the judge using cache agreement (How images are judged).
A batch often holds the same render twice, re-encoded. dedupe groups them by difference hash, and keep is the
list to judge:
python aw.py dedupe rendersprints:
{
"groups": [
[
"renders/render_01.png",
"renders/render_01_copy.png"
]
],
"pairs": [
{
"a": "renders/render_01.png",
"b": "renders/render_01_copy.png",
"distance": 0
}
],
"keep": [
"renders/render_01.png",
"renders/render_02.png",
"renders/render_03.png",
"renders/render_04.png",
"renders/render_05.png",
"renders/render_06.png"
],
"threshold": {
"algo": "dhash",
"version": 1,
"max_distance": 6
},
"ok": true
}
render_01_copy.png was render_01.png through degrade --kind jpeg: a different file (another SHA-256) with
the same 64-bit hashes, distance 0.
Crop at full resolution rather than reading the whole image larger. A 300 x 150 box around the fox in the 2000 x 1200 scene:
python aw.py fit dusk.png -o fox_crop.png --crop 1100,850,300,150prints:
{
"out": "fox_crop.png",
"size": [
300,
150
],
"tokens": {
"standard": {
"tokens": 66,
"read_at": [
300,
150
]
},
"high": {
"tokens": 66,
"read_at": [
300,
150
]
}
},
"ok": true
}
66 tokens, against 1500 for the whole image on the standard tier.
This wiki describes artwright 0.7.2 (the v0.7.2 tag, commit a185c05) and was last updated on 2026-10-26. The plugin is MIT licensed. Report problems in the issues. It installs from the repository, m4bwav/artwright, or from the 0.7.2 release.
Using it
- Getting started
- Skills
- Commands
- Light, colour and composition
- How images are judged
- Verdict contract
- Errors and edge cases
- Recipes
- FAQ
The releases
Contributing
Elsewhere