Skip to content

feat(bridge): native-vision skip guard + configurable describe output cap - #10289

Merged
diegosouzapw merged 8 commits into
release/v3.8.50from
feat/bridge-vision-skip-maxchars
Aug 14, 2026
Merged

feat(bridge): native-vision skip guard + configurable describe output cap#10289
diegosouzapw merged 8 commits into
release/v3.8.50from
feat/bridge-vision-skip-maxchars

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Summary

PR-C of the OCR/image-to-text migration series (plan: _tasks/superpowers/plans/2026-08-13-ocr-image-to-text-migration.md; patterns migrated from openclaw-zero-token's vision-skip + configurable describe limits).

  • Explicit native-vision skip guard (tests/unit/vision-bridge-native-skip.test.ts): permanent regression test proving that when the target model supports vision natively the bridge leaves messages untouched and makes zero vision-model calls — plus a dedicated Skipping: target model supports vision natively log at the capability early-return (the only production change of C1).
  • modalityBridgeVisionMaxChars — configurable cap on the vision model's description output ("raise for detail-heavy OCR tasks, cap for terse contexts"):
    • Schema: z.union([z.literal(0), z.number().int().min(100).max(50000)]).optional()0 is the explicit "no cap" sentinel, so an operator can always turn the cap back off (gap caught in review and fixed in-series).
    • Defaults/runtime: visionMaxChars: 0 in MODALITY_BRIDGE_DEFAULTS, maxChars on VisionBridgeRuntimeSettings.
    • Truncation applied at the single site where descriptions become [Image N]: text — cached descriptions are stored raw and re-capped at read time, so changing the cap re-applies to cache hits.
    • Dashboard: numeric field in Modality Bridge → Vision → Advanced (same NumberField pattern as Timeout/Max images; UI pulls 1–99 up to 100, 0 stays 0), i18n keys in en + 42 locales via i18n:sync-ui --translate-markers, docs row in GUARDRAILS.md.

Note for the merger: the mandated i18n sync also back-translated ~7 pre-existing unrelated __MISSING__ markers (thinkingMode* family, mostly in pt.json/zh-TW.json) and deduped a stale block — translation-only churn that pays existing i18n debt and raises the coverage ratchet; no hand edits outside this PR's keys.

Validation (TDD)

  • vision-bridge-native-skip 1/1 · vision-bridge-maxchars 5/5 (incl. explicit-0 no-truncation and 50-rejected) · UI modality-bridge-vision-tab 6/6 (asserts the PATCH body carries modalityBridgeVisionMaxChars: 2000; pre-existing cases untouched).
  • Canaries green: vision-bridge-mode 4/4, task-aware 5/5, modality-bridge-settings, cc-no-reroute 8/8, settings-schema 2/2, describe-cache 3/3.
  • typecheck:core 0 · eslint/prettier clean · check:docs-all 0 · zero __MISSING__ for the new keys across 42 locales.
  • Devbox note: running the 3 node:test files in one command trips database is locked (shared temp DATA_DIR across parallel test processes — environmental); each file is green in isolation, and CI shards run them separately.

⚠️ base-red inherited: #9985 (ESLint errors from #10240/#9448 — unrelated to this diff)

Add the "Max description characters" field to the Vision tab's Advanced
panel (modalityBridgeVisionMaxChars, clamped to the 100-50000 schema
range with 0 treated as the explicit "unlimited" sentinel), wire the
en.json copy and sync it across all 42 locales, and document the new
setting in GUARDRAILS.md.
updateSettingsSchema previously rejected modalityBridgeVisionMaxChars: 0
because the field's range was min(100).max(50000), so a dashboard PATCH
sending the explicit "unlimited" sentinel would 400. Widen the schema to
z.union([z.literal(0), z.number().int().min(100).max(50000)]) so 0
validates as its own valid value, not just an implicit default.
…e-vision-skip-maxchars

# Conflicts:
#	src/i18n/messages/ar.json
#	src/i18n/messages/az.json
#	src/i18n/messages/bg.json
#	src/i18n/messages/bn.json
#	src/i18n/messages/cs.json
#	src/i18n/messages/da.json
#	src/i18n/messages/de.json
#	src/i18n/messages/es.json
#	src/i18n/messages/fa.json
#	src/i18n/messages/fi.json
#	src/i18n/messages/fr.json
#	src/i18n/messages/gu.json
#	src/i18n/messages/he.json
#	src/i18n/messages/hi.json
#	src/i18n/messages/hu.json
#	src/i18n/messages/id.json
#	src/i18n/messages/in.json
#	src/i18n/messages/it.json
#	src/i18n/messages/ja.json
#	src/i18n/messages/ko.json
#	src/i18n/messages/mr.json
#	src/i18n/messages/ms.json
#	src/i18n/messages/nl.json
#	src/i18n/messages/no.json
#	src/i18n/messages/phi.json
#	src/i18n/messages/pl.json
#	src/i18n/messages/pt.json
#	src/i18n/messages/ro.json
#	src/i18n/messages/ru.json
#	src/i18n/messages/sk.json
#	src/i18n/messages/sv.json
#	src/i18n/messages/sw.json
#	src/i18n/messages/ta.json
#	src/i18n/messages/te.json
#	src/i18n/messages/th.json
#	src/i18n/messages/tr.json
#	src/i18n/messages/uk-UA.json
#	src/i18n/messages/ur.json
#	src/i18n/messages/zh-CN.json
#	src/i18n/messages/zh-TW.json
@diegosouzapw
diegosouzapw merged commit a7ddcf1 into release/v3.8.50 Aug 14, 2026
22 checks passed
@diegosouzapw
diegosouzapw deleted the feat/bridge-vision-skip-maxchars branch August 14, 2026 16:06
@diegosouzapw diegosouzapw mentioned this pull request Aug 15, 2026
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