feat(copilot): dynamic model catalog from /models API#73216
Conversation
Greptile SummaryThis PR replaces the hardcoded Copilot model table with live data from the Confidence Score: 4/5Safe to merge with minor deduplication inconsistency and a misleading fallback branch; no data loss or incorrect model behavior observed. All findings are P2. The most notable is that catalog.run bypasses fetchAndCacheModels, violating the stated at-most-one-call guarantee and risking a duplicate parallel API request during startup. The _copilotCapabilities always-object issue and the minimal level injection are style/correctness concerns that don't produce wrong user-visible behavior today. extensions/github-copilot/index.ts (catalog.run deduplication gap), extensions/github-copilot/thinking.ts (minimal level injection)
|
c05dda7 to
c498e39
Compare
|
Thanks for the review! Addressed the first two findings in the force-push:
|
c498e39 to
3f83279
Compare
427c1b3 to
341e086
Compare
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the live GitHub Copilot So I’m closing this here and keeping the remaining discussion on the canonical linked item. Review detailsBest possible solution: Use the merged live-catalog implementation on current main, and keep the remaining Claude 1m thinking/static fallback work on the narrower canonical issue and follow-up PRs instead of rebasing this duplicate branch. Do we have a high-confidence way to reproduce the issue? Yes for the PR blockers: source inspection of PR head shows the unscoped cache, missing Is this the best way to solve the issue? No, this PR is no longer the best way to solve the issue. A later merged PR implements the live catalog more cleanly on main, and the remaining thinking/fallback behavior should be handled in the focused related issue and PRs. Security review: Security review cleared: The PR adds a token-bearing Copilot What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against ba625e2cff29. |
0fe7cfa to
5edb5f5
Compare
Fetch the model list from the Copilot /models API at runtime instead of relying on hardcoded defaults. This gives OpenClaw accurate context windows, output limits, vision support, and thinking capabilities for every model on the user's Copilot plan — including new models added by GitHub without requiring a code change. Three hooks work together: - **catalog.run** populates models when the plugin discovery pipeline invokes it during ensureOpenClawModelsJson. - **augmentModelCatalog** adds the same models to the model catalog so they appear in /models list. This covers environments where the discovery pipeline does not reach late-order provider plugins (e.g. auth-profile-only setups without env-var credentials). - **prepareDynamicModel** lazily fetches capabilities on the first model request when neither of the above paths has run yet. All three share a single fetchAndCacheModels helper with in-flight deduplication so the API is called at most once per gateway lifecycle. Capability mapping: - contextWindow / maxTokens from capabilities.limits - vision from capabilities.supports.vision - transport API from supported_endpoints - reasoning flag from reasoning_effort / model family - thinking profile levels from reasoning_effort and adaptive_thinking (replaces the hardcoded xhigh model list) - compat.supportedReasoningEfforts from API data Filtering: - Internal router models (accounts/msft/routers/*) excluded - Embedding models excluded (they have their own provider path) - Duplicate model entries deduplicated (keeps richer capabilities) The existing resolveDynamicModel catch-all remains as a fallback for models not returned by the API, using conservative defaults (128K context, 8K max output). New modules: - models-api.ts: Copilot /models API types and fetch - models-mapping.ts: API response -> OpenClaw model mapping - thinking.ts: API capabilities -> thinking profile resolution Tests: 35 new tests (models-mapping + thinking).
5edb5f5 to
9e315f9
Compare
|
Friendly ping from a downstream user — no pressure 🙂 This PR (along with #72829) would fix a real pain point for those of us on I saw the clawsweeper feedback around agent-scoped auth, cache scoping, and preserving the known- Thanks for the work — totally understand if it has to wait, just wanted to surface that there's a user waiting downstream whenever you have cycles. |
@wyhgoodjob Thanks for your feedback! Actually, my original intention was to use the internal 1M-context model with xhigh effort, but I wasn't sure if I should mention that publicly. I wasn't familiar with OpenClaw's contribution guidelines, and since I hadn't received any human review or discussion beyond the automated agent's comments, I assumed this PR might just get buried like most of other PRs. Anyway, I'll find some time to rebase and reopen it. |
Summary
gpt-5.5(400K context, 128K output) orclaude-opus-4.7(200K context, 32K output) are either capped incorrectly or missing entirely. Thinking levels (e.g.xhigh) are hardcoded to a fixed list of model IDs./models list, and incorrect thinking level options — all of which degrade the Copilot experience without any visible error./modelsAPI at runtime. Three hooks (catalog.run,augmentModelCatalog,prepareDynamicModel) cooperate to populate capability-aware model definitions. A sharedfetchAndCacheModelshelper with in-flight deduplication ensures the API is called at most once per gateway lifecycle.resolveDynamicModelcatch-all fallback are untouched.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
N/A — this is a new feature.
Regression Test Plan (if applicable)
extensions/github-copilot/models-mapping.test.ts,extensions/github-copilot/thinking.test.tsUser-visible / Behavior Changes
/models list github-copilotnow shows all models available on the user's Copilot plan (fetched from API), not just a hardcoded subset.xhigh,adaptive) are determined from API capabilities instead of a hardcoded model ID list.Diagram (if applicable)
Security Impact (required)
resolveCopilotApiTokeninfrastructure{copilotBaseUrl}/modelsduring startupRepro + Verification
Environment
plugins.entries.github-copilot.enabled: true, auth via device login profile (no env vars)Steps
openclaw doctor)/models list github-copilotExpected
All models from the user's Copilot plan are listed with accurate context windows and capabilities.
Actual
Before: Only hardcoded default models shown (10 models, all with 128K context).
After: All API-returned models shown (e.g. 20+ models with correct per-model limits).
Evidence
/models list github-copilotshows API-sourced models with correct context windowsHuman Verification (required)
/models listshows dynamic models, model switching works with correct context windowsReview Conversations
Compatibility / Migration
Risks and Mitigations
/modelsAPI is unreachable or returns unexpected formatresolveDynamicModelcatch-all still creates synthetic model definitions with conservative defaults. API call has 30s timeout.