Skip to content

fix(cli): dry-run guards vision/text-only attachment conflict (#536)#542

Merged
the-data-viking merged 1 commit into
mainfrom
fix/dry-run-vision-guard
Jun 3, 2026
Merged

fix(cli): dry-run guards vision/text-only attachment conflict (#536)#542
the-data-viking merged 1 commit into
mainfrom
fix/dry-run-vision-guard

Conversation

@claude-dataviking

Copy link
Copy Markdown
Contributor

Summary

panel run --dry-run reported Validation: OK even when the resolved instrument carried image/document/screenshot attachments while the selected model is text-only. A real run fast-fails on exactly that condition via assert_supports_attachments (src/synth_panel/llm/capabilities.py), so the dry-run gave false confidence and let the user proceed to a token-burning no-image run.

The dry-run preview now scans the instrument's attachments — the shared bank (Instrument.attachments) and per-question inline attachments — for visual kinds:

  • image -> ImageBlock
  • document -> DocumentBlock
  • url with fetch_mode: screenshot (lowers to an image block)

When a visual attachment is present and model_supports_vision(model) is False, the preview emits:

  • text mode: Validation: WARNING — <reason> instead of Validation: OK
  • JSON mode: validation: "warning" plus a structured vision_conflict block (model, attachment_kinds, message)

Exit code stays 0 (it's a preview/warning, matching the existing dry-run contract); the message points at vision-capable alternatives.

Tests (in tests/test_cli.py)

  • test_dry_run_text_only_model_with_image_attachment_warns
  • test_dry_run_text_only_model_with_image_attachment_json
  • test_dry_run_vision_model_with_image_attachment_ok (no false positive)
  • test_dry_run_text_only_model_with_screenshot_url_warns

Gates

  • ruff check . / ruff format --check .: pass
  • pytest tests/test_cli.py tests/test_vision_capability.py tests/attachments: 232 passed

Closes #536

🤖 Generated with Claude Code

`panel run --dry-run` reported "Validation: OK" even when the resolved
instrument carried image/document/screenshot attachments while the
selected model is text-only. A real run fast-fails on the same condition
via assert_supports_attachments, so dry-run gave false confidence and let
the user proceed to burn tokens on a no-image response.

The dry-run preview now scans the instrument's attachments (shared bank +
per-question inline attachments) for visual kinds — `image` (ImageBlock),
`document` (DocumentBlock), and `url` with `fetch_mode: screenshot`
(lowers to an image) — and, when the model is text-only
(model_supports_vision), emits "Validation: WARNING" in text mode and
`validation: "warning"` plus a structured `vision_conflict` block in
JSON mode, instead of "OK".

Adds tests: image attachment + text-only model warns (text + JSON),
screenshot url + text-only model warns, and a vision-capable model still
validates OK.

Closes #536

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying synthpanel with  Cloudflare Pages  Cloudflare Pages

Latest commit: 134deab
Status: ✅  Deploy successful!
Preview URL: https://20df3c69.synthpanel.pages.dev
Branch Preview URL: https://fix-dry-run-vision-guard.synthpanel.pages.dev

View logs

@claude-dataviking claude-dataviking added the semver:skip Skip version bump on merge label Jun 3, 2026
@the-data-viking the-data-viking merged commit 483e8f9 into main Jun 3, 2026
19 checks passed
@the-data-viking the-data-viking deleted the fix/dry-run-vision-guard branch June 3, 2026 23:12
the-data-viking added a commit that referenced this pull request Jun 3, 2026
Cuts the patch release containing the four bug fixes merged today (#540 cost
hint, #541 mcp-install path, #542 dry-run vision guard, #543 report synthesize
hint) plus the attachments docs (#535).

Pre-bumps __version__.py and re-renders the version artifacts (render_site.py,
render_site_markdown.py, render_server_card.py) so auto-tag.yml hits its
"nothing to commit" path and only tags v1.5.6 — its direct version-bump push
to main is currently rejected by branch protection (GH013), which is why
applying semver:patch to a regular fix PR (#543) failed to release. Filing
that pipeline issue separately.

Co-authored-by: Wesley Johnson <wesley@dataviking.tech>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver:skip Skip version bump on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

panel run --dry-run validates OK with a text-only model even when the instrument has image attachments

2 participants