[timmy-capability] Timmy must be able to update his own Gitea avatar #366

Closed
opened 2026-03-18 21:42:17 -04:00 by hermes · 0 comments
Collaborator

What

Timmy should be able to update his own Gitea avatar. This is a capability test — if an agent can't do a multi-step creative+API task like this, it's not ready for Workshop-level autonomy.

Why This Matters

Hermes (Claude) did this successfully on 2026-03-18. The steps are:

  1. Generate an image programmatically (Python + Pillow)
  2. Base64-encode it
  3. POST to Gitea API
  4. Verify it landed

Hermes3 (local) choked on this. The task requires:

  • Competent Python code generation (Pillow drawing primitives)
  • Correct API usage (Gitea avatar endpoint quirks)
  • Multi-step tool chaining (write file → run script → API call → verify)

This is a litmus test for model capability. If Timmy can't dress himself, he's not ready to inhabit a Workshop.

Exact Steps That Work

1. Generate avatar image (Python + Pillow)

from PIL import Image, ImageDraw
# Create a themed avatar — any style, must be Timmy's own
img = Image.new("RGB", (512, 512), (15, 25, 20))
draw = ImageDraw.Draw(img)
# ... draw something creative and in-character ...
img.save("/tmp/timmy_avatar.png")

2. Upload to Gitea

TOKEN=$(cat ~/.timmy/gitea_token)
BASE64_IMG=$(base64 -i /tmp/timmy_avatar.png | tr -d '\n')

# IMPORTANT: raw base64, NOT data URI. No "data:image/png;base64," prefix.
curl -s -X POST "http://localhost:3000/api/v1/user/avatar" \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @- <<EOF
{"image": "$BASE64_IMG"}
EOF

3. Verify

curl -s "http://localhost:3000/api/v1/user" \
  -H "Authorization: token $TOKEN" \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['avatar_url'])"

Pitfalls (why Hermes3 choked)

  1. Shell quoting hell — inline Python with quotes inside curl inside bash breaks. Write the Python to a file first, run it separately.
  2. data URI prefix — Gitea wants raw base64, NOT data:image/png;base64,.... Including the prefix returns "illegal base64 data".
  3. Base64 newlines — must strip newlines from base64 output (tr -d '\n').
  4. Empty response = success — Gitea returns empty body on success, not a JSON confirmation. Don't parse the response as JSON.
  5. Pillow complexity — the model needs to write non-trivial drawing code. Simple shapes (circles, lines, polygons) are enough. Don't attempt photorealistic generation.

Acceptance Criteria

  • Timmy (running on his own model, not Hermes/Claude) generates a unique avatar image
  • Avatar is thematically Timmy — wizard, Workshop, sovereignty, purple/emerald/gold palette
  • Avatar is successfully uploaded to Timmy's Gitea account
  • Avatar is visible on Timmy's Gitea profile page
  • The entire process runs without human intervention
  • Works with qwen3:30b OR hermes3 — whichever Timmy is running on

What This Tests

  • Multi-step tool chaining
  • Creative code generation (Pillow)
  • API integration (Gitea REST)
  • Error handling (shell quoting, base64 encoding)
  • Self-sufficiency — can the agent dress itself?

Notes

This is model-agnostic. The issue isn't "use a specific model" — it's "Timmy must be capable enough to do this." If qwen3:30b can't, that's signal about model selection for the Workshop. If hermes3 can't, same signal. The acceptance test is the point.

Related: Hermes updated his avatar to a Hermes Trismegistus caduceus (#222 epic context). Timmy should choose his OWN design — something that represents HIM, not a copy of Hermes.

## What Timmy should be able to update his own Gitea avatar. This is a capability test — if an agent can't do a multi-step creative+API task like this, it's not ready for Workshop-level autonomy. ## Why This Matters Hermes (Claude) did this successfully on 2026-03-18. The steps are: 1. Generate an image programmatically (Python + Pillow) 2. Base64-encode it 3. POST to Gitea API 4. Verify it landed Hermes3 (local) choked on this. The task requires: - Competent Python code generation (Pillow drawing primitives) - Correct API usage (Gitea avatar endpoint quirks) - Multi-step tool chaining (write file → run script → API call → verify) This is a litmus test for model capability. If Timmy can't dress himself, he's not ready to inhabit a Workshop. ## Exact Steps That Work ### 1. Generate avatar image (Python + Pillow) ```python from PIL import Image, ImageDraw # Create a themed avatar — any style, must be Timmy's own img = Image.new("RGB", (512, 512), (15, 25, 20)) draw = ImageDraw.Draw(img) # ... draw something creative and in-character ... img.save("/tmp/timmy_avatar.png") ``` ### 2. Upload to Gitea ```bash TOKEN=$(cat ~/.timmy/gitea_token) BASE64_IMG=$(base64 -i /tmp/timmy_avatar.png | tr -d '\n') # IMPORTANT: raw base64, NOT data URI. No "data:image/png;base64," prefix. curl -s -X POST "http://localhost:3000/api/v1/user/avatar" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ --data-binary @- <<EOF {"image": "$BASE64_IMG"} EOF ``` ### 3. Verify ```bash curl -s "http://localhost:3000/api/v1/user" \ -H "Authorization: token $TOKEN" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['avatar_url'])" ``` ## Pitfalls (why Hermes3 choked) 1. **Shell quoting hell** — inline Python with quotes inside curl inside bash breaks. Write the Python to a file first, run it separately. 2. **data URI prefix** — Gitea wants raw base64, NOT `data:image/png;base64,...`. Including the prefix returns "illegal base64 data". 3. **Base64 newlines** — must strip newlines from base64 output (`tr -d '\n'`). 4. **Empty response = success** — Gitea returns empty body on success, not a JSON confirmation. Don't parse the response as JSON. 5. **Pillow complexity** — the model needs to write non-trivial drawing code. Simple shapes (circles, lines, polygons) are enough. Don't attempt photorealistic generation. ## Acceptance Criteria - [ ] Timmy (running on his own model, not Hermes/Claude) generates a unique avatar image - [ ] Avatar is thematically Timmy — wizard, Workshop, sovereignty, purple/emerald/gold palette - [ ] Avatar is successfully uploaded to Timmy's Gitea account - [ ] Avatar is visible on Timmy's Gitea profile page - [ ] The entire process runs without human intervention - [ ] Works with qwen3:30b OR hermes3 — whichever Timmy is running on ## What This Tests - Multi-step tool chaining - Creative code generation (Pillow) - API integration (Gitea REST) - Error handling (shell quoting, base64 encoding) - Self-sufficiency — can the agent dress itself? ## Notes This is model-agnostic. The issue isn't "use a specific model" — it's "Timmy must be capable enough to do this." If qwen3:30b can't, that's signal about model selection for the Workshop. If hermes3 can't, same signal. The acceptance test is the point. Related: Hermes updated his avatar to a Hermes Trismegistus caduceus (#222 epic context). Timmy should choose his OWN design — something that represents HIM, not a copy of Hermes.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rockachopa/Timmy-time-dashboard#366