Skip to content

feat(vision): make sidecar reasoning configurable - #1002

Open
hanjianjun wants to merge 2 commits into
lidge-jun:devfrom
hanjianjun:agent/configurable-vision-reasoning
Open

feat(vision): make sidecar reasoning configurable#1002
hanjianjun wants to merge 2 commits into
lidge-jun:devfrom
hanjianjun:agent/configurable-vision-reasoning

Conversation

@hanjianjun

@hanjianjun hanjianjun commented Aug 4, 2026

Copy link
Copy Markdown

Summary

  • make the OpenAI vision sidecar reasoning effort configurable
  • expose low, medium, high, xhigh, and max in the Dashboard and management API
  • preserve the existing low default for backward compatibility
  • include reasoning effort in the vision-description cache identity
  • document the option across all shipped documentation locales

Why

The vision sidecar previously hard-coded reasoning.effort: "low", even though the CLI already accepted ocx agent sidecar vision --reasoning. Users of vision models such as gpt-5.6-luna therefore could not trade latency and cost for more detailed image analysis, and the CLI setting was silently ignored by the vision management path.

Impact

OpenAI-backed vision descriptions now send the configured effort in the Responses request. Existing configurations behave exactly as before because the default remains low. Anthropic vision retains the setting in shared configuration but ignores the OpenAI-specific wire field. Cache entries are separated by reasoning effort so changing the setting cannot reuse a description produced at a different effort.

Validation

  • bun run typecheck
  • bun run test — 8214 passed, 8 skipped, 0 failed
  • focused vision tests — 25 passed, 0 failed after the final cache-key adjustment
  • cd gui && bun test tests — 583 passed, 0 failed
  • cd gui && bun run lint:i18n && bun run lint && bun run build
  • cd docs-site && ASTRO_TELEMETRY_DISABLED=1 bun run build — 216 pages built
  • bun run privacy:scan

Summary by CodeRabbit

  • New Features

    • Added a Vision reasoning-effort setting with five levels: low, medium, high, xhigh, and max.
    • Added a dashboard selector that adapts to each model’s supported reasoning levels.
    • Added localized labels for the new setting.
  • Bug Fixes

    • Vision image-description caches now distinguish between reasoning levels.
    • Invalid reasoning values are safely rejected or reset to the default.
  • Documentation

    • Updated configuration references and Vision sidecar examples in supported languages.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a configurable reasoning effort setting (low, medium, high, xhigh, max) to the vision sidecar. The setting flows through type definitions, vision plan and cache logic, the management API, dashboard GUI, i18n labels, tests, and localized documentation, replacing hardcoded "low" behavior.

Changes

Vision Reasoning Effort Implementation

Layer / File(s) Summary
Type definitions and contracts
src/types.ts, src/vision/describe.ts
Adds optional reasoning field to OcxVisionSidecarConfig and required reasoning field to VisionSettings, both typed as "low" | "medium" | "high" | "xhigh" | "max".
Reasoning effort constants and validation
src/reasoning-effort.ts
Exports VISION_REASONING_EFFORTS ladder, provides VisionReasoningEffort type, isVisionReasoningEffort() type guard, and sanitizeVisionReasoning() sanitizer that rejects non-string and unsupported values.
Vision planning and cache-key logic
src/vision/index.ts, src/vision/describe.ts
Applies configured or default ("low") reasoning to Anthropic and OpenAI vision sidecar plans. describeImage forwards the configured reasoning. Cache identities include reasoning for OpenAI descriptions but exclude it for Anthropic descriptions.
Configuration load-time and mutation validation
src/config.ts
Sanitizes invalid visionSidecar.reasoning values before schema validation during load, warns when degradation occurs, and validates at mutation boundary to reject invalid values in live updates.
Management API reasoning support
src/server/management/config-routes.ts
GET response includes reasoning with "low" default. PUT request accepts, validates, sanitizes, and persists reasoning. Invalid values return 400 error. PUT response includes persisted reasoning value.
Dashboard reasoning selector and logic
gui/src/pages/dashboard-shared.ts, gui/src/pages/dashboard-overview-sections.tsx, gui/tests/dashboard-contracts.test.ts
Adds VisionReasoning type and VISION_REASONING_LEVELS constant. Extends mergeSidecarSetting to persist reasoning. visionReasoningLadder() filters supported efforts by model. visionReasoningOptionsFor() preserves unsupported persisted values. Dashboard UI adds paired model and reasoning selectors that persist selections and compute compatible levels on model change. Tests verify ladder behavior, merge preservation, and model-advertised efforts.
Localization labels
gui/src/i18n/en.ts, gui/src/i18n/de.ts, gui/src/i18n/ja.ts, gui/src/i18n/ko.ts, gui/src/i18n/ru.ts, gui/src/i18n/zh.ts
Adds the dash.visionReasoning translation key across six languages.
Integration and resilience tests
tests/claude-sidecar-override.test.ts, tests/vision-anthropic.test.ts, tests/vision-cache.test.ts, tests/vision-sidecar-e2e.test.ts, tests/config.test.ts, tests/settings-stream-mode.test.ts
Updates sidecar plan expectations to include default or persisted reasoning. Verifies cache-key separation by reasoning and model. Confirms Anthropic reasoning changes reuse cache. Tests invalid-value degradation to "low". Validates end-to-end forwarding of configured reasoning to the backend. Tests configuration validation and resilience of hand-edited invalid reasoning.
Localized documentation
docs-site/src/content/docs/guides/sidecars.md, docs-site/src/content/docs/reference/configuration/server.md, docs-site/src/content/docs/{ja,ko,ru,zh-cn}/...
Documents the reasoning field, explains that OpenAI requests use the selected effort and Anthropic ignores it, describes the updated vision cache-key composition including reasoning, and provides an updated example configuration switching from Anthropic claude-sonnet-5 to OpenAI gpt-5.6-luna with medium reasoning. Updates appear in English, Japanese, Korean, Russian, and Simplified Chinese guide and reference documentation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Dashboard as Dashboard GUI
  participant ConfigAPI as Management API
  participant VisionIndex as vision/index.ts
  participant Describe as vision/describe.ts
  participant Backend as OpenAI/Anthropic Backend

  Dashboard->>ConfigAPI: PUT visionSidecar.reasoning
  ConfigAPI->>ConfigAPI: validate and sanitize reasoning
  ConfigAPI-->>Dashboard: 200 with persisted reasoning
  Note over VisionIndex: later, on image description request
  VisionIndex->>VisionIndex: build plan with configured reasoning
  VisionIndex->>VisionIndex: compute cache key: backend + model + reasoning + details
  VisionIndex->>Describe: describeImage(settings with reasoning)
  Describe->>Backend: send request with reasoning effort
  Backend-->>Describe: description result
  Describe-->>VisionIndex: description or error
  VisionIndex-->>Dashboard: return cached or fresh description
Loading

Possibly related PRs

  • lidge-jun/opencodex#494: Related through shared reasoning-effort handling in chat request logs.
  • lidge-jun/opencodex#853: Related through shared reasoning-effort metadata and model capability ladders used in the dashboard vision selector.
  • lidge-jun/opencodex#980: Related through shared vision-sidecar functionality, reasoning-effort metadata, and model capability handling.

Suggested reviewers: wibias, ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 59.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: configurable reasoning effort for the vision sidecar.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 4, 2026
@hanjianjun
hanjianjun marked this pull request as ready for review August 4, 2026 12:32

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1122fe5cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/vision/index.ts Outdated
settings: { model: resolveOpenAiVisionModel(config), timeoutMs: cfg.timeoutMs ?? DEFAULT_TIMEOUT_MS },
settings: {
model: resolveOpenAiVisionModel(config),
reasoning: cfg.reasoning ?? DEFAULT_REASONING,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate loaded reasoning before forwarding it

When visionSidecar.reasoning is written through ocx config set/import or by editing config.json, configSchema passes the sidecar object through and validateConfigCandidate() therefore accepts arbitrary values such as "ultra"; this line then forwards that value as reasoning.effort, causing every OpenAI vision description to be rejected upstream even though the management endpoint rejects the same input. Add this enum to the persisted-config validation/normalization path, or normalize it before constructing VisionSettings.

Useful? React with 👍 / 👎.

Comment thread src/vision/index.ts Outdated
key: JSON.stringify([
plan.backend,
plan.settings.model,
plan.settings.reasoning,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exclude ignored Anthropic reasoning from the cache key

When the selected vision backend is Anthropic and the operator changes this dashboard-exposed reasoning setting, the Anthropic request remains identical (anthropic-describe.ts always sends thinking: { type: "disabled" } and never reads settings.reasoning), but this key changes. Consequently the same image and context bypass an otherwise valid cached description and trigger another potentially billed OAuth sidecar call; include reasoning in the identity only for the OpenAI backend, or key on the effective Anthropic settings.

Useful? React with 👍 / 👎.

/>
<Select
value={sidecar?.vision.reasoning ?? "low"}
options={VISION_REASONING_LEVELS.map(value => ({ value, label: value }))}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restrict effort choices to the selected vision model

This picker offers max for every OpenAI vision model, but the repository's native catalog deliberately gives only GPT-5.6 models the max rung and limits native gpt-5.5, gpt-5.4, and gpt-5.4-mini to low through xhigh (src/codex/catalog/sync.ts). Selecting max with one of those models therefore persists a value that passes the management API's universal enum check and is sent raw as reasoning.effort, causing the vision request to fail; derive the choices from the selected model's reasoningEfforts metadata or validate/clamp the pair server-side.

AGENTS.md reference: gui/AGENTS.md:L9-L10

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/guides/sidecars.md`:
- Around line 79-81: Rewrite the sidecar image-processing descriptions to
distinguish provider-specific transports: in
docs-site/src/content/docs/guides/sidecars.md lines 79-81, explain ChatGPT-login
passthrough uses the OpenAI Responses endpoint and that Anthropic uses the
Messages path with its thinking-budget mapping; apply the equivalent provider
split in Japanese at docs-site/src/content/docs/ja/guides/sidecars.md lines
78-80, Korean at docs-site/src/content/docs/ko/guides/sidecars.md lines 79-81,
Russian at docs-site/src/content/docs/ru/guides/sidecars.md lines 90-92, and
Chinese at docs-site/src/content/docs/zh-cn/guides/sidecars.md lines 72-73,
preserving each language’s accuracy and alignment with the provider contracts.

In `@docs-site/src/content/docs/ja/reference/configuration/server.md`:
- Line 147: Update the reasoning configuration references to add one concise
upstream-support caveat in each affected table or adjacent paragraph:
docs-site/src/content/docs/ja/reference/configuration/server.md:147-147 in
Japanese,
docs-site/src/content/docs/ko/reference/configuration/server.md:147-147 in
Korean, docs-site/src/content/docs/reference/configuration/server.md:179-179 in
English, docs-site/src/content/docs/ru/reference/configuration/server.md:182-182
in Russian, and
docs-site/src/content/docs/zh-cn/reference/configuration/server.md:162-162 in
Chinese. State that supported reasoning levels are gated by upstream provider
capabilities and the provider’s available reasoning ladder.

In `@gui/src/i18n/ru.ts`:
- Line 217: Update the dash.visionReasoning translation to replace the English
“vision” with the file’s established Russian wording “для изображений,” matching
the phrasing pattern used by dash.searchReasoning and related vision keys.

In `@src/server/management/config-routes.ts`:
- Around line 347-352: Extract the shared vision reasoning allowlist into a
single constant in the config-routes module, then reuse it in both the
validation branch around the vision.reasoning check and the persistence branch
around the second repeated check. Replace both duplicated OR chains with
membership checks against that constant so both paths always accept the same
five values.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 006a539f-e1bf-41f8-987e-3ffa15d8d192

📥 Commits

Reviewing files that changed from the base of the PR and between e44d234 and a1122fe.

📒 Files selected for processing (27)
  • docs-site/src/content/docs/guides/sidecars.md
  • docs-site/src/content/docs/ja/guides/sidecars.md
  • docs-site/src/content/docs/ja/reference/configuration/server.md
  • docs-site/src/content/docs/ko/guides/sidecars.md
  • docs-site/src/content/docs/ko/reference/configuration/server.md
  • docs-site/src/content/docs/reference/configuration/server.md
  • docs-site/src/content/docs/ru/guides/sidecars.md
  • docs-site/src/content/docs/ru/reference/configuration/server.md
  • docs-site/src/content/docs/zh-cn/guides/sidecars.md
  • docs-site/src/content/docs/zh-cn/reference/configuration/server.md
  • gui/src/i18n/de.ts
  • gui/src/i18n/en.ts
  • gui/src/i18n/ja.ts
  • gui/src/i18n/ko.ts
  • gui/src/i18n/ru.ts
  • gui/src/i18n/zh.ts
  • gui/src/pages/dashboard-overview-sections.tsx
  • gui/src/pages/dashboard-shared.ts
  • gui/tests/dashboard-contracts.test.ts
  • src/server/management/config-routes.ts
  • src/types.ts
  • src/vision/describe.ts
  • src/vision/index.ts
  • tests/claude-sidecar-override.test.ts
  • tests/vision-anthropic.test.ts
  • tests/vision-cache.test.ts
  • tests/vision-sidecar-e2e.test.ts

Comment thread docs-site/src/content/docs/guides/sidecars.md Outdated
Comment thread docs-site/src/content/docs/ja/reference/configuration/server.md
Comment thread gui/src/i18n/ru.ts Outdated
Comment thread src/server/management/config-routes.ts Outdated
@hanjianjun

Copy link
Copy Markdown
Author

Review feedback addressed in 47e2540.

  • P2 persisted-config validation: visionSidecar.reasoning is now sanitized at load time (invalid hand edits degrade to the default with a warning instead of breaking startup or reaching the wire), rejected at the CLI write boundary (validateConfigCandidate), and normalized again before constructing the vision plan.
  • P2 Anthropic cache key: the description cache now includes reasoning effort only for the OpenAI backend, so an effort change cannot evict a valid Anthropic cached description.
  • P2 model ladder: the Dashboard derives the reasoning picker options from the selected model's reasoningEfforts metadata and clamps the persisted value to the new model's highest supported rung when switching models.
  • CodeRabbit nits: shared VISION_REASONING_EFFORTS constant now backs both management checks, the Russian label follows the file's для изображений convention, guides in all five locales describe the OpenAI Responses vs Anthropic Messages split, and the reference tables note that supported levels are upstream/model-gated.

Validation: full server suite 8217 passed / 0 failed, GUI suite 585 passed / 0 failed, typecheck, GUI lint+build, docs build (216 pages), and privacy scan all green.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs-site/src/content/docs/guides/sidecars.md (1)

95-96: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the cache-key documentation across all locales.

The runtime includes reasoning in the description cache identity only for the OpenAI backend. Anthropic intentionally excludes the OpenAI-specific setting. Update each affected sentence to state this backend-specific behavior.

  • docs-site/src/content/docs/guides/sidecars.md#L95-L96: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ja/guides/sidecars.md#L93-L94: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ko/guides/sidecars.md#L93-L96: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ru/guides/sidecars.md#L107-L108: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/zh-cn/guides/sidecars.md#L85-L87: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/reference/configuration/server.md#L186-L188: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ja/reference/configuration/server.md#L151-L151: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ko/reference/configuration/server.md#L151-L151: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/ru/reference/configuration/server.md#L189-L192: qualify reasoning as an OpenAI-only cache-key component.
  • docs-site/src/content/docs/zh-cn/reference/configuration/server.md#L166-L166: qualify reasoning as an OpenAI-only cache-key component.

As per path instructions, keep translated documentation synchronized with actual runtime behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-site/src/content/docs/guides/sidecars.md` around lines 95 - 96, Update
the cache-key sentences to state that reasoning is included only for the OpenAI
backend, while preserving the existing exclusion for Anthropic. Apply this
wording correction in docs-site/src/content/docs/guides/sidecars.md:95-96,
docs-site/src/content/docs/ja/guides/sidecars.md:93-94,
docs-site/src/content/docs/ko/guides/sidecars.md:93-96,
docs-site/src/content/docs/ru/guides/sidecars.md:107-108,
docs-site/src/content/docs/zh-cn/guides/sidecars.md:85-87,
docs-site/src/content/docs/reference/configuration/server.md:186-188,
docs-site/src/content/docs/ja/reference/configuration/server.md:151-151,
docs-site/src/content/docs/ko/reference/configuration/server.md:151-151,
docs-site/src/content/docs/ru/reference/configuration/server.md:189-192, and
docs-site/src/content/docs/zh-cn/reference/configuration/server.md:166-166,
keeping each translation synchronized with the runtime behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/guides/sidecars.md`:
- Around line 79-82: Add a caveat after each provider-specific transport
description explaining that the reasoning ladder support is constrained by the
selected provider and model, and that the Dashboard clamps persisted values when
a model does not advertise the selected reasoning level. This caveat must be
added at the following locations with equivalent translations or localized
versions: English version in docs-site/src/content/docs/guides/sidecars.md at
lines 79-82 (anchor), Japanese version in
docs-site/src/content/docs/ja/guides/sidecars.md at lines 78-81, Korean version
in docs-site/src/content/docs/ko/guides/sidecars.md at lines 79-82, Russian
version in docs-site/src/content/docs/ru/guides/sidecars.md at lines 90-93, and
Simplified Chinese version in
docs-site/src/content/docs/zh-cn/guides/sidecars.md at lines 72-74. Ensure the
caveat does not imply that advertised reasoning levels are universally supported
across all models or providers.

In `@src/config.ts`:
- Around line 1657-1662: Preserve an untouched copy of parsed before
sanitizeVisionSidecarForLoad mutates it, then pass that original data to both
warnDegradedVisionReasoning calls while continuing to use the sanitized parsed
object for schema parsing and other behavior. Update the relevant load paths
around sanitizeVisionSidecarForLoad and both warning-call sites without changing
the sanitizer’s existing validation behavior.

---

Outside diff comments:
In `@docs-site/src/content/docs/guides/sidecars.md`:
- Around line 95-96: Update the cache-key sentences to state that reasoning is
included only for the OpenAI backend, while preserving the existing exclusion
for Anthropic. Apply this wording correction in
docs-site/src/content/docs/guides/sidecars.md:95-96,
docs-site/src/content/docs/ja/guides/sidecars.md:93-94,
docs-site/src/content/docs/ko/guides/sidecars.md:93-96,
docs-site/src/content/docs/ru/guides/sidecars.md:107-108,
docs-site/src/content/docs/zh-cn/guides/sidecars.md:85-87,
docs-site/src/content/docs/reference/configuration/server.md:186-188,
docs-site/src/content/docs/ja/reference/configuration/server.md:151-151,
docs-site/src/content/docs/ko/reference/configuration/server.md:151-151,
docs-site/src/content/docs/ru/reference/configuration/server.md:189-192, and
docs-site/src/content/docs/zh-cn/reference/configuration/server.md:166-166,
keeping each translation synchronized with the runtime behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5a0ab5cb-72fb-40da-9e5d-9946acf3960d

📥 Commits

Reviewing files that changed from the base of the PR and between a1122fe and 47e2540.

📒 Files selected for processing (23)
  • docs-site/src/content/docs/guides/sidecars.md
  • docs-site/src/content/docs/ja/guides/sidecars.md
  • docs-site/src/content/docs/ja/reference/configuration/server.md
  • docs-site/src/content/docs/ko/guides/sidecars.md
  • docs-site/src/content/docs/ko/reference/configuration/server.md
  • docs-site/src/content/docs/reference/configuration/server.md
  • docs-site/src/content/docs/ru/guides/sidecars.md
  • docs-site/src/content/docs/ru/reference/configuration/server.md
  • docs-site/src/content/docs/zh-cn/guides/sidecars.md
  • docs-site/src/content/docs/zh-cn/reference/configuration/server.md
  • gui/src/i18n/ru.ts
  • gui/src/pages/dashboard-overview-sections.tsx
  • gui/src/pages/dashboard-shared.ts
  • gui/tests/dashboard-contracts.test.ts
  • src/config.ts
  • src/reasoning-effort.ts
  • src/server/management/config-routes.ts
  • src/vision/describe.ts
  • src/vision/index.ts
  • tests/config.test.ts
  • tests/settings-stream-mode.test.ts
  • tests/vision-anthropic.test.ts
  • tests/vision-cache.test.ts

Comment on lines +79 to +82
- On the OpenAI path (ChatGPT-login passthrough), each image is sent to the configured vision model
over the Responses endpoint with the selected `reasoning.effort` (`low` by default), and its
description replaces the image part inline. The Anthropic path uses the Messages endpoint with its
own thinking-budget mapping and ignores this OpenAI-specific setting.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add model-dependent support and clamping caveats to every guide.

The shared reasoning ladder is constrained by the selected provider and model. The Dashboard also clamps persisted values when a model does not advertise the selected level. Add this caveat next to the provider-specific transport description in every guide.

  • docs-site/src/content/docs/guides/sidecars.md#L79-L82: add the provider/model support and Dashboard clamping caveat.
  • docs-site/src/content/docs/ja/guides/sidecars.md#L78-L81: add the equivalent Japanese caveat.
  • docs-site/src/content/docs/ko/guides/sidecars.md#L79-L82: add the equivalent Korean caveat.
  • docs-site/src/content/docs/ru/guides/sidecars.md#L90-L93: add the equivalent Russian caveat.
  • docs-site/src/content/docs/zh-cn/guides/sidecars.md#L72-L74: add the equivalent Chinese caveat.

As per path instructions, do not imply that advertised reasoning levels are universally supported.

📍 Affects 5 files
  • docs-site/src/content/docs/guides/sidecars.md#L79-L82 (this comment)
  • docs-site/src/content/docs/ja/guides/sidecars.md#L78-L81
  • docs-site/src/content/docs/ko/guides/sidecars.md#L79-L82
  • docs-site/src/content/docs/ru/guides/sidecars.md#L90-L93
  • docs-site/src/content/docs/zh-cn/guides/sidecars.md#L72-L74
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-site/src/content/docs/guides/sidecars.md` around lines 79 - 82, Add a
caveat after each provider-specific transport description explaining that the
reasoning ladder support is constrained by the selected provider and model, and
that the Dashboard clamps persisted values when a model does not advertise the
selected reasoning level. This caveat must be added at the following locations
with equivalent translations or localized versions: English version in
docs-site/src/content/docs/guides/sidecars.md at lines 79-82 (anchor), Japanese
version in docs-site/src/content/docs/ja/guides/sidecars.md at lines 78-81,
Korean version in docs-site/src/content/docs/ko/guides/sidecars.md at lines
79-82, Russian version in docs-site/src/content/docs/ru/guides/sidecars.md at
lines 90-93, and Simplified Chinese version in
docs-site/src/content/docs/zh-cn/guides/sidecars.md at lines 72-74. Ensure the
caveat does not imply that advertised reasoning levels are universally supported
across all models or providers.

Source: Path instructions

Comment thread src/config.ts
Comment on lines +1657 to +1662
sanitizeVisionSidecarForLoad(parsed);
const result = configSchema.safeParse(parsed);
if (result.success) {
const config = normalizeApiKeyIds(result.data as OcxConfig);
warnDegradedStreamMode(parsed, config);
warnDegradedVisionReasoning(parsed, config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve the raw reasoning value before sanitization.

sanitizeVisionSidecarForLoad deletes the invalid value in place at Line 1340. The later warnDegradedVisionReasoning(parsed, config) call receives the same object at Lines 1662 and 1683. Its raw value is already undefined, so invalid persisted reasoning never produces the intended warning.

Copy the parsed object before sanitization, or return the removed value from the sanitizer, and pass the untouched data to both warning calls.

Proposed fix
 const parsed = JSON.parse(raw);
+const rawParsed = structuredClone(parsed);
 sanitizeRetryOn429ForLoad(parsed);
 sanitizeVisionSidecarForLoad(parsed);

 ...
-      warnDegradedVisionReasoning(parsed, config);
+      warnDegradedVisionReasoning(rawParsed, config);

 ...
-      warnDegradedVisionReasoning(parsed, config);
+      warnDegradedVisionReasoning(rawParsed, config);

Also applies to: 1327-1353, 1683-1683

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(detect-child-process-typescript)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/config.ts` around lines 1657 - 1662, Preserve an untouched copy of parsed
before sanitizeVisionSidecarForLoad mutates it, then pass that original data to
both warnDegradedVisionReasoning calls while continuing to use the sanitized
parsed object for schema parsing and other behavior. Update the relevant load
paths around sanitizeVisionSidecarForLoad and both warning-call sites without
changing the sanitizer’s existing validation behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant