acecode previously treated context_window as a mostly static value and used a fallback of 128000.
That was incorrect for some Copilot models.
Observed example:
gpt-5.4under GitHub Copilot was shown as128kin acecode- Hermes Agent resolved it to
400k
The practical impact was not limited to display. The wrong value also affected runtime behavior:
- token status bar capacity display
/configoutput- auto-compact trigger threshold in
AgentLoop
AgentLoop derives automatic compaction at 90% of the resolved model context
window and the hard effective input window at 95%. The runtime compares the
latest server-reported total active-context usage with a fresh estimate of the
current request and uses the larger value. Message count is not an independent
compaction trigger.
GitHub Copilot's /models metadata is not a reliable source for the full model context window.
For some models it exposes provider-side input caps rather than the effective model context used for routing decisions.
That means a naive GET /models -> parse context -> trust it strategy can under-report context length.
Hermes Agent does not blindly trust provider /models metadata for known providers.
Its approach is provider-aware:
- Prefer a curated provider/model metadata source
- Use endpoint metadata only as a fallback
- Keep a final hardcoded fallback only for unknown cases
For Copilot, this avoids the common under-reporting problem.
acecode now uses a provider-aware runtime resolver implemented in:
src/provider/model_context_resolver.cpp
Current resolution strategy:
- If provider is
copilot, prefermodels.devprovider entrygithub-copilot - If provider is official
openai, prefermodels.devprovider entryopenai - For generic OpenAI-compatible endpoints, try the endpoint
/modelsmetadata as fallback - If no trustworthy metadata is found, keep the configured fallback value
Session-facing paths use a non-blocking variant of this resolver. When create/resume/model-switch code cannot find a cached or local models.dev value, it returns the configured fallback immediately and warms endpoint /models metadata in the background for future calls. This keeps small Web sessions from waiting on remote model metadata before the UI can switch sessions.
For this specific problem, models.dev is used as the authoritative provider-aware source because it exposes the model context expected for the provider variant instead of just the raw endpoint limit.
Example:
github-copilot / gpt-5.4resolves to400000
This is the value acecode should use for UX and runtime threshold calculations.
The resolved value is applied at runtime in two places:
- App startup
/model <name>switching- Web session create/resume model state
Whenever the model changes, acecode now refreshes:
config.context_windowAgentLoopcontext limit- token status display
For Web session create/resume, the first reported context_window may be the configured fallback if remote metadata is not cached yet; later session-facing resolutions reuse the process-local cache after a background probe succeeds.
OpenAI-compatible and Anthropic saved models can include optional
request_headers metadata:
{
"name": "gateway",
"provider": "openai",
"base_url": "https://gateway.example.com/v1",
"api_key": "sk-placeholder",
"model": "gpt-4o",
"request_headers": {
"X-Team": "acecode",
"X-Token": "{env:ACE_GATEWAY_TOKEN}"
}
}request_headers must be a JSON object with string header names and string template values. Templates may contain {env:NAME} placeholders; ACECode resolves them immediately before each OpenAI-compatible or Anthropic chat request. OpenAI-compatible /models probes also resolve the same templates. Keep secrets in environment variables instead of writing literal secrets into config.json, because the unresolved templates are returned by the Web/Desktop model editor for later editing.
Content-Type is controlled by ACECode and cannot be overridden. A custom Authorization header is allowed and overrides the built-in bearer header derived from api_key.
For legacy configs, the top-level openai.request_headers object is also accepted. It is used as a fallback for OpenAI-compatible saved model entries that do not define their own request_headers; per-model headers take precedence. Anthropic entries use only their own per-model request_headers.
For known providers, do not assume /models returns the real context window.
Prefer provider-aware metadata first.
- Cache
models.devresults locally to avoid repeated startup fetches - Show resolved context length directly in interactive model selection
- Expand provider mappings if more providers show endpoint metadata drift
src/provider/model_context_resolver.cppsrc/provider/model_context_resolver.hppsrc/commands/builtin_commands.cppmain.cpp