refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

refactor(web): resolve language model capabilities from models.dev - #1372

Merged
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities
Jun 27, 2026
Merged

refactor(web): resolve language model capabilities from models.dev#1372
whoisthey merged 13 commits into
mainfrom
whoisthey/language-model-input-modalities

Conversation

@whoisthey

@whoistheywhoisthey commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Lays the groundwork for chat file attachments by teaching Sourcebot which inputs a configured language model can accept, resolved automatically from the models.dev catalog (the same catalog that already backs context-window resolution).

What this adds

  • Automatic capability resolution.resolveModelCapabilities (packages/web/src/features/chat/modelCapabilities.server.ts) looks a model's modalities.input up in the models.dev catalog and partitions it into two buckets:
    • inputModalities (text | image | audio | video) — perceptual channels the model encodes natively.
    • supportedDocumentTypes (pdf) — rich compound container formats providers decompose server-side. models.dev folds pdf into modalities.input; we split it back out, since a document is not a modality.
  • Shared catalog module. The catalog fetch/cache plumbing (TTL, negative cache, stale-while-revalidate, in-flight dedupe, provider-id overrides) lives in modelsDevCatalog.server.ts and backs both context-window and capability resolution off a single cached fetch.
  • Both resolved fields are exposed on the client-safe LanguageModelInfo (via getConfiguredLanguageModelsInfo and the MCP ask path).

This is pure capability plumbing. It adds no attachment UI (future work).

Behavior

  • Catalogued models light up their real capabilities automatically, with no config.json changes.
  • Uncatalogued models (e.g. openai-compatible / self-hosted endpoints) fall back to text-only with no document support: the model stays fully usable for normal chat, and richer attachments stay gated off until support can be positively confirmed.

Add an optional `inputModalities` declaration to language model config and
expose a resolved capability set to the client.
- Schema: add optional `inputModalities` (`text` | `image` | `pdf`) to every
provider definition in `schemas/v3/languageModel.json` and regenerate the
schema types/snippets.
- Add a fail-closed `resolveModelInputModalities` resolver that defaults to
text-only when a model does not declare its input modalities.
- Expose the resolved `inputModalities` on the client-safe `LanguageModelInfo`
(populated via `getConfiguredLanguageModelsInfo` and the MCP ask path).
This is groundwork for chat file attachments. It adds no attachment UI and no
live provider capability probing yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitaiBot commented Jun 26, 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

Language-model capability fields were added to schema and type contracts, mirrored in generated JSON/docs, and propagated into chat metadata plus MCP askCodebase/server payloads. The web code resolves omitted modality and document-type values to text-only and no-document defaults.

Changes

Type contracts

Layer / File(s)Summary
Provider model interfaces
packages/schemas/src/v3/index.type.ts, packages/schemas/src/v3/languageModel.type.ts
Provider language-model interfaces add optional inputModalities and supportedDocumentTypes fields across the supported provider types.

Schema contracts

Layer / File(s)Summary
Schema definitions
packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/languageModel.schema.ts
Matching JSON-schema definitions add the same optional fields and fail-closed descriptions in both base definitions and oneOf provider variants.

Published artifacts

Layer / File(s)Summary
Generated schema and docs mirrors
schemas/v3/languageModel.json, docs/snippets/schemas/v3/index.schema.mdx, docs/snippets/schemas/v3/languageModel.schema.mdx, CHANGELOG.md
The generated JSON schema, docs snippets, and changelog mirror the new capability fields and defaults.

Capability helpers and tooling

Layer / File(s)Summary
Chat capability metadata
packages/web/src/features/chat/types.ts, packages/web/src/features/chat/modelCapabilities.ts, packages/web/src/features/chat/utils.ts
Chat metadata types add explicit modality and document-type fields with defaults, capability resolvers apply fail-closed behavior, and getLanguageModelKey accepts only identifying fields.

Payload wiring

Layer / File(s)Summary
Server payload enrichment
packages/web/src/features/chat/utils.server.ts, packages/web/src/ee/features/mcp/askCodebase.ts
Server-side language-model mappings and the MCP AskCodebaseResult.languageModel payload now include resolved capability fields.

Sequence Diagram(s)

sequenceDiagram
participant modelCapabilities as "packages/web/src/features/chat/modelCapabilities.ts"
participant utilsServer as "packages/web/src/features/chat/utils.server.ts"
participant askCodebase as "packages/web/src/ee/features/mcp/askCodebase.ts"
utilsServer->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
utilsServer->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelInputModalities(languageModelConfig)
askCodebase->>modelCapabilities: resolveModelSupportedDocumentTypes(languageModelConfig)
utilsServer->>utilsServer: add inputModalities and supportedDocumentTypes to LanguageModelInfo
askCodebase->>askCodebase: attach inputModalities and supportedDocumentTypes to AskCodebaseResult.languageModel
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.
Title check✅ PassedThe title clearly reflects the main change: resolving language model capabilities from models.dev.
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/language-model-input-modalities

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.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟢 ReadyView PreviewJun 26, 2026, 4:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlifyBot commented Jun 26, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

ProjectStatusPreviewUpdated (UTC)
sourcebot🟡 BuildingJun 26, 2026, 3:58 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

inputModalities now only enumerates true perceptual channels
(text | image | audio | video). Document/container formats like PDF
move to a separate fail-closed `supportedDocumentTypes` field, since
PDF is not a model modality but a format providers decompose into
text/image internally.
Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the inputModalities / supportedDocumentTypes descriptions to
remove the implication that omitting supportedDocumentTypes blocks all
non-text attachments. Clarify the taxonomy: single-medium files
(images, audio, video) and plain-text files (.txt, .md) are governed by
inputModalities; supportedDocumentTypes only gates rich compound
container formats like PDF.
Co-authored-by: Cursor <cursoragent@cursor.com>
whoistheyand others added 2 commits June 26, 2026 10:25
LanguageModelInfo now has required inputModalities/supportedDocumentTypes,
so a raw LanguageModel config (where those are optional) is no longer
assignable to it. getLanguageModelKey only reads provider/model/displayName,
so type its parameter as that Pick subset, letting both LanguageModel and
LanguageModelInfo be keyed. Fixes the docker build type check.
Co-authored-by: Cursor <cursoragent@cursor.com>
Two dev-experience fixes for the stale-build-output footgun:
- schemas watch now runs `yarn build` (generate + tsc) instead of
generate-only, so editing a schema JSON during `yarn dev` refreshes
dist (both the .d.ts types and the runtime index.schema.js used by
ajv), not just the generated source.
- web tsconfig maps @sourcebot/schemas/v3|v2/* to the package source,
so type-checking and the IDE read committed source directly instead
of stale built .d.ts. Web only imports .type files (erased at
compile), so there is no bundling/runtime impact.
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown
Contributor

License Audit

⚠️Status: PASS

MetricCount
Total packages2129
Resolved (non-standard)11
Unresolved0
Strong copyleft0
Weak copyleft39

Weak Copyleft Packages (informational)

PackageVersionLicense
@img/sharp-libvips-darwin-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-darwin-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.0.5LGPL-3.0-or-later
@img/sharp-libvips-linux-arm1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-ppc641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-riscv641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-s390x1.2.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linux-x641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-arm641.2.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.0.4LGPL-3.0-or-later
@img/sharp-libvips-linuxmusl-x641.2.4LGPL-3.0-or-later
@img/sharp-wasm320.33.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-wasm320.34.5Apache-2.0 AND LGPL-3.0-or-later AND MIT
@img/sharp-win32-arm640.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-ia320.34.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.33.5Apache-2.0 AND LGPL-3.0-or-later
@img/sharp-win32-x640.34.5Apache-2.0 AND LGPL-3.0-or-later
axe-core4.10.3MPL-2.0
dompurify3.4.11(MPL-2.0 OR Apache-2.0)
lightningcss1.32.0MPL-2.0
lightningcss-android-arm641.32.0MPL-2.0
lightningcss-darwin-arm641.32.0MPL-2.0
lightningcss-darwin-x641.32.0MPL-2.0
lightningcss-freebsd-x641.32.0MPL-2.0
lightningcss-linux-arm-gnueabihf1.32.0MPL-2.0
lightningcss-linux-arm64-gnu1.32.0MPL-2.0
lightningcss-linux-arm64-musl1.32.0MPL-2.0
lightningcss-linux-x64-gnu1.32.0MPL-2.0
lightningcss-linux-x64-musl1.32.0MPL-2.0
lightningcss-win32-arm64-msvc1.32.0MPL-2.0
lightningcss-win32-x64-msvc1.32.0MPL-2.0
Resolved Packages (11)
PackageVersionOriginalResolvedSource
@react-grab/cli0.1.23UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/cli0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
@react-grab/mcp0.1.29UNKNOWNMITGitHub repo (github.com/aidenybai/react-grab README + LICENSE)
codemirror-lang-elixir4.0.0UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
element-source0.0.3UNKNOWNMITGitHub repo (github.com/aidenybai/element-source LICENSE)
lezer-elixir1.1.2UNKNOWNApache-2.0npm registry (registry.npmjs.org top-level license field)
map-stream0.1.0UNKNOWNMITnpm registry (registry.npmjs.org top-level license field)
memorystream0.3.1UNKNOWNMITnpm registry (licenses array object [{type:MIT}])
valid-url1.0.9UNKNOWNMITGitHub repo (raw LICENSE file github.com/ogt/valid-url)
pause-stream0.0.11["MIT","Apache2"]MITextracted from object (license array ["MIT","Apache2"])
posthog-js1.369.0SEE LICENSE IN LICENSEMITnpm registry (registry.npmjs.org top-level license field)

….json
Re-source language model input-modality / document capabilities from the
models.dev catalog instead of hand-declared config.json fields, aligning
with the move to de-emphasize on-disk config in favor of automatic
resolution (the same catalog already backs context-window resolution).
- Revert the inputModalities/supportedDocumentTypes additions to
schemas/v3/languageModel.json and all regenerated artifacts; capabilities
are no longer declared in config.json.
- Extract the shared models.dev catalog plumbing (fetch/TTL/negative-cache/
stale-while-revalidate/provider-id overrides) into modelsDevCatalog.server.ts,
now consumed by both context-window and capability resolution.
- Add models.dev-backed resolveModelCapabilities (modelCapabilities.server.ts),
partitioning the catalog's modalities.input list into Sourcebot's
inputModalities (channels) and supportedDocumentTypes (containers); falls back
to text-only for uncatalogued / self-hosted models.
The client-safe LanguageModelInfo contract is unchanged; only the resolution
backend moved.
Co-authored-by: Cursor <cursoragent@cursor.com>
@whoistheywhoisthey changed the title feat(web): add language model inputModalities capability plumbingrefactor(web): resolve language model capabilities from models.devJun 27, 2026
jsourcebot
jsourcebot previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
brendan-kellam
brendan-kellam previously approved these changes Jun 27, 2026
Comment threadpackages/web/src/features/chat/types.ts Outdated
@whoisthey
whoisthey dismissed stale reviews from brendan-kellam and jsourcebot via bf79260June 27, 2026 19:57
Sign up for freeto 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.

3 participants

@whoisthey@brendan-kellam@jsourcebot