Skip to content

feat(api): discover a provider's models from the provider itself - #652

Draft
jayesh9747 wants to merge 1 commit into
truefoundry:mainfrom
jayesh9747:feat/discover-provider-models
Draft

feat(api): discover a provider's models from the provider itself#652
jayesh9747 wants to merge 1 commit into
truefoundry:mainfrom
jayesh9747:feat/discover-provider-models

Conversation

@jayesh9747

Copy link
Copy Markdown
Contributor

Closes part of #648.

Problem

A well-known provider can only offer the models checked into packages/trueforge/catalog/model-catalog.yaml. google-gemini ships 2 there, against openai's 5 and anthropic's 6, and the file goes stale whenever a provider releases a model. Google's own list endpoint currently reports 40 chat-capable models.

The catalog is also the only source of model properties, which turns a stale list into a silent runtime problem. A model configured without them has no context_length, so resolveCompactionThresholdTokens falls back to DEFAULT_CONTEXT_COMPACTION_THRESHOLD_TOKENS (50k) rather than 80% of the real window:

compaction threshold
with properties (1M context) 838,860 tokens
without 50,000 tokens

That is roughly 17x earlier than it should, with nothing surfaced to the user.

Change

Adds GET /api/v1/settings/model-providers/{name}/discovered-models, which asks a configured provider which models it actually serves, using the stored API key.

  • Gemini uses the native list, which reports inputTokenLimit / outputTokenLimit — so discovered Gemini models arrive with the properties compaction needs.
  • Other providers use the OpenAI-compatible GET /models, which reports ids only. Those models are returned without properties rather than with invented ones.
  • truefoundry resolves its endpoint and token at runtime, so it reports unsupported (501).

The API key is read from the stored manifest and never crosses the wire. Gemini takes it as a query parameter, the compatible shape as a bearer header; both placements are asserted in tests.

Responses: 200 / 404 unknown provider / 501 no adapter / 502 provider unreachable or rejecting.

Verified

Against a local docker compose stack with a real Gemini key:

  • 40 models returned, all 40 carrying token limits
  • gemini-3.8-flashcontext_length: 1048576, max_output_tokens: 65536
  • unknown provider → 404

Notes for review

  • UI is deliberately not included. The settings page talks to ModelCatalogServer, which is defined in @truefoundry/assistant-ui-runtime (external dependency, pinned 0.1.27) and has no discoverModels. Wiring the UI needs an optional method added there first — the same shape as the existing deleteModelProvider?. This PR is the backend half so it can land independently.
  • OpenAPI and SDK were regenerated with pnpm sdk:generate, since CI cannot commit those to a fork PR. pnpm-lock.yaml is unchanged.
  • Only the Gemini path was exercised against a live provider; the OpenAI-compatible path is covered by unit tests but not against a real key.

The shipped catalog is a hand-maintained preset list, so a well-known
provider offers only the models checked into model-catalog.yaml —
google-gemini ships 2 against openai's 5 and anthropic's 6 — and it goes
stale whenever a provider releases a model.

The catalog is also the only source of model properties. A model
configured without them has no context_length, and
resolveCompactionThresholdTokens then falls back to
DEFAULT_CONTEXT_COMPACTION_THRESHOLD_TOKENS (50k) instead of 80% of the
real window. For a 1M-context Gemini model that compacts roughly 17x
earlier than it should, silently.

Add GET /settings/model-providers/{name}/discovered-models, which asks
the provider which models it serves using the stored key. Gemini's
native list reports inputTokenLimit and outputTokenLimit, so discovered
Gemini models carry the properties compaction needs; the remaining
providers use the OpenAI-compatible list, which reports ids only, and
those models are returned without invented limits.

The key is read from the stored manifest and never crosses the wire.
Gemini takes it as a query parameter and the compatible shape as a
bearer header; both are covered by tests.

Refs truefoundry#648

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 62d7821

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@truefoundry/trueforge Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant