Skip to content

Add VLM-judge creative critique tools - #4373

Merged
georgi merged 2 commits into
mainfrom
claude/nodetool-creative-agent-tgh6ye
Jul 20, 2026
Merged

georgi merged 2 commits into
mainfrom
claude/nodetool-creative-agent-tgh6ye

Conversation

@georgi

@georgi georgi commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

What

Five new agent tools in packages/agents that close the creative feedback loop — generate → look → critique → revise — built entirely on the vision-capable chat providers NodeTool already ships. No dedicated scorer models (PickScore/HPSv3-style weights) are introduced; all judging is VLM tool calls.

  • critique_image — reviews one image against the brief and returns directional feedback: concrete defects with location and fix, plus a pass/revise verdict. The prompt forbids "add more detail" advice, since vague critique makes iteration loops polish details while freezing a bad composition.
  • compare_images — picks the best of 2–8 candidates via a pairwise knockout tournament. VLM judges rank far better than they score and their verdicts are order-sensitive, so every match is judged twice with the presentation order swapped; disagreements go to a tiebreak call. Returns the winner plus every match verdict (triage, not deletion).
  • score_image_adherence — decomposes the brief into up to 12 binary yes/no checks (or takes explicit ones) and has the VLM answer each, returning per-check answers and the pass fraction — an explainable adherence score instead of one opaque rating.
  • record_style_preference / get_style_profile — persist aesthetic preferences (which variant the user chose, over what, in which brief) through LongTermMemory and return them as a profile block to inject into generation prompts and pass as taste_profile to the judging tools.

How

Judging tools take provider + model params (pair with find_model on a vision-capable chat model) and call ProcessingContext.runProviderPrediction with the generate_message capability at temperature 0, so asset:// image sources resolve to data URIs through the existing media resolver. Bare asset ids are normalized to asset:// URIs. Taste tools follow the ltm-tools binding pattern (constructor-bound LongTermMemory or per-user registry fallback, degrading gracefully when LTM isn't configured). All five are registered in BUILTIN_TOOL_CLASSES and exported from the package index.

Tests

15 new Vitest cases in packages/agents/tests/creative-critique-tools.test.ts covering param validation, JSON-parse failure paths, order-swap agreement and position-bias tiebreak behavior, knockout rounds with byes, adherence decompose/answer flow, and both taste tools. npm run test --workspace=packages/agents shows no new failures (71 pre-existing failures on this branch's base are environmental — sqlite-vec native module unavailable under --ignore-scripts install). Package tsc --noEmit and lint pass; web and electron typecheck pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SGdnz8JAsc4p3SyUUY3sAc


Generated by Claude Code

Close the generate → look → critique → revise loop with five agent tools
built entirely on existing vision-capable chat providers — no dedicated
scorer models:

- critique_image: directional defect list (what/where/fix) against the
  brief with a pass/revise verdict; forbids "add more detail" advice.
- compare_images: pairwise knockout tournament; every match judged twice
  with presentation order swapped to cancel position bias, plus a
  tiebreak call on disagreement.
- score_image_adherence: decomposes the brief into binary yes/no checks
  and answers each with the VLM — an explainable adherence score.
- record_style_preference / get_style_profile: persist aesthetic
  preferences via LongTermMemory and return them as a taste-profile
  block for generation prompts and judge rubrics.

Judging tools take provider+model params (pair with find_model) and run
through runProviderPrediction's generate_message capability at
temperature 0, so asset:// image sources resolve like everywhere else.
All five register as built-ins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SGdnz8JAsc4p3SyUUY3sAc
@georgi
georgi enabled auto-merge (squash) July 20, 2026 08:07
CodeQL flags Math.random as insecure randomness. The tiebreak order
choice isn't security-sensitive, but node:crypto randomInt costs
nothing and clears the alert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SGdnz8JAsc4p3SyUUY3sAc
@georgi
georgi merged commit 88de411 into main Jul 20, 2026
17 of 18 checks passed
@georgi
georgi deleted the claude/nodetool-creative-agent-tgh6ye branch July 20, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants