Skip to content

feat(sdk): enumerate provider models of every modality in the model catalog - #4676

Merged
heavy-d merged 3 commits into
mainfrom
feat/sdk-catalog-provider-models
Aug 4, 2026
Merged

feat(sdk): enumerate provider models of every modality in the model catalog#4676
heavy-d merged 3 commits into
mainfrom
feat/sdk-catalog-provider-models

Conversation

@heavy-d

@heavy-d heavy-d commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

The SDK model catalog (/api/sdk/v1/models) built its list from getAllModels, which only enumerates language models from configured providers. Image, TTS, music, ASR, video, and embedding models appeared only when they happened to be in RECOMMENDED_MODELS — an SDK client asking for image_model compatibility got exactly one entry (GPT Image 2) while the web editor's picker, which goes through availableForKind, showed the full provider lists.

Add collectProviderCatalogModels: one pass per configured provider calling each getAvailable*Models once, no task filtering, so text_to_image and image_to_image capable models are both included. Per-list failures degrade to an empty list instead of dropping the provider.

The catalog service merges these into the existing gathering behind a 60s per-user TTL cache. Only the remote provider enumeration is cached — local download state (HF cache scan, download manager) stays fresh on every call, so a finished download still flips to ready_local immediately. Worker-scoped catalogs are unchanged and never enumerate providers.

getAllModels and availableForKind are untouched; existing consumers keep their exact behavior.

…atalog

The SDK model catalog (/api/sdk/v1/models) built its list from getAllModels,
which only enumerates language models from configured providers. Image, TTS,
music, ASR, video, and embedding models appeared only when they happened to be
in RECOMMENDED_MODELS — an SDK client asking for image_model compatibility got
exactly one entry (GPT Image 2) while the web editor's picker, which goes
through availableForKind, showed the full provider lists.

Add collectProviderCatalogModels: one pass per configured provider calling
each getAvailable*Models once, no task filtering, so text_to_image and
image_to_image capable models are both included. Per-list failures degrade to
an empty list instead of dropping the provider.

The catalog service merges these into the existing gathering behind a 60s
per-user TTL cache. Only the remote provider enumeration is cached — local
download state (HF cache scan, download manager) stays fresh on every call, so
a finished download still flips to ready_local immediately. Worker-scoped
catalogs are unchanged and never enumerate providers.

getAllModels and availableForKind are untouched; existing consumers keep
their exact behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 3, 2026 23:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the SDK model catalog endpoint (/api/sdk/v1/models) to include provider-enumerated models for non-LLM modalities (image, TTS, music, ASR, video, embeddings) so SDK consumers see the same breadth of models as the editor’s provider pickers, while keeping provider enumeration behind a short per-user TTL cache.

Changes:

  • Add collectProviderCatalogModels() to enumerate all non-language-model modalities per configured provider (one call per getAvailable*Models per provider, no task filtering).
  • Cache provider enumeration results for 60s per user in getSdkV1ModelCatalog, with an optional injection hook for tests/callers.
  • Add Vitest coverage for inclusion, dedupe behavior, caching, and worker-scope behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
packages/websocket/src/trpc/routers/models.ts Adds collectProviderCatalogModels() to enumerate provider models across modalities for the SDK catalog.
packages/websocket/src/sdk/sdk-model-catalog-service.ts Merges provider-enumerated models into the SDK catalog with a per-user TTL cache and test hook.
packages/websocket/tests/sdk-model-catalog-provider-models.test.ts Adds tests validating provider-enumerated entries, dedupe, caching, injection, and worker-scope behavior.

Comment thread packages/websocket/src/trpc/routers/models.ts
Comment thread packages/websocket/src/sdk/sdk-model-catalog-service.ts
Comment on lines +223 to +227
[availableModels, providerCatalogModels, providerIds] = await Promise.all([
getAllModels(args.userId),
(args.getProviderCatalogModels ?? getCachedProviderCatalogModels)(
args.userId
),
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 4, 2026 00:09
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/websocket/src/sdk/sdk-model-catalog-service.ts:182

  • providerCatalogCache is a process-global Map keyed by userId but entries are never pruned. In a long-lived server handling many users, this can grow unbounded even though values are treated as TTL’d, since expired entries remain resident until overwritten for the same user.
      providerCatalogCache.delete(key);
    }
  }
}

packages/websocket/src/sdk/sdk-model-catalog-service.ts:227

  • This code path ends up re-running provider configuration checks multiple times per request: getAllModels() calls getAvailableProviderIds() internally (models.ts:784), collectProviderCatalogModels() calls it again (models.ts:942), and getSdkV1ModelCatalog() also calls it here to build configuredProviderIds. On instances with many registered providers/secret backends, this adds avoidable latency and load.

Consider fetching providerIds once in getSdkV1ModelCatalog and threading it into provider enumeration (e.g., add an optional providerIds parameter to collectProviderCatalogModels / cache helper), so at least the catalog-specific enumeration doesn’t re-check configuration.

  let providerIds: readonly string[];
  if (args.query.scope === "worker") {
    if (!args.getWorkerModels) {
      throw new SdkModelCatalogServiceError(
        "Worker model catalogs are not available through this server."

Copilot AI review requested due to automatic review settings August 4, 2026 00:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/websocket/src/sdk/sdk-model-catalog-service.ts:240

  • getSdkV1ModelCatalog now calls getAvailableProviderIds directly, but collectProviderCatalogModels (invoked via getCachedProviderCatalogModels) also calls getAvailableProviderIds internally, and getAllModels does the same. That means each catalog request can re-run provider configuration checks multiple times and can (rarely) observe different provider-id snapshots inside one response.

Consider fetching providerIds once in getSdkV1ModelCatalog and threading that list into the provider-catalog enumeration (and ideally into getAllModels) so the request uses a consistent set and avoids repeated secret/config checks.

    [availableModels, providerCatalogModels, providerIds] = await Promise.all([
      getAllModels(args.userId),
      (args.getProviderCatalogModels ?? getCachedProviderCatalogModels)(
        args.userId
      ),
      getAvailableProviderIds(args.userId)
    ]);

@heavy-d
heavy-d merged commit f462400 into main Aug 4, 2026
25 checks passed
@heavy-d
heavy-d deleted the feat/sdk-catalog-provider-models branch August 4, 2026 00:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants