Skip to content

feat: describe CLI image attachments with a Gemma vision sidecar - #206

Merged
Desperado merged 8 commits into
mainfrom
feat/vision-sidecar
Oct 17, 2026
Merged

Desperado merged 8 commits into
mainfrom
feat/vision-sidecar

Conversation

@Desperado

@Desperado Desperado commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

CLI backends receive text only, so images need a description before a text-only coding model can use them. Add a Gemma 4 sidecar that sends attached images to Cerebras and passes the description to the selected CLI.

The default auto mode applies to OpenCode with Z.AI coding-plan models; always enables the sidecar for every CLI backend, and off disables it. A Cerebras key is required. Configure it with /set vision_sidecar auto|always|off or qmax-code config set vision_sidecar off.

Screenshots and clipboard images fall back to the configured built-in multimodal backend when the sidecar fails, or stop with an explicit image-not-sent message. Dragged image paths retain the text-only CLI fallback. Cancellation skips the turn. Image descriptions escape markup delimiters.

Merged current main (including #214), resolved the changelog conflict while preserving both features, and removed an unreachable fallback. Added regression coverage for screenshot/paste routing, fallback, cancellation, config persistence/validation, unknown provider catalogues, invalid attachments, rejected/empty provider responses, request contents, Unicode truncation, and disabled-sidecar routing.

Validation:

  • Full coverage-enabled Go test suite, go vet ./..., golangci-lint, and release-style build pass.
  • All six sidecar functions have 100% statement coverage. Focused sidecar policy/request tests also pass under the race detector.
  • Ponytail review of the changed paths and connected callers; secret scan found no outstanding findings.
  • REPL race checks expose an existing readline startup/close WaitGroup race. It also reproduces on merged feat: keep rejected approaches visible across backend handoffs #214 without these sidecar changes; the ordinary full suite passes.
  • Tests use offline transports. Live Cerebras/provider behavior has not been verified in this update.

QualityMax follow-up: the REPL tests use replEnv, which restores http.DefaultTransport with t.Cleanup; these tests do not run in parallel. The reported missing cleanup is already present in the shared helper.

@qualitymaxapp

qualitymaxapp Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

QualityMax Review

Verdict: COMMENT · Confidence: evidence-backed scan

Re-review: Open the QualityMax check and select Re-review after it completes.

Files eligible: 14 · Files reviewed: 14 · Files with findings: 0 · Findings: 0 · Inline cards: 0

Priority findings

priority location finding
— — No blocking findings

Review gates

gate status
AI diff review completed · eligible 12, reviewed 12 · MODEL-ONLY findings are advisory · batches reviewed 2 of 2 · LLM · served gemini-3.1-flash-lite
SAST completed · eligible 14, reviewed 14 · hybrid · served qwen3.7-plus
Overall review evidence clean
Inline evidence not needed

Important files

file risk note next step
— — No findings —

Change diagram — Flow

flowchart TD
    Start[User Prompt with Images] --> CheckMode{Vision Sidecar Mode?}
    CheckMode -- Off --> Skip[Use Primary Model Directly]
    CheckMode -- Always --> CallSidecar[Call Cerebras Gemma 4]
    CheckMode -- Auto --> CheckModel{Is Model Text-Only?}
    CheckModel -- Yes --> CallSidecar
    CheckModel -- No --> Skip
    CallSidecar --> Describe[Get Description]
    Describe --> Augment[Inject Description into Prompt]
    Augment --> Send[Send to Primary Model]
Loading

Review lifecycle

Use the inline cards to inspect evidence and suggested remediation. Re-run the QualityMax review after pushing a fix; unchanged cards are identified by their stable finding marker. Dismiss with a reason through the existing QualityMax/GitHub review feedback flow. 1 prior card(s) are stale/resolved on this head. Thread reconciliation resolved 0/0 superseded QualityMax thread(s). @qmax Q&A is tracked separately.

Proof legend: GROUNDED deterministic scanner evidence · MODEL-ONLY advisory model judgment · MODEL-REVIEWED patch model judgment, not reproduction.

QualityMax project results are available in the configured project.

Receipt · commit 13d4f32e97f46ca770582ed0fab851d4d25c111a · run 2026-10-17T11:06:15+00:00 · model served qwen3.7-plus, gemini-3.1-flash-lite · model requested qwen3.7-plus, gemini-3.1-flash-lite · model review recorded — 3937 model output tokens · model source repository ai_review_preferences.preferred_model · re-review 2 · proof counts {}

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

@qualitymaxapp

qualitymaxapp Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

⚠️ QualityMax Pipeline

Gate Result
🔍 AI diff review ✅ Clean · gemini-3.1-flash-lite · completed · 12 eligible / 12 reviewed · gemini-3.1-flash-lite
🔍 SAST completed · 14 eligible / 14 reviewed · qwen3.7-plus
🔍 Canonical PR review delivery completed · 0 eligible / 0 reviewed · exact-head review #5557511330 and overview #5728556476 confirmed
🧪 Repo Tests ✅ 1551/1551 passed (go)
🤖 AI Tests ⚠️ 51/56 passed

Powered by QualityMax — AI-Powered Test Automation

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

@qualitymaxapp

qualitymaxapp Bot commented Sep 18, 2026

Copy link
Copy Markdown

⚠️ QualityMax Diff Analysis — WARN

The vision sidecar implementation is well-integrated and logically sound, but the prompt injection mitigation is insufficient. The current sanitization strategy for the description output is easily bypassed, potentially allowing the vision model to influence the main LLM's behavior via indirect prompt injection.

🟡 Finding 1: security

File: internal/agent/cerebras_vision.go:175 | Severity: warning

What: The sanitization of the vision sidecar description is weak and susceptible to prompt injection.

Fix: Instead of simple string replacement, consider using a more robust delimiter or a structured format (like JSON) for the description. Alternatively, instruct the main LLM in its system prompt to treat the content within tags as untrusted data rather than instructions.

Fix with your LLM agent
<your-llm-agent> "Fix the security issue in internal/agent/cerebras_vision.go at line 175: The sanitization of the vision sidecar description is weak and susceptible to prompt injection."
Fix all findings with your LLM agent
<your-llm-agent> "Fix all QualityMax review findings in this PR:\n- security in internal/agent/cerebras_vision.go:175: The sanitization of the vision sidecar description is weak and susceptible to prompt injection."

Change diagram — Flow

graph TD
    A[User Input: Prompt + Images] --> B{ShouldUseVisionSidecar?}
    B -- Yes --> C[DescribeImagesWithGemma (Cerebras)]
    C --> D[BuildSidecarAugmentedPrompt]
    D --> E[RunCLI (Main LLM)]
    B -- No --> E
    E --> F[Final Response]
Loading

Analyzed commit 67ffe068 with gemini-3.1-flash-lite (12 files, 11598 tokens) | Customize review preferences

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

Comment thread internal/agent/cerebras_vision.go Outdated
@qualitymaxapp qualitymaxapp Bot added the bug Something isn't working label Sep 18, 2026

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; inline findings are attached to this review.

@Desperado

Copy link
Copy Markdown
Contributor Author

👋 Thanks for the vision sidecar! A review turned up 4 bugs plus the lint errors that fail CI. The fixes are in #213, which targets feat/vision-sidecar:

  • 🛑 HIGH: pressing Esc couldn't stop the Gemma image read
  • 🛑 HIGH: text in a screenshot could close the </image-descriptions> block (prompt injection)
  • ⚠️ MEDIUM: the header could name images Gemma never read
  • ⚠️ MEDIUM: /screenshot and /paste images were dropped when the image read failed
  • 🔧 Fixed the two errcheck lint errors in cerebras_vision_test.go

Once #213 is merged in, please rebase on main. The branch is behind v1.36.0 and v1.37.0, which both touched internal/agent/. 🙏

- Esc now cancels the Gemma sidecar call: it runs on a cancellable
  context wired into the turn's cancel hook, and a cancelled sidecar
  skips the CLI turn instead of starting it after the timeout.
- Escape every '<' in the Gemma description so case/whitespace variants
  of </image-descriptions> in screenshot text can't close the block.
- Build the sidecar header from the same usable-image filter as the
  Gemma request, so [n] numbering matches the named files.
- /screenshot and /paste images fall back to the embedded multimodal
  backend when the sidecar fails (or fail with a clear error if none is
  configured) instead of being silently dropped.
- Check Decode/Encode errors in the sidecar test server (errcheck).

Adds regression tests for tag breakout, cancellation and the header
mismatch.
@Desperado Desperado changed the title feat/vision sidecar feat: describe CLI image attachments with a Gemma vision sidecar Oct 17, 2026
@qualitymaxapp

qualitymaxapp Bot commented Oct 17, 2026

Copy link
Copy Markdown

⚠️ QualityMax Diff Analysis — WARN

Completed 2 bounded review batches covering the full eligible diff. The PR introduces a robust vision sidecar feature that allows text-only CLI models to process images via a Cerebras-hosted Gemma 4 model. The implementation includes necessary security mitigations (prompt injection protection via tag escaping), proper error handling, context-aware cancellation, and comprehensive test coverage. The new test suite in internal/repl/vision_sidecar_test.go modifies the global http.DefaultTransport variable, which introduces significant risk of race conditions and test flakiness. Modifying global state in tests is a dangerous pattern that can affect other tests in the package if they run concurrently or rely on the default HTTP transport.

🟡 Finding 1: logic

File: internal/repl/vision_sidecar_test.go:33 | Severity: warning

What: The test suite directly assigns to the global http.DefaultTransport variable. This is a shared global resource; concurrent tests or tests relying on the default transport will experience non-deterministic behavior or failures.

Fix: Refactor the code under test to accept an *http.Client as a dependency (dependency injection) rather than relying on http.DefaultClient. If injection is not possible, use t.Cleanup to restore the original http.DefaultTransport after the test completes.

Fix with your LLM agent
<your-llm-agent> "Fix the logic issue in internal/repl/vision_sidecar_test.go at line 33: The test suite directly assigns to the global http.DefaultTransport variable. This is a shared global resource; concurrent tests or tests relying on the default transport will experience non-deterministic behavior or failures."
Fix all findings with your LLM agent
<your-llm-agent> "Fix all QualityMax review findings in this PR:\n- logic in internal/repl/vision_sidecar_test.go:33: The test suite directly assigns to the global http.DefaultTransport variable. This is a shared global resource; concurrent tests or tests relying on the default transport will experience non-deterministic behavior or failures."

Change diagram — Flow

graph TD
    A[User Input with Images] --> B{Use Vision Sidecar?}
    B -- Yes --> C[Call Gemma 4 (Cerebras)]
    C -- Success --> D[Augment Prompt with Descriptions]
    D --> E[Run CLI Model with Augmented Prompt]
    C -- Failure --> F{Embedded Fallback Available?}
    F -- Yes --> G[Run Embedded Multimodal Model]
    F -- No --> H[Run CLI Model with Original Prompt]
    B -- No --> I[Run CLI Model / Error]
Loading

Analyzed commit 3d480490 with gemini-3.1-flash-lite (12 files, 19466 tokens) | Customize review preferences

@codecov-commenter

codecov-commenter commented Oct 17, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; no inline findings were created for this review.

@qualitymaxapp qualitymaxapp Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QualityMax Review — canonical overview updated; no inline findings were created for this review.

@Desperado
Desperado merged commit 2246882 into main Oct 17, 2026
6 checks passed
@Desperado
Desperado deleted the feat/vision-sidecar branch October 17, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working qualitymax:reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants