Skip to content

fix(provider): unify model capability resolution - #2041

Merged
yyhhyyyyyy merged 13 commits into
devfrom
fix/provider-capability-identity
Jul 28, 2026
Merged

fix(provider): unify model capability resolution#2041
yyhhyyyyyy merged 13 commits into
devfrom
fix/provider-capability-identity

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Unify model capability resolution across provider routing, runtime serialization, settings, agent defaults, and renderer controls.

This fixes Kimi K3 requests through New API while establishing a single capability identity and request-policy contract for future models and aggregators.

Root cause

New API correctly routed kimi-k3 through an OpenAI-compatible endpoint, but runtime code later treated the transport as the capability owner and attempted to resolve openai/kimi-k3.

That lost Moonshot's provider-db metadata, converted unknown temperature support into an enabled default, and sent unsupported sampling parameters. Renderer components also resolved capabilities independently, allowing UI controls to disagree with the final HTTP request.

Changes

  • Separate service provider, transport endpoint, and provider-db capability identity.
  • Resolve New API routes in two phases:
    1. derive a narrow family hint for endpoint selection;
    2. resolve the complete capability identity after the endpoint is known.
  • Keep request-facing and catalog-facing model IDs separate.
  • Reject ambiguous cross-provider matches instead of selecting a provider by iteration order.
  • Introduce a shared request policy with passthrough, fixed, and omit modes.
  • Apply Kimi K3 policy consistently:
    • omit temperature;
    • omit top_p;
    • require reasoning;
    • omit legacy thinking.
  • Preserve existing K2 fixed-temperature behavior and unknown-model passthrough compatibility.
  • Serialize effective generation settings once for tracing, streaming, and non-streaming requests.
  • Restore Grok Mini reasoning_effort through the standard AI SDK option.
  • Expose one typed capability snapshot to runtime, settings, agents, and renderer consumers.
  • Make ChatConfig, ChatStatusBar, and ModelConfigDialog consume the same effective wire policy.
  • Preserve stored user values when a control is hidden or fixed.
  • Silently hide generation controls when capability loading fails while retaining internal diagnostics and stale-query protection.
  • Replace repeated derived model scans with a compact O(1) route metadata index.
  • Refresh generated provider and ACP registry resources.

Summary by CodeRabbit

  • New Features
    • Added a unified “model capability identity” flow with a single per-request capability snapshot powering routing, generation defaults, and reasoning-effort behavior.
    • Model sampling controls (temperature/Top P) and reasoning settings now follow policy consistently, including policy-fixed UI states and hints.
  • Bug Fixes
    • Prevented unsupported/omitted sampling and reasoning fields from being sent on requests (including K3 and compatible Grok variants).
    • Improved capability-load failure handling by hiding affected controls silently while keeping configuration safe.
  • Documentation
    • Added/updated architecture/spec/task documentation for the new capability-identity runtime contracts.
  • Tests
    • Expanded end-to-end coverage for identity resolution, policy-to-wire correctness, and renderer controls.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR centralizes model capability identity and request-policy resolution in the main process, propagates request-local capability snapshots through runtime generation, updates renderer controls, refreshes model metadata and registries, and adds identity, policy, wire, routing, and UI tests.

Changes

Model capability identity and request policy

Layer / File(s) Summary
Identity and capability contracts
src/shared/*, docs/architecture/model-capability-identity/*, docs/features/provider-runtime/spec.md
Defines provider, transport, and catalog identities; capability snapshots; route overrides; and passthrough, fixed, or omitted request policies.
Catalog resolution and provider routing
src/main/provider/capabilityIdentity.ts, src/main/provider/modelCapabilities.ts, src/main/provider/modelConfig.ts, src/main/provider/providerModelHelper.ts, src/main/provider/providers/*
Resolves normalized identities, builds snapshots, adds targeted route metadata reads, and threads route decisions through provider operations.
Request-local runtime facts and SDK serialization
src/main/agent/deepchat/runtime/*, src/main/provider/aiSdk/*
Reuses resolved model facts for generation settings, compaction, input capabilities, streaming, and effective request serialization.
Renderer capability controls
src/renderer/src/composables/*, src/renderer/src/components/**/*
Projects snapshot policies into loading, hidden, editable, and fixed controls while preserving stored configuration intent.
Catalog and registry refreshes
resources/model-db/providers.json, resources/acp-registry/registry.json
Updates model metadata, reasoning fields, limits, costs, modalities, and ACP distribution versions.
Validation coverage
test/main/*, test/renderer/*, test/setup.renderer.ts
Adds coverage for identity precedence, K3 aliases and wire payloads, runtime fact reuse, route metadata reads, renderer lifecycle, policy projections, and stale-request rejection.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Renderer
  participant ModelClient
  participant ProviderSettings
  participant AiSdkProvider
  participant AiSdkRuntime
  Renderer->>ModelClient: request capability snapshot
  ModelClient->>ProviderSettings: forward route override and reasoning
  ProviderSettings->>AiSdkProvider: resolve capability identity
  AiSdkProvider->>AiSdkRuntime: provide snapshot and runtime facts
  AiSdkRuntime->>AiSdkProvider: serialize effective generation options
Loading

Possibly related PRs

Suggested reviewers: zerob13

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.23% 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 is concise and accurately summarizes the main change: unifying provider/model capability resolution.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/provider-capability-identity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 14

🧹 Nitpick comments (8)
src/main/provider/providers/aiSdkProvider.ts (1)

1281-1306: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Extract the duplicated embeddings/dimensions runtime-context builder.

runEmbeddingsWithDecision and the fallback path in runDimensionsWithDecision now construct byte-identical AiSdkRuntimeContext objects (identity resolution, headers, snapshot, trace/header callbacks). A single private helper (e.g. buildEmbeddingRuntimeContext(modelId, decision)) would keep the capability-snapshot wiring in one place as this evolves.

Also applies to: 1367-1392

🤖 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/main/provider/providers/aiSdkProvider.ts` around lines 1281 - 1306,
Extract the duplicated AiSdkRuntimeContext construction from
runEmbeddingsWithDecision and the fallback path in runDimensionsWithDecision
into one private helper, such as buildEmbeddingRuntimeContext(modelId,
decision). Move identity resolution, headers, capability snapshot, trace/header
callbacks, and related runtime flags into the helper, then reuse it from both
call sites while preserving their existing behavior.
src/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts (1)

155-181: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Reuse providerModelFacts for the input-capability lookup too.

compact() now resolves facts once, but the later resolveProviderInputCapabilities(this.deps.providerSettings, state.providerId, state.modelId) call in this method omits them, so it re-runs getModelConfig + getCapabilitySnapshot. turnCoordinator and deepChatLoopRunner pass the facts through; matching that here keeps the "resolve once per turn" invariant and avoids a snapshot recomputation that could disagree with the one used above.

♻️ Pass the resolved facts through
       const { supportsVision, supportsAudioInput } = resolveProviderInputCapabilities(
         this.deps.providerSettings,
         state.providerId,
-        state.modelId
+        state.modelId,
+        providerModelFacts
       )
🤖 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/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts` around lines
155 - 181, Update compact() to pass the already resolved providerModelFacts into
its later resolveProviderInputCapabilities call. Preserve the existing
capability lookup behavior while avoiding a second
getModelConfig/getCapabilitySnapshot resolution and maintaining the
resolve-once-per-turn invariant used by turnCoordinator and deepChatLoopRunner.
src/renderer/src/components/chat/ChatStatusBar.vue (1)

1948-1952: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

topP defaults ignore a fixed request policy while temperature honors it.

Temperature prefers temperaturePolicy.value when fixed, but topP still resolves purely from modelConfig.topP. When the capability snapshot fixes topP, the stored session default diverges from the value shown in the UI (topPInputValue) and from what is sent on the wire. Consider mirroring the temperature branch.

♻️ Suggested symmetry
-    topP: normalizeTopP(modelConfig.topP),
+    topP:
+      capabilities?.requestPolicy.topP?.mode === 'fixed'
+        ? capabilities.requestPolicy.topP.value
+        : normalizeTopP(modelConfig.topP),
🤖 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/renderer/src/components/chat/ChatStatusBar.vue` around lines 1948 - 1952,
Update the topP assignment in the ChatStatusBar configuration flow to honor the
fixed topP request policy before falling back to modelConfig.topP, mirroring the
temperature policy precedence. Reuse the existing topP policy mode/value symbols
and normalize the selected value consistently with the current topP handling.
src/renderer/src/components/settings/ModelConfigDialog.vue (1)

991-1003: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

queueCapabilityRefresh refetches even when nothing changed.

The @blur handler on the model ID input calls this on every blur, and modelClient.getCapabilities bypasses its cache whenever options are passed, so each blur is an unconditional IPC round-trip plus a beginLoading() that blanks the snapshot and flips the controls into the loading skeleton. The currentModelLookupId watcher at Line 1614 already guards with modelCapabilities.identity.value?.requestModelId === nextModelId; consider the same short-circuit here (or only refresh on blur when the id actually changed).

🤖 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/renderer/src/components/settings/ModelConfigDialog.vue` around lines 991
- 1003, Update queueCapabilityRefresh to return early when
modelCapabilities.identity.value?.requestModelId already matches the current
model lookup ID, reusing the same identity comparison as the
currentModelLookupId watcher. Keep the existing open and loading guards, and
only call beginLoading and fetchCapabilities when the model ID has changed.
test/renderer/composables/useChatConfigFields.test.ts (1)

51-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that fixed controls cannot persist updates.

This test verifies the disabled presentation but not the new setValue guard. Invoke temperature?.setValue(...) and assert that the emit spy was not called, so future slider changes cannot overwrite a policy-fixed value.

🤖 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 `@test/renderer/composables/useChatConfigFields.test.ts` around lines 51 - 60,
Extend the fixed-mode test around createFields and the temperature field to
invoke temperature?.setValue(...) with a different value, then assert the emit
spy was not called. Keep the existing disabled, hint, and getValue assertions,
and verify the setValue guard prevents policy-fixed controls from persisting
updates.
test/main/provider/aiSdkRuntime.test.ts (1)

2135-2150: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Snapshot is internally inconsistent: effort-mode portrait with supportsReasoningEffort: false.

The helper defaults supportsReasoningEffort to false, but this override supplies an effort-mode reasoningPortrait. Real snapshots derive that flag from the portrait (see buildResolvedCapabilitySnapshot), so this fixture can't occur in production and may mask a regression in effort handling. Add supportsReasoningEffort: true, reasoningEffortDefault: 'max' as in the non-streaming counterpart at Line 2072.

🤖 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 `@test/main/provider/aiSdkRuntime.test.ts` around lines 2135 - 2150, Update the
capability snapshot fixture for the effort-mode reasoningPortrait to explicitly
set supportsReasoningEffort: true and reasoningEffortDefault: 'max', matching
the non-streaming counterpart and keeping the snapshot internally consistent.
test/renderer/composables/useModelCapabilities.test.ts (1)

121-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Nit: temperatureCapability: null is likely not a producible value.

buildResolvedCapabilitySnapshot sets temperatureCapability from the catalog, where "unknown" is undefined, not null. The Record<string, unknown> overrides parameter hides the mismatch. Using undefined keeps these fixtures faithful.

Also applies to: 153-182

🤖 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 `@test/renderer/composables/useModelCapabilities.test.ts` around lines 121 -
136, Update the capability fixtures in the tests around the successful
unknown-temperature case and the additionally referenced cases to use
temperatureCapability: undefined instead of null, matching the catalog value
produced by buildResolvedCapabilitySnapshot. Remove any type override or fixture
typing that masks this mismatch while preserving the existing assertions and
test behavior.
src/main/provider/settings.ts (1)

601-688: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Each capability getter re-resolves a full snapshot; consider memoizing.

getCapabilityProviderId, supportsReasoningCapability, getReasoningPortrait, getThinkingBudgetRange, supportsSearchCapability, getTemperatureCapability, supportsTemperatureControl, getSearchDefaults, supportsAudioInputCapability, supportsReasoningEffortCapability, getReasoningEffortDefault, supportsVerbosityCapability, getVerbosityDefault each call getCapabilitySnapshot, which runs getModelRouteConfig + getProviderModelRouteMetadata (store/DB read) + resolveCapabilityIdentity (catalog scans). Previously these were direct modelCapabilities.* lookups. Any caller touching several getters for the same (providerId, modelId) now pays that resolution repeatedly.

The runtime paths were updated to thread a single snapshot, but these port methods stay on hot paths (e.g. getDbProviderModels at Line 1200 calls supportsReasoningCapability per model). A small keyed memo invalidated alongside invalidateProviderModelsCache / setModelConfig would remove the fan-out.

🤖 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/main/provider/settings.ts` around lines 601 - 688, Memoize capability
snapshots keyed by the `(providerId, modelId)` pair so the listed capability
getters reuse one result instead of repeatedly calling `getCapabilitySnapshot`.
Add a small cache around `getCapabilitySnapshot` or the shared getter path, and
clear it wherever `invalidateProviderModelsCache` and `setModelConfig`
invalidate model configuration, preserving refreshed results after configuration
changes.
🤖 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 `@resources/model-db/providers.json`:
- Around line 269258-269286: Add the missing cost block to the claude-opus-5
provider record, mirroring the full pricing values from the equivalent
anthropic/claude-opus-5 entry. Keep the existing capabilities and model metadata
unchanged so cost estimation uses the published rates.
- Around line 242069-242072: Update the limit.output values for the newly added
model entries in providers.json, rather than mirroring limit.context. Set each
model’s output limit to its concrete provider API max_output_tokens or
generation limit, including qwen3.5-122b-a10b, qwen3-coder-next,
gemini-3-flash-preview, claude-opus-4-6, doubao-seed-2-0-* variants, and
cc-glm-5.1.
- Around line 242492-242586: Update the reasoning defaults in the gpt-5.4-high
and gpt-5.4-low entries so each tier explicitly uses its corresponding default
effort/path: high for gpt-5.4-high and low for gpt-5.4-low. Preserve their
shared limits, costs, supported options, and other configuration.

In `@src/main/provider/aiSdk/providerOptionsMapper.ts`:
- Around line 264-275: Update the DashScope reasoning block in the provider
options mapping so `reasoningEnabled` with a supported reasoning portrait still
sets `config.enable_thinking`, while an explicit `modelConfig.thinkingBudget`
can set `config.thinking_budget` even when `reasoningPortrait` is unresolved.
Keep portrait-based default budget resolution conditional on the portrait being
available.

In `@src/main/provider/aiSdk/runtime.ts`:
- Around line 795-821: Update resolveEffectiveGenerationRequest so an undefined
requestedTemperature falls back to modelConfig.temperature before applying
requestPolicy.temperature. Preserve explicit caller-provided temperatures and
ensure the resolved value is still used to populate samplingOptions.

In `@src/main/provider/capabilityIdentity.ts`:
- Around line 111-162: Update getOwnerProviderIds so the xAI provider check also
matches the normalized “x ai” owner form alongside “xai” and “grok”, allowing
hyphen-normalized x-ai values to resolve to the xai provider.

In `@src/main/provider/providerModelHelper.ts`:
- Around line 282-285: Update the non-`new-api` branch of the `type` resolution
in `getProviderModelRouteMetadata` to use model-first precedence, matching
`applyResolvedModelConfig`: prefer the stored model’s defined type and fall back
to `config.type` only when it is absent. Keep the existing `new-api` resolution
through `resolveNewApiEffectiveModelType` unchanged.

In `@src/main/provider/routes.ts`:
- Around line 650-665: Align the capabilities response in the handler using
modelsGetCapabilitiesRoute with ModelCapabilitiesSchema: omit the snapshot’s
internal identity and requestPolicy fields before parsing, unless those fields
are intentionally part of the public contract, in which case explicitly add them
to the response schema. Preserve the existing temperatureCapability null
fallback.

In `@src/renderer/src/components/settings/ModelConfigDialog.vue`:
- Around line 1614-1629: The currentModelLookupId watcher calls
modelCapabilities.beginLoading() without guaranteeing a subsequent capability
fetch, leaving the dialog stuck loading when no blur occurs. Update this watcher
to queue or trigger the composable’s refresh/load operation after the model ID
changes, while preserving clear() for an empty ID and the existing early-return
conditions.

In `@src/shared/modelId.ts`:
- Around line 14-20: Update getDottedProviderUnqualifiedModelId so it does not
identify the model segment using the first hyphenated segment, which incorrectly
preserves hyphenated provider prefixes such as meta-llama. Use the established
known-provider prefix list or a reliable model-ID token heuristic to strip
provider prefixes while preserving the model identifier for both hyphenated and
non-hyphenated providers.

In `@test/main/provider/aiSdkReasoningWire.test.ts`:
- Around line 15-27: The captureRequestBody helper’s exact single-call assertion
is nondeterministic because retryable failures may invoke fetch multiple times.
Replace fetchMock’s toHaveBeenCalledTimes(1) assertion with a nonzero-call
assertion while continuing to inspect mock.calls[0], or configure the relevant
wire-test generateText path to use maxRetries: 0 where supported.

In `@test/renderer/components/ModelConfigDialog.test.ts`:
- Around line 62-73: Update createCapabilityResult in
test/renderer/components/ModelConfigDialog.test.ts (lines 62-73) and the
getCapabilities mock in test/renderer/components/ChatStatusBar.test.ts (lines
481-516) to distinguish an omitted temperatureCapability from one explicitly set
to undefined: use a property-presence check for both supportsTemperatureControl
and temperatureCapability, defaulting to true only when the property is absent.

In `@test/renderer/composables/useModelCapabilities.test.ts`:
- Around line 138-151: Align the fixture in the test around useModelCapabilities
with the main-process contract by using temperatureCapability: false together
with a served temperature policy of mode "omit", and assert the resolved
temperature state is hidden. Update the test description to reflect that it
verifies capability-derived omission rather than passthrough-policy handling.

In `@test/setup.renderer.ts`:
- Around line 14-38: Update createDefaultReasoningCapabilities to match the
catalog expectations for its default OpenAI gpt-5.4 identity: mark it
catalog-matched, populate catalogModelId with the resolved model ID, set
supportsSearch to true, and provide the corresponding searchDefaults. Preserve
the existing behavior for other capability fields and explicitly verify whether
non-default provider/model inputs should retain their current fallback values.

---

Nitpick comments:
In `@src/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts`:
- Around line 155-181: Update compact() to pass the already resolved
providerModelFacts into its later resolveProviderInputCapabilities call.
Preserve the existing capability lookup behavior while avoiding a second
getModelConfig/getCapabilitySnapshot resolution and maintaining the
resolve-once-per-turn invariant used by turnCoordinator and deepChatLoopRunner.

In `@src/main/provider/providers/aiSdkProvider.ts`:
- Around line 1281-1306: Extract the duplicated AiSdkRuntimeContext construction
from runEmbeddingsWithDecision and the fallback path in
runDimensionsWithDecision into one private helper, such as
buildEmbeddingRuntimeContext(modelId, decision). Move identity resolution,
headers, capability snapshot, trace/header callbacks, and related runtime flags
into the helper, then reuse it from both call sites while preserving their
existing behavior.

In `@src/main/provider/settings.ts`:
- Around line 601-688: Memoize capability snapshots keyed by the `(providerId,
modelId)` pair so the listed capability getters reuse one result instead of
repeatedly calling `getCapabilitySnapshot`. Add a small cache around
`getCapabilitySnapshot` or the shared getter path, and clear it wherever
`invalidateProviderModelsCache` and `setModelConfig` invalidate model
configuration, preserving refreshed results after configuration changes.

In `@src/renderer/src/components/chat/ChatStatusBar.vue`:
- Around line 1948-1952: Update the topP assignment in the ChatStatusBar
configuration flow to honor the fixed topP request policy before falling back to
modelConfig.topP, mirroring the temperature policy precedence. Reuse the
existing topP policy mode/value symbols and normalize the selected value
consistently with the current topP handling.

In `@src/renderer/src/components/settings/ModelConfigDialog.vue`:
- Around line 991-1003: Update queueCapabilityRefresh to return early when
modelCapabilities.identity.value?.requestModelId already matches the current
model lookup ID, reusing the same identity comparison as the
currentModelLookupId watcher. Keep the existing open and loading guards, and
only call beginLoading and fetchCapabilities when the model ID has changed.

In `@test/main/provider/aiSdkRuntime.test.ts`:
- Around line 2135-2150: Update the capability snapshot fixture for the
effort-mode reasoningPortrait to explicitly set supportsReasoningEffort: true
and reasoningEffortDefault: 'max', matching the non-streaming counterpart and
keeping the snapshot internally consistent.

In `@test/renderer/composables/useChatConfigFields.test.ts`:
- Around line 51-60: Extend the fixed-mode test around createFields and the
temperature field to invoke temperature?.setValue(...) with a different value,
then assert the emit spy was not called. Keep the existing disabled, hint, and
getValue assertions, and verify the setValue guard prevents policy-fixed
controls from persisting updates.

In `@test/renderer/composables/useModelCapabilities.test.ts`:
- Around line 121-136: Update the capability fixtures in the tests around the
successful unknown-temperature case and the additionally referenced cases to use
temperatureCapability: undefined instead of null, matching the catalog value
produced by buildResolvedCapabilitySnapshot. Remove any type override or fixture
typing that masks this mismatch while preserving the existing assertions and
test behavior.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 52c3c6c9-7ba1-4b87-a2a3-60e466945ff5

📥 Commits

Reviewing files that changed from the base of the PR and between 13f0c6c and 083bd29.

📒 Files selected for processing (115)
  • docs/architecture/model-capability-identity/plan.md
  • docs/architecture/model-capability-identity/spec.md
  • docs/architecture/model-capability-identity/tasks.md
  • docs/features/provider-runtime/spec.md
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • src/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts
  • src/main/agent/deepchat/runtime/deepChatLoopRunner.ts
  • src/main/agent/deepchat/runtime/generationSettings.ts
  • src/main/agent/deepchat/runtime/providerInputCapabilities.ts
  • src/main/agent/deepchat/runtime/providerModelRuntimeFacts.ts
  • src/main/agent/deepchat/runtime/sessionSettingsCoordinator.ts
  • src/main/agent/deepchat/runtime/turnCoordinator.ts
  • src/main/provider/aiSdk/providerOptionsMapper.ts
  • src/main/provider/aiSdk/runtime.ts
  • src/main/provider/baseProvider.ts
  • src/main/provider/capabilityIdentity.ts
  • src/main/provider/data/settingsTable.ts
  • src/main/provider/modelCapabilities.ts
  • src/main/provider/modelConfig.ts
  • src/main/provider/providerModelHelper.ts
  • src/main/provider/providers/aiSdkProvider.ts
  • src/main/provider/providers/ollamaProvider.ts
  • src/main/provider/routes.ts
  • src/main/provider/settings.ts
  • src/main/provider/settingsDbStores.ts
  • src/renderer/api/ModelClient.ts
  • src/renderer/src/components/ChatConfig.vue
  • src/renderer/src/components/ChatConfig/ConfigSliderField.vue
  • src/renderer/src/components/ChatConfig/types.ts
  • src/renderer/src/components/GenerationParameterLoadingSkeleton.vue
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/renderer/src/composables/useChatConfigFields.ts
  • src/renderer/src/composables/useModelCapabilities.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shared/contracts/domainSchemas.ts
  • src/shared/contracts/routes/models.routes.ts
  • src/shared/model.ts
  • src/shared/modelId.ts
  • src/shared/modelRequestPolicy.ts
  • src/shared/moonshotKimiPolicy.ts
  • src/shared/types/model-capabilities.ts
  • src/shared/types/provider.ts
  • src/types/i18n.d.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
  • test/main/agent/deepchat/runtime/compactionRuntimeCoordinator.test.ts
  • test/main/agent/deepchat/runtime/generationSettings.test.ts
  • test/main/agent/deepchat/runtime/providerInputCapabilities.test.ts
  • test/main/agent/deepchat/runtime/sessionSettingsCoordinator.test.ts
  • test/main/provider/aiSdkProviderOptionsMapper.test.ts
  • test/main/provider/aiSdkReasoningWire.test.ts
  • test/main/provider/aiSdkRuntime.test.ts
  • test/main/provider/basicApiKeyProviders.test.ts
  • test/main/provider/capabilityIdentity.test.ts
  • test/main/provider/data/settingsTable.test.ts
  • test/main/provider/data/settingsTableQuery.test.ts
  • test/main/provider/modelCapabilities.test.ts
  • test/main/provider/modelConfig.test.ts
  • test/main/provider/newApiProvider.test.ts
  • test/main/provider/ollamaProvider.test.ts
  • test/main/provider/providerDbModelConfig.test.ts
  • test/main/provider/providerModelCapabilityMapping.test.ts
  • test/main/provider/providerModelHelper.test.ts
  • test/main/provider/routes.test.ts
  • test/main/routes/contracts.test.ts
  • test/main/session/runtimeIntegration.test.ts
  • test/main/shared/model.test.ts
  • test/main/shared/modelRequestPolicy.test.ts
  • test/main/shared/moonshotKimiPolicy.test.ts
  • test/renderer/components/ChatConfig.test.ts
  • test/renderer/components/ChatStatusBar.test.ts
  • test/renderer/components/ModelConfigDialog.test.ts
  • test/renderer/composables/useChatConfigFields.test.ts
  • test/renderer/composables/useModelCapabilities.test.ts
  • test/setup.renderer.ts
💤 Files with no reviewable changes (25)
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • test/main/shared/moonshotKimiPolicy.test.ts
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/shared/moonshotKimiPolicy.ts
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/types/i18n.d.ts
  • src/renderer/src/i18n/zh-HK/chat.json
  • test/main/shared/model.test.ts
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/main/provider/baseProvider.ts

Comment thread resources/model-db/providers.json
Comment thread resources/model-db/providers.json
Comment thread resources/model-db/providers.json
Comment thread src/main/provider/aiSdk/providerOptionsMapper.ts Outdated
Comment thread src/main/provider/aiSdk/runtime.ts
Comment thread src/shared/modelId.ts
Comment thread test/main/provider/aiSdkReasoningWire.test.ts
Comment thread test/renderer/components/ModelConfigDialog.test.ts Outdated
Comment thread test/renderer/composables/useModelCapabilities.test.ts
Comment thread test/setup.renderer.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@resources/model-db/providers.json`:
- Around line 52897-52928: Update the gpt-4o-mini-transcribe model entry’s
limit.output value from 16000 to 2000, while preserving its context limit and
all other metadata.
- Around line 58986-59017: Update both gpt-4o-transcribe entries in the model
provider definitions so their limit.output value is 2000 instead of 16000, while
preserving the 16000 context limit and all other model metadata.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6fdb4694-d3ee-4241-a7e4-20d1410ca6f3

📥 Commits

Reviewing files that changed from the base of the PR and between 083bd29 and 9fbecc8.

📒 Files selected for processing (27)
  • docs/architecture/model-capability-identity/plan.md
  • docs/architecture/model-capability-identity/spec.md
  • docs/architecture/model-capability-identity/tasks.md
  • resources/acp-registry/registry.json
  • resources/model-db/providers.json
  • src/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts
  • src/main/provider/aiSdk/providerOptionsMapper.ts
  • src/main/provider/capabilityIdentity.ts
  • src/main/provider/modelConfig.ts
  • src/main/provider/providerModelHelper.ts
  • src/main/provider/providers/aiSdkProvider.ts
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/shared/modelId.ts
  • src/shared/types/provider.ts
  • test/main/agent/deepchat/runtime/compactionRuntimeCoordinator.test.ts
  • test/main/provider/aiSdkProviderOptionsMapper.test.ts
  • test/main/provider/aiSdkReasoningWire.test.ts
  • test/main/provider/aiSdkRuntime.test.ts
  • test/main/provider/capabilityIdentity.test.ts
  • test/main/provider/providerDbModelConfig.test.ts
  • test/main/provider/providerModelHelper.test.ts
  • test/main/shared/modelId.test.ts
  • test/renderer/components/ChatStatusBar.test.ts
  • test/renderer/components/ModelConfigDialog.test.ts
  • test/renderer/composables/useChatConfigFields.test.ts
  • test/renderer/composables/useModelCapabilities.test.ts
🚧 Files skipped from review as they are similar to previous changes (21)
  • src/shared/types/provider.ts
  • src/main/agent/deepchat/runtime/compactionRuntimeCoordinator.ts
  • src/shared/modelId.ts
  • test/main/provider/providerDbModelConfig.test.ts
  • test/main/provider/aiSdkReasoningWire.test.ts
  • docs/architecture/model-capability-identity/spec.md
  • test/main/agent/deepchat/runtime/compactionRuntimeCoordinator.test.ts
  • test/renderer/composables/useChatConfigFields.test.ts
  • src/main/provider/capabilityIdentity.ts
  • src/main/provider/aiSdk/providerOptionsMapper.ts
  • docs/architecture/model-capability-identity/tasks.md
  • src/main/provider/providerModelHelper.ts
  • test/renderer/components/ChatStatusBar.test.ts
  • test/main/provider/aiSdkRuntime.test.ts
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • test/renderer/components/ModelConfigDialog.test.ts
  • docs/architecture/model-capability-identity/plan.md
  • test/main/provider/capabilityIdentity.test.ts
  • test/renderer/composables/useModelCapabilities.test.ts
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/main/provider/providers/aiSdkProvider.ts

Comment thread resources/model-db/providers.json
Comment thread resources/model-db/providers.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@resources/model-db/providers.json`:
- Around line 268502-268525: Update the type classification for the
qwen/qwen3.7-flash entry from imageGeneration to chat, preserving its existing
text/image/video input and text output modalities.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4526df06-abb1-4982-8153-561768055d7d

📥 Commits

Reviewing files that changed from the base of the PR and between 9fbecc8 and e72b182.

📒 Files selected for processing (45)
  • resources/model-db/providers.json
  • src/main/agent/deepchat/runtime/turnCoordinator.ts
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/de-DE/settings.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/vi-VN/settings.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shared/contracts/domainSchemas.ts
  • src/types/i18n.d.ts
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
💤 Files with no reviewable changes (21)
  • src/renderer/src/i18n/de-DE/chat.json
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/pl-PL/chat.json
  • src/renderer/src/i18n/vi-VN/chat.json
  • src/renderer/src/i18n/tr-TR/chat.json
  • src/renderer/src/i18n/ms-MY/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/types/i18n.d.ts
  • src/renderer/src/i18n/it-IT/chat.json
  • src/renderer/src/i18n/es-ES/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/id-ID/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
🚧 Files skipped from review as they are similar to previous changes (22)
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/es-ES/settings.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/tr-TR/settings.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/pl-PL/settings.json
  • src/renderer/src/i18n/it-IT/settings.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/shared/contracts/domainSchemas.ts
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/id-ID/settings.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/renderer/src/i18n/ms-MY/settings.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/de-DE/settings.json
  • test/main/agent/deepchat/harness/deepChatAgentHarness.test.ts
  • src/main/agent/deepchat/runtime/turnCoordinator.ts
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/en-US/settings.json

Comment thread resources/model-db/providers.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@src/shared/imageGenerationSettings.ts`:
- Line 106: Update the providerOptionsKey condition in normalizeText to accept
both openai and newapi, preserving the canonical newApi fallback after
normalization. Ensure provider factory values emitted as newApi are classified
correctly.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c8bb710f-3148-42b8-8cf0-9cfefe07f5e2

📥 Commits

Reviewing files that changed from the base of the PR and between d64a619 and 8cb8c7e.

📒 Files selected for processing (7)
  • src/main/provider/aiSdk/providerFactory.ts
  • src/shared/imageGenerationSettings.ts
  • src/shared/videoGenerationSettings.ts
  • test/main/provider/aiSdkProviderFactory.test.ts
  • test/main/provider/aiSdkProviderOptionsMapper.test.ts
  • test/main/provider/aiSdkRuntime.test.ts
  • test/main/provider/aiSdkStreamAdapter.test.ts
💤 Files with no reviewable changes (1)
  • src/shared/videoGenerationSettings.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/main/provider/aiSdkRuntime.test.ts

Comment thread src/shared/imageGenerationSettings.ts
@yyhhyyyyyy
yyhhyyyyyy merged commit b0085a8 into dev Jul 28, 2026
12 checks passed
@yyhhyyyyyy
yyhhyyyyyy deleted the fix/provider-capability-identity branch July 28, 2026 02:48
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.

1 participant