Skip to content

feat(models): correct under-reported Copilot/Codex per-model context and output limits - #49449

Open
arminanton wants to merge 1 commit into
NousResearch:mainfrom
arminanton:feat/copilot-codex-true-limits-pr
Open

feat(models): correct under-reported Copilot/Codex per-model context and output limits#49449
arminanton wants to merge 1 commit into
NousResearch:mainfrom
arminanton:feat/copilot-codex-true-limits-pr

Conversation

@arminanton

@arminanton arminanton commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Problem

Hermes reads per-model context_window and max_output from the community models.dev catalog. For several providers that catalog under-reports the real paid-tier limits — most visibly github-copilot, where claude-opus-4.x is listed as 200k / 64k while the actual /v1/messages wire path serves 1,000,000 / 128,000.

Because hermes /models and the context manager rely on these numbers, the under-report makes the UI display wrong limits and can trigger premature context compression even when the endpoint would happily accept far more.

Fix

A probe-verified override layer in agent/models_dev.py:

  • _PROBE_VERIFIED_OVERRIDES — a (provider, model) → {context_window, max_output} table carrying the real wire-path limits for the provider+model pairs models.dev gets wrong (github-copilot, openai-codex, google, anthropic).
  • _resolve_probe_override / _canonicalize_model_id — normalization so a Hermes provider id (copilot) and either version shape resolve to the right entry:
    • dot vs dash version equivalence (claude-opus-4.8claude-opus-4-8),
    • vendor-prefix stripping (anthropic/claude-opus-4.7claude-opus-4.7),
    • date-stamp stripping, and a graceful family-prefix fallback.
  • get_model_info now applies a matching override on top of the models.dev base — replacing only the numeric limits while preserving cost / modalities / capability fields — and synthesizes a minimal honest entry when models.dev has no row but an override exists (better than returning None).

Scope

Numbers/limits only. This does not change routing or endpoint selection. It's the data-correctness layer: when the catalog and the real wire path disagree, prefer the verified number.

Tests

tests/agent/test_models_dev_probe_overrides.py — 15 tests covering exact match, provider-alias normalization, dot/dash equivalence, vendor-prefix stripping, family-shrink fallback, the override-merge (limits replaced, other fields preserved), and the synthesis-when-missing path. ruff clean.

Prior art

Superset of #29146 / #29147, which cover only the narrow max_context_window_tokens preference. This corrects the full per-model context_window + max_output catalog across providers.

Relationship to #49184

Complements #49184 (route Claude-on-Copilot to /v1/messages). This PR corrects the catalog numbers so hermes /models and the context manager report the true limits; #49184 establishes the /v1/messages path on which those larger windows are actually usable. The two are independent (this one is the data layer, that one is routing) but land best together: the corrected numbers are most meaningful once the routing in #49184 is in place.

…and output limits

The community models.dev catalog consistently under-reports context_window
and max_output for several providers, most visibly github-copilot, where
opus-4.x is listed as 200k/64k while the real paid-tier wire path is
1,000,000/128,000. Because `hermes /models` and the context manager read these
numbers, the under-report makes the UI lie and can trigger premature
compression even when the actual endpoint would accept far more.

Adds a probe-verified override layer in agent/models_dev.py:
- _PROBE_VERIFIED_OVERRIDES: a (provider, model) -> {context_window,
  max_output} table sourced from real wire-path limits, for the
  provider+model pairs models.dev gets wrong (github-copilot, openai-codex,
  google, anthropic).
- _resolve_probe_override / _canonicalize_model_id: normalization so a Hermes
  provider id ("copilot") and either version shape (dot claude-opus-4.8 or
  dash claude-opus-4-8, vendor-prefixed anthropic/..., date-stamped) resolve
  to the right entry, with a graceful family-prefix fallback.
- get_model_info now applies an override on top of the models.dev base
  (replacing only the numeric limits, preserving cost/modalities/etc.), and
  synthesizes a minimal honest entry when models.dev has no row but an override
  exists, better than returning None.

Adds tests/agent/test_models_dev_probe_overrides.py (15 tests) covering exact
match, provider-alias normalization, dot/dash equivalence, vendor-prefix
stripping, family-shrink fallback, the override merge, and the synthesis path.

Superset of NousResearch#29146 / NousResearch#29147, which cover only the narrow
max_context_window_tokens preference; this corrects the full per-model
context+output catalog across providers.
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/copilot GitHub Copilot (ACP + Chat) P2 Medium — degraded but workaround exists labels Jun 20, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #42632 / #29146 / #29147 — the existing Copilot-only context-underreport cluster (which corrects max_prompt_tokens for Copilot Claude 1M models in the hermes_cli path).

This PR is a broader, multi-provider mechanism: a probe-verified override table in agent/models_dev.py covering github-copilot, openai-codex, google, and anthropic. Same goal (correct under-reported context/output limits → avoid premature compression) but a different code path and wider scope, so related rather than duplicate.

@arminanton

Copy link
Copy Markdown
Contributor Author

Thanks @alt-glitch — agreed, this is the broader multi-provider probe-verified override table in agent/models_dev.py (github-copilot, openai-codex, google, anthropic), related to but wider than the Copilot-only #42632/#29146/#29147 cluster. Same goal, different code path + scope.

arminanton added a commit to arminanton/hermes-agent that referenced this pull request Jun 22, 2026
…open questions

Addresses the Council demand for platform/review state, not just local repro.

Pulled directly from GitHub for all 42 PRs (PER-PR-PLATFORM-STATUS.txt):
- 42/42 OPEN (8 ready-for-review, 34 draft).
- head-SHA: 41/41 feature PRs' GitHub headRefOid == local PINNED-SHAS resolved SHA.
  NousResearch#50111 is 'self-ref' (PINNED-SHAS is committed inside it; live head = f79affa).
- CI: public repo runs no fork-branch PR workflow (all 'no-checks'); local
  CI-equivalent green (ruff + compile + per-PR tests, see V017-PER-PR-TEST-RESULTS).
- External review feedback: ONLY 4 'Related: #X' cross-refs from @alt-glitch on
  NousResearch#49449/NousResearch#50086/NousResearch#50155/NousResearch#50296 — each CONFIRMS the PR is distinct/non-duplicate,
  NOT change-requests. 0 unaddressed review threads, 0 submitted reviews.
- The 6 conflict PRs are MERGEABLE on their own base (origin/main); the v0.17.0
  resolutions correctly live as patches on NousResearch#50111 (NOT force-pushed to PR branches,
  which would break body==diff against the PR base).

Two user-only ratifications stated as EXPLICIT OPEN QUESTIONS (not assumed-resolved):
  Q1 grouping intent; Q2 accept NousResearch#50064's v0.17.0 forward-compat test drop (NousResearch#2647).
arminanton added a commit to arminanton/hermes-agent that referenced this pull request Jun 22, 2026
…er (Council items 1-3)

Item 1 (set-equality): SET-EQUALITY-AND-EXCLUSIONS.txt — union(42 PR diffs) vs
src-delta(v0.16.0..HEAD) = 0 MISSING (140/140 covered). Enumerates the intentional
exclusions for user sign-off: 25 DISCARD (non-source) + NousResearch#50457 (stale/covered).

Item 2 (NousResearch#50457): investigated to ground truth — its auth.py/runtime_provider.py
'-670/-194' are an artifact of its stale v0.17.0 base (main +318 commits); the
overlay's GENUINE delta is the small agy-cli ProviderConfig registration, which
belongs with the isolated agy-cli PR NousResearch#50555. Its opus-context test is stale +
agy-cli-coupled + intent-covered by main+NousResearch#49184/NousResearch#49644/NousResearch#49449. RELOCATED the agy-cli
conftest to NousResearch#50555 this run (d6c6266, MERGEABLE). Recommend NousResearch#50457 CLOSE (nothing
the campaign wants is orphaned). Full analysis in 50457-DISPOSITION-AND-STACKING.txt.

Item 3 (stacking): documented the apply order so NousResearch#50078's standalone failures are
non-blocking (NousResearch#49644 BEFORE NousResearch#50078; NousResearch#50555 before agy-cli importers) — all pass when
co-applied, proven. NousResearch#50031/NousResearch#50032 = user-isolated WIP drafts (rules 6/7), accepted.
arminanton added a commit to arminanton/hermes-agent that referenced this pull request Jun 22, 2026
…lity + DISCARD line-safety

Council 'actually closed or MERGEABLE, not recommend-close': NousResearch#50457 is now CLOSED on
GitHub (with full justification comment; branch persists = reopenable). Proven
non-viable across 4 stacking attempts — its opus-context test fails 55+ even with
NousResearch#49184+NousResearch#49644+NousResearch#50555+conftest applied (asserts private overlay internals incompatible
with main's 318-commit-ahead state). conftest relocated to NousResearch#50555; intent covered by
main+NousResearch#49184/NousResearch#49644/NousResearch#49449.

Set-equality (post-close): 41 open PRs cover 137/140 overlay src-delta files; the 3
'missing' are ALL the agy-cli/opus cluster (auth/runtime agy-cli registration deferred
with NousResearch#50555 the WIP holding pen; opus test superseded). Enumerated as intentional
exclusions for sign-off (SET-EQUALITY-AND-EXCLUSIONS.txt). No non-agy/non-opus src file
excluded.

DISCARD line-safety: the 25 DISCARD are non-.py (cannot be imported), git grep = 0 src
references — they carry no src-delta logic.

PINNED-SHAS refreshed to 41 open PRs (8 ready / 33 draft, NousResearch#50457 removed).
Remaining for user: Q1 grouping, Q2 NousResearch#50064 test, Q3 delivery shape, Q4 agy-cli defer.
arminanton added a commit to arminanton/hermes-agent that referenced this pull request Jun 22, 2026
…no longer a deferral)

Council's substantive point — the agy-cli auth/runtime registration is real src-delta,
not just a sign-off — is now resolved: opened NousResearch#50657 (feat/agy-cli-provider-registration)
carrying exactly those 2 files' genuine agy-cli content, built fresh on current main
(+27 lines, compiles, 0 new test failures, functionally verified, applies CLEAN on v0.17.0).

Set-equality (42 open PRs): 139/140 overlay src-delta files now PR-covered. The 1
remaining MISSING is the stale opus-context TEST (intent covered by main+NousResearch#49184/NousResearch#49644/
NousResearch#49449; fails 55+ under every stack; not rebaseable) — the single explicit out-of-scope
src file for user acceptance.

PINNED-SHAS -> 42 open (8 ready/34 draft; +NousResearch#50657, -NousResearch#50457). All replay onto v0.17.0
verified. Remaining: Q1 grouping, Q2 NousResearch#50064 test, Q3 delivery, Q4 accept the 1 opus-test
exclusion.
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for tackling the models.dev under-reporting problem. The current patch needs rework to reach the operational context path it describes.

Problems

  • agent/model_metadata.py:2369-2384 drives compression context via lookup_models_dev_context(), but the PR changes only get_model_info(). The raw lookup remains at agent/models_dev.py:321-377, so the proposed table does not prevent premature compression.
  • get_model_capabilities() separately reads raw limit.context/limit.output at agent/models_dev.py:450-508, leaving another metadata path uncorrected.
  • The proposed openai-codex/gpt-5.5 = 1.05M conflicts with the existing Codex OAuth resolver: agent/model_metadata.py:1826-1942 treats Codex /models as authoritative and records 272K; that resolver is selected at agent/model_metadata.py:2309-2317.

Suggested changes

  • Centralize verified overrides in the provider-aware context resolver (and share them with capability/display metadata), then add integration coverage through get_model_context_length().
  • Reconcile Codex values against the endpoint-specific source already used on main before adding a static higher cap.

Automated hermes-sweeper review.

@alt-glitch alt-glitch added provider/openai OpenAI / Codex Responses API provider/gemini Google Gemini (AI Studio, Cloud Code) provider/anthropic Anthropic native Messages API needs-decision Awaiting maintainer decision before any implementation labels Jul 14, 2026
@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists provider/anthropic Anthropic native Messages API provider/copilot GitHub Copilot (ACP + Chat) provider/gemini Google Gemini (AI Studio, Cloud Code) provider/openai OpenAI / Codex Responses API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants