Skip to content

feat(models-info): let the modelsInfoUrl catalog hide text-only / unmatched models - #68

Merged
stephane-segning merged 2 commits into
mainfrom
claude/hide-text-models-info-98692f
Jul 28, 2026
Merged

feat(models-info): let the modelsInfoUrl catalog hide text-only / unmatched models#68
stephane-segning merged 2 commits into
mainfrom
claude/hide-text-models-info-98692f

Conversation

@stephane-segning

Copy link
Copy Markdown
Contributor

1. Summary

This PR changes:

  • Adds a new opt-in meta.modelsInfoHideTextOnly provider option to @vymalo/opencode-models-info.
  • When true, the modelsInfoUrl catalog becomes authoritative for which models exist, not just their metadata: a model is deleted from provider.models outright (instead of being enriched) if the catalog reports it as text-in/text-out only, or if the catalog has no entry for it at all.
  • Updates docs (docs/models-info.md, packages/opencode-models-info/README.md, CLAUDE.md/AGENTS.md composition-contract section) and CHANGELOG.md.

It solves:

  • A user question in this session: "Do we have a way of hiding a text model when using model info?" — followed up with "I want the model info endpoint [to] take total precedence over the /models endpoint. Is it possible?" No existing mechanism let the richer modelsInfoUrl catalog prune or override membership; the plugin only ever merged metadata onto models that already existed.

2. Intent

The intent of this PR is:

Let a richer, OpenRouter-shaped metadata endpoint be the single source of truth for which models are offered — e.g. hiding chat-only models when only multimodal ones should appear in OpenCode's picker, or overriding a provider's own /v1/models discovery (used by @vymalo/opencode-oauth2) entirely. See docs/models-info.md#hiding-text-only-models--catalog-authoritative-membership for the full design writeup (source of truth for this change).


3. Scope

In Scope

  • New meta.modelsInfoHideTextOnly boolean option (default false), parsed in config.ts.
  • isTextOnlyModality() helper in mapping.ts.
  • Deletion logic in plugin.ts's enrichProvider: drops a matched-but-text-only model, and (when the flag is on) drops any model the catalog doesn't mention at all.
  • New log events models_info_model_hidden_text_only and models_info_model_hidden_unmatched (debug), plus hiddenCount on the models_info_enriched summary event.
  • Tests (config.test.ts, mapping.test.ts, plugin.test.ts) and docs/README/CHANGELOG updates.

Out of Scope

  • Synthesizing new provider.models entries for catalog models that discovery/config never listed (only pruning existing entries is supported — see the "Config shape" discussion in the PR description below).
  • Any change to the default (flag-off) enrichment behavior — fully backward compatible.

4. Verification

I verified this change by:

  • Running automated tests
  • Checking logs
  • Running manual tests
  • Checking metrics
  • Testing error cases
  • Testing permissions/security behavior
  • Testing rollback or failure behavior, if relevant

Commands run:

pnpm --filter @vymalo/opencode-models-info test
pnpm -r build
pnpm -r typecheck
pnpm coverage
pnpm lint
pnpm format:check

Results:

@vymalo/opencode-models-info: Test Files 6 passed (6), Tests 78 passed (78)
pnpm -r build: all 10 buildable packages/apps succeeded
pnpm -r typecheck: all packages succeeded
pnpm coverage: all packages passed their per-package thresholds (models-info: 82.59% stmts / 79.57% branches)
pnpm lint / pnpm format:check: no issues (239 files checked)

5. Screenshots / Evidence

Add evidence here:

  • Screenshot: N/A (backend plugin logic, no UI)
  • Logs: new models_info_model_hidden_text_only / models_info_model_hidden_unmatched debug events, exercised in plugin.test.ts
  • Metrics: N/A
  • Recording: N/A

6. Risk Assessment

Risk level:

  • Low

Potential risks:

  • A user enabling modelsInfoHideTextOnly without realizing "unmatched → dropped" is part of the semantics could lose a hand-configured model that the metadata endpoint simply doesn't know about.
  • The flag makes deletion a hard, silent-by-default (debug-level log only) operation — no dry-run mode.

Mitigation:

  • Opt-in, off by default; fully documented (README "Hiding text-only models" section spells out both deletion cases explicitly) and covered by tests for both the "flag off" and "flag on" paths.
  • Deletions are logged at debug (models_info_model_hidden_text_only / models_info_model_hidden_unmatched) and rolled up into hiddenCount on the models_info_enriched summary event, so the behavior is diagnosable via --log-level DEBUG.

7. AI Usage Declaration

AI was used for:

  • Understanding existing code
  • Generating code
  • Generating tests
  • Drafting documentation
  • Refactoring
  • Reviewing the diff
  • Not used

Human verification:

  • I understand every meaningful change in this PR
  • I checked generated code manually
  • I checked generated tests manually
  • I removed unsupported AI assumptions
  • I accept responsibility for this PR

8. Reviewer Focus

Please focus your review on:

  • Correctness
  • Architecture
  • Edge cases
  • Security
  • Performance
  • Tests
  • Maintainability
  • Product intent

…ched models

Lets the modelsInfoUrl catalog take total precedence over whatever
populated provider.models first (hand-written config, or oauth2's
/v1/models discovery): with the flag on, a model is deleted outright
if the catalog reports it text-in/text-out only, or if the catalog
has no entry for it at all. Off by default; only ever prunes existing
entries, never invents new ones.

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

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a7cb39d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@github-actions

Copy link
Copy Markdown

✅ AI Governance check passed

This PR declares AI usage, references a source of truth, and provides verification evidence. Thank you.

…esh scheduler

Adds a per-provider scheduler that re-checks modelsInfoUrl on the same
modelsInfoTtlSeconds cadence that already governs cache freshness (no
new config surface), so a long-lived OpenCode process doesn't stay
stuck with whatever the catalog looked like at boot. It's a
cache-warming mechanism for the next config-hook run, not a live
in-session update — no channel exists for that in OpenCode's plugin
API. Wired via config (start/restart) and dispose (stop); timers are
unref()'d so a short CLI invocation is never kept alive by it.

Also refactors enrichProvider's per-model branching into a single
reconcileModel() decision function, and splits loadRecord's fetch
logic into a reusable fetchAndCache() shared with the new refresh path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@stephane-segning
stephane-segning merged commit 63a7069 into main Jul 28, 2026
3 checks passed
@stephane-segning
stephane-segning deleted the claude/hide-text-models-info-98692f branch July 28, 2026 16:03
stephane-segning added a commit that referenced this pull request Jul 28, 2026
Bump all eleven workspace packages to 0.10.0. Needed because npm's
@vymalo/opencode-models-info@0.9.0 was already published on 2026-06-29
(confirmed by pulling the tarball and grepping for
modelsInfoHideTextOnly/reconcileModel/startCacheRefreshSchedulers —
none present), so today's models-info work (#68) and the fast-uri
audit fix (#70), both merged under the still-0.9.0 version line,
could never actually reach npm: publish.yml's own guard silently
skips re-publishing an already-existing version.

CHANGELOG changes: split the mis-filed [0.9.0] "unreleased" entry —
the two models-info bullets and the fast-uri fix move to a new
[0.10.0] — 2026-07-28 section; [0.9.0] is re-dated to 2026-06-29 (the
actual npm publish timestamp) and keeps only what that publish really
contained (devtools/devtools-mcp + docs).

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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