Skip to content

feat(core): discover gateway model metadata and request defaults - #53713

Closed
tudstudent wants to merge 11 commits into
anomalyco:devfrom
tudstudent:gateway-model-metadata
Closed

tudstudent wants to merge 11 commits into
anomalyco:devfrom
tudstudent:gateway-model-metadata

Conversation

@tudstudent

@tudstudent tudstudent commented Oct 7, 2026 •

Copy link
Copy Markdown

Issue for this PR

Feature/design discussion: #55354. Related context work: #46574 and #53080. Targets dev (maintainer-retargeted on October 10); this implementation uses the current Core/Schema/Server architecture.

Latest published revision, October 26

Commit fb00e8e1e merges upstream dev at ed74ec82c (OpenCode 2.1.4) and reconciles the gateway integration with current reasoning and compaction code. The separate 32k summary cap is removed, gateway-selected budgets remain enforced, and duplicate upstream functionality has been removed. Linux and Windows x64 baseline builds with web assets completed. The compiled Linux client passed isolated key-login/cold-start discovery and four streaming budget cases against a local gateway fixture. Native Windows execution remains unverified. Older validation entries below are historical

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Gateway users currently need local model definitions to expose model limits and capabilities. This adds opt-in discovery through providers.<id>.settings.modelDiscovery, using the configured provider URL, existing API-key connection or environment credentials, and headers. No per-model definitions or renamed model aliases are required. OpenCode contacts only the configured gateway.

The optional OpenAI-style /models extension carries independent total-context, input and output limits, API endpoints, tools/parallel tools, exact reasoning choices/defaults, input/output modalities, and chosen output-request defaults. These are documented extension fields, not additions to the standard OpenAI model-list contract. Any compatible gateway can implement them; this client change has no LiteLLM dependency. LiteLLM #45023 provides the companion catalog, metadata and serving policy; it is independently useful to HTTP clients and does not need to merge before this PR. Gateways returning only IDs can still provide discovered models, with ordinary compatibility behavior for missing metadata.

A successful catalog is authoritative for that opted-in provider, including an empty catalog. Removed models are unavailable for new parent/subagent requests even with local metadata overrides; reappearing models regain current metadata. In-flight requests retain their snapshot, and unrelated providers retain existing behavior. Failed/malformed polls retain the last valid catalog. Configuration/credential changes invalidate account-scoped metadata; source and refresh-generation guards reject stale concurrent results. Invalid IDs, duplicates and negative limits reject the complete response.

Discovery metadata overrides existing catalog defaults field by field; explicit local metadata remains authoritative for listed models. Advertised Responses is preferred over Chat Completions unless an explicit package overrides the choice. Reasoning choices become variants of the same model ID.

Optional request_defaults output budgets, including budgets by reasoning effort, are distinct from supplier output maxima. Local settings.outputTokenBudget overrides them; known maxima still constrain requests. The effective budget governs normal generation and advance compaction reservation for both parents and subagents. Compaction respects independent input limits and total context after output reservation, preserving the existing estimation buffer. Unknown limits stay unknown.

Initial model reads await plugin activation and one bounded account/configuration-scoped discovery attempt. API-key login waits for that attempt before reporting Connected, and the first read after a cold restart sees the catalog. Failed attempts preserve saved credentials and ordinary providers, log a sanitized warning, and retry periodically.

Public client types were regenerated. specs/v2/model-discovery.md documents configuration, the vendor-neutral wire extension, inventory semantics and budget precedence. This PR is independently useful with any implementing gateway; a corresponding LiteLLM producer change supplies one tested implementation but is not required to merge this client.

How did you verify your code works?

Reproducible repository checks (run tests from their package directories):

bun run check
(cd packages/core && bun test test/plugin/provider-model-discovery.test.ts test/model-resolver.test.ts test/credential.test.ts test/integration.test.ts test/session-model-request.test.ts test/session-model-request-hooks.test.ts test/session-compaction.test.ts test/provider.test.ts test/plugin/provider-azure.test.ts test/plugin/provider-openai.test.ts test/config/provider-options.test.ts)
(cd packages/cli && bun test test/auth.test.ts test/auth-login-choices.test.ts test/auth-form.test.ts)
(cd packages/schema && bun test test/model.test.ts test/contract-hygiene.test.ts)
(cd packages/server && bun test test/model.test.ts)
(cd packages/ai && bun test test/provider/openai-chat.test.ts test/provider/openai-compatible-chat.test.ts)
(cd packages/client && bun run generate)
(cd packages/cli && bun run build --single --skip-install --skip-web-ui)
  • On validated compatibility merge 60121fd77a1f8f6bcf9fcefa462d2b16311924d9 (prior tested feature merge plus upstream v2 at 69219470), canonical lint and all 36 workspace typecheck tasks passed. Selected merged suites passed 134 Core tests, 27 CLI authentication tests, 26 Schema tests, two Server HTTP tests and 99 AI Chat tests. The upstream API-key metadata/request-body fix and Azure credential configuration regressions are included. Public client generation produced no tracked delta, and the Linux CLI built successfully. Compiled isolated API and PTY login fixtures passed immediate/cold-first catalog reads and default reads; authenticated discovery completed before Connected, with zero inference.
  • Earlier feature-revision validation also included compiled Linux/Windows builds. The saved-key correction passed 115 Core regression tests and two HTTP model tests. An isolated compiled API/PTY fixture verified discovery completes before Connected and before the first model read after restart, with one authenticated catalog request per startup and zero inference.
  • Local compiled-client integration passed eleven context/compaction cases and persistent inventory removal/reappearance against an actual gateway implementation and loopback supplier. The same cases passed through the gateway's built official-runtime Docker image. These harnesses are external corroborating evidence; the repository unit/HTTP tests above are self-contained.
  • Short authenticated Responses streams, parent/subagent model selection and tool execution passed against native GPT and a separate Chat-compatible supplier. User-reported Windows execution confirmed a built-in general subagent with its selected model/reasoning. Windows fresh-profile test execution was reported, without a retained explicit PASS transcript.

Large-context policy fixtures use controlled usage counts; they do not prove physical supplier maxima. Native GPT accepted one request with reported 861,654 input and 9 output tokens, while prompts estimated at 995,024 and 1,000,028 input tokens were rejected. Exact maxima and a physical 1,050,000-token subscription window remain unverified; that metadata override was test-only. Independent input limits guide compaction rather than enforcing a separate hard rejection when automatic compaction is disabled. Existing request fitting retains its 1,024-token minimum, and arbitrary request hooks cannot govern an earlier compaction decision; use the typed budget setting for advance reservation.

Additional compiled-client validation on historical head 7f5754e848 (2.0.24 with a custom suffix) loaded the live gateway catalog with separate GPT context/output limits of 872,000/128,000 and low/medium/high/xhigh/max variants. The client opened a copied migrated database, preserving the selected large conversation's exported message array exactly. These catalog and compatibility checks made no supplier inference requests; they do not establish physical context maxima or real-model continuation of every migrated session.

Commit identity correction

The previous head 7f5754e848 corrected author/committer attribution to the contributor's verified GitHub email. Its Git tree is identical to tested revision 60121fd77a; every rewritten commit preserves its original tree, dates, message and merge topology. The validation results below refer to that identical source. GitHub checks rerun because the commit hashes changed.

Upstream compatibility update (2026-10-08)

Head at that update 34a1199c3 includes upstream v2 at 0621ea9d9 (2.0.25). The earlier compatibility merge eb36ad61f combined upstream provider-aware image handling with discovered tool/parallel-tool capabilities and fitted output budgets. On that merged source, canonical lint and all 36 workspace typecheck tasks passed. Selected suites passed 138 Core tests, 27 CLI authentication tests, 26 Schema tests, two Server HTTP tests and 99 AI Chat tests. Public client regeneration produced no additional tracked changes, and the Linux CLI built successfully. An isolated compiled-client catalog fixture passed immediate discovery after key registration and the first catalog read after a cold restart, with zero inference

The subsequent upstream release/TUI merge changed no gateway Core, Schema, Server or AI source. The new wrapped-link regression passed, and canonical lint plus all 36 workspace typecheck tasks passed again on 34a1199c3. The earlier test/build results are evidence for the identical gateway source; a new 2.0.25 binary build and complete test rerun are not claimed. An independent semantic review found no gateway merge regression

Checks must rerun on the current merge. Previous functional fork workflows required upstream maintainer approval and did not run. Pending workflows or reviews are not recorded as passes

Upstream compatibility update (2026-10-14)

Head at that update 3281b5fe0 includes upstream dev at 3a69bae84 and the latest v2 tip 461721082. Existing PR history is preserved; no force-push was used. The model HTTP handler now uses upstream's shared, timeout-bounded awaitPlugins helper instead of the previous direct activation wait. Discovery uses Effect 4's standard HTTP imports, and gateway model filtering preserves upstream provider-level compatibility inheritance and request encoding. A gateway regression assertion covers inherited compatibility with model-level overrides.

Canonical bun run check passed, including all 36 workspace typecheck tasks; lint reported warnings but zero errors. Selected suites passed 292 Core tests, 27 CLI authentication tests, 26 Schema tests, three Server HTTP tests and 100 AI Chat tests (448 total). The updated discovery/compatibility suites were rerun successfully after adding the inheritance assertion. Public client types were regenerated, and the Linux CLI built successfully. The pre-push hook reran canonical lint/typechecking successfully on the committed head. These are local checks; upstream CI/review results are not claimed, and no new live supplier inference or physical context-capacity validation was performed.

The overlap check retained gateway-specific credential-scoped inventory, optional metadata and request-budget behavior. Upstream local-provider discovery is not equivalent to its authoritative empty-catalog and account-change semantics. Related PRs #54398 (custom-provider limit discovery) and #54558 (LiteLLM provider) remained open/unmerged at verification; their overlapping scope still merits maintainer coordination.

Upstream compatibility update (2026-10-26)

Current head fb00e8e1e includes upstream dev at ed74ec82c (2.1.4). The merge adopts upstream's structured local reasoning controls, normalized variant generation, schema-derived settings filtering and OpenAI Chat parallel-tool handling, removing our duplicate protocol implementation. Gateway discovery keeps its account-scoped inventory and exact optional metadata, and local reasoning overrides preserve supported inherited defaults while clearing incompatible ones

The obsolete summary-only 32,000-token cap is removed. The resolved gateway/local output budget governs primary and summary requests, including background summaries, within supplier and context limits. Budget/limit changes invalidate held summaries. Post-hook fitting also constrains a resolved budget if a hook removes the explicit output option. Without a chosen output budget, upstream compaction reservation remains unchanged. The separate unknown-output fallback is still 32,000 tokens. Earlier fork-only boolean local reasoning configuration should use upstream's structured capabilities.reasoning form

Local canonical checks passed, including the pre-push hook (35 workspace tasks). The official TypeScript workspace run passed 34 tasks, and Core's official check passed again after the final reasoning adjustment. Selected checks passed 657 Core tests, all 91 Schema tests, 28 CLI authentication tests, three Server HTTP tests and 109 AI Chat tests. The final reasoning/config/provider suites passed 99 tests, and three discovery/request/compaction files passed ten repetitions (490 test executions). Public client generation completed. Linux and Windows x64 baseline release builds with freshly built web assets passed. The compiled Linux client passed isolated API and interactive key-login checks, immediate and cold-start catalog reads, and streaming requests with 8,192 / 65,536 / 131,072 output budgets plus a 12,345 local override against a loopback gateway fixture. These checks made no real supplier inference requests. Native Windows execution remains unverified. No current upstream CI/review pass or new supplier inference is claimed

V2.1 compaction checkpoints require a matching newer client/service. Older stored sessions have compatibility decoders, but downgrading after a new-format compaction requires restoring pre-upgrade data. Upstream's opt-in background compaction still has a conservative reuse limitation with a separately configured compaction-agent model, which can cause redundant summary generation

Screenshots / recordings

Not applicable; this changes model discovery and request handling.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@tudstudent
tudstudent force-pushed the gateway-model-metadata branch from 60121fd to 7f5754e Compare October 7, 2026 11:32
@thdxr
thdxr changed the base branch from v2 to dev October 10, 2026 19:35
Merge upstream v2 at 4617210, retaining gateway model metadata and request budgets. Use upstream awaitPlugins for model HTTP reads, migrate discovery to Effect 4 HTTP imports, and retain the model resolver node in the expanded upstream plugin test fixture.
Follow the PR's maintainer-selected dev base at 3a69bae. Preserve provider compatibility inheritance and request encoding alongside gateway inventory filters and budgets. Regenerate the public client and cover discovered-model compatibility inheritance with local overrides.
fwiesel added a commit to fwiesel/opencode that referenced this pull request Oct 21, 2026
Extend the discovery lifecycle from anomalyco#57161 so native proxy endpoints do not inherit unsupported models from the shared catalog. Preserve catalog metadata and explicit configuration, without coupling availability to routing or request-budget changes.

Based on anomalyco#57161; availability and effective-connection handling informed by anomalyco#53713 and anomalyco#54398.

Co-authored-by: Gr33nbl00d <[email protected]>
Co-authored-by: J.H.S. Schlepers <[email protected]>
Co-authored-by: Lance Woodson <[email protected]>
fwiesel added a commit to fwiesel/opencode that referenced this pull request Oct 22, 2026
Extend the discovery lifecycle from anomalyco#57161 so native proxy endpoints do not inherit unsupported models from the shared catalog. Preserve catalog metadata and explicit configuration, without coupling availability to routing or request-budget changes.

Based on anomalyco#57161; availability and effective-connection handling informed by anomalyco#53713 and anomalyco#54398.

Co-authored-by: Gr33nbl00d <[email protected]>
Co-authored-by: J.H.S. Schlepers <[email protected]>
Co-authored-by: Lance Woodson <[email protected]>
fwiesel added a commit to fwiesel/opencode that referenced this pull request Oct 22, 2026
Extend the discovery lifecycle from anomalyco#57161 so native proxy endpoints do not inherit unsupported models from the shared catalog. Preserve catalog metadata and explicit configuration, without coupling availability to routing or request-budget changes.

Based on anomalyco#57161; availability and effective-connection handling informed by anomalyco#53713 and anomalyco#54398.

Co-authored-by: Gr33nbl00d <[email protected]>
Co-authored-by: J.H.S. Schlepers <[email protected]>
Co-authored-by: Lance Woodson <[email protected]>
fwiesel added a commit to fwiesel/opencode that referenced this pull request Oct 22, 2026
Extend the discovery lifecycle from anomalyco#57161 so native proxy endpoints do not inherit unsupported models from the shared catalog. Preserve catalog metadata and explicit configuration, without coupling availability to routing or request-budget changes.

Based on anomalyco#57161; availability and effective-connection handling informed by anomalyco#53713 and anomalyco#54398.

Co-authored-by: Gr33nbl00d <[email protected]>
Co-authored-by: J.H.S. Schlepers <[email protected]>
Co-authored-by: Lance Woodson <[email protected]>
Adopt upstream reasoning overlays, schema-derived settings and Chat tool handling. Preserve gateway-selected output budgets without a separate summary cap, including background summaries and post-hook fitting. Invalidate held summaries on budget or limit changes and prevent disabled reasoning defaults from being inherited again. Retain ordinary upstream compaction policy when no output budget is chosen.
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant