Skip to content

ModelMetadata has no context-window concept, and TokenLimitReachedException is never thrown #260

Description

@georgestephanis

Summary

ModelMetadata has no concept of a model's context window (maximum input/total token count), and TokenLimitReachedException is declared in the SDK but never thrown anywhere in it. There's currently no way for a provider, a PromptBuilder consumer, or a plugin built on top of the SDK to know how much room a model has for a given prompt, or to be told proactively that a prompt won't fit — the only way to find out is to send the request and let the underlying API reject it (or silently truncate/misbehave, depending on the server).

Current behavior

  • ModelMetadata (src/Providers/Models/DTO/ModelMetadata.php) exposes id, name, supportedCapabilities, and supportedOptions — nothing describing the model's context window or max input tokens.
  • ModelConfig::maxTokens (→ OptionEnum::maxTokens()) only ever maps to the output-side max_tokens request parameter. It's a per-request cap on generation length, unrelated to how much input the model can accept.
  • TokenLimitReachedException (src/Common/Exception/TokenLimitReachedException.php) exists, with a docblock describing it as being thrown "when token usage exceeds the model's context window or a configured maximum," and carries a getMaxTokens() accessor — but grepping the SDK, it is never actually thrown by any provider implementation or by PromptBuilder. It's a defined contract with no implementation.
  • PromptBuilder builds the message list to send without any token estimation or trimming.

Why this matters

Callers that maintain their own conversation history (chat UIs, agents, plugins) have no way to:

  1. Discover a model's context window size from the SDK, so they could truncate/summarize history themselves.
  2. Get a clear, typed exception before firing a request that's too large, rather than an opaque provider-specific HTTP error.

This came up while working on an OpenAI-compatible-server connector plugin: we let site owners configure a "context length" for their self-hosted model, but the SDK gives us nowhere to plug that in on the input side — it can only be forwarded to the server as a best-effort hint (e.g. Ollama's num_ctx), not used by the SDK itself to warn or trim before sending.

Relationship to #193

#193 ("Missing Required Parameters in Tool Calls When Token Limit Reached") is adjacent but describes a different failure mode: output-side truncation, where generation stops mid-tool-call because finish_reason hit the length cap, and asks for TokenLimitReachedException to be thrown reactively when that happens.

This issue is about the input side: knowing a model's context window ahead of time as metadata, and optionally being able to catch an over-budget prompt before it's ever sent. Both problems converge on the same TokenLimitReachedException class, so a design for "when should this exception actually fire" should probably consider both at once — but they're distinct enough (reactive output-truncation vs. proactive input-budgeting) that I didn't want to conflate them in one issue.

Proposed solution (open to alternatives)

  1. Add a context-window field to ModelMetadata (e.g. contextWindow or maxInputTokens), populated by providers that know it (static per-model tables for hosted providers; left null for providers, like OpenAI-compatible self-hosted servers, where it's genuinely unknowable/configurable).
  2. Give callers a way to check a prompt against it — either a helper on ModelMetadata/PromptBuilder that estimates whether a set of messages fits, or having TokenLimitReachedException thrown proactively when the caller supplies/knows the limit and the assembled prompt exceeds it.
  3. Document the distinction between ModelConfig::maxTokens (output cap) and this new context-window concept clearly, since the naming is easy to conflate (we ran into exactly this confusion while building against the SDK).

Happy to help scope or contribute an implementation once there's agreement on direction — this surfaced from real usage, not a hypothetical.

AI disclosure

This issue was raised collaboratively between a human maintainer and Claude (Anthropic's AI coding assistant), working together in a Claude Code session against a WordPress plugin that consumes this SDK. Claude traced the plugin's context_length setting to confirm there was no corresponding SDK-side concept, read the relevant SDK source (ModelMetadata, ModelConfig, TokenLimitReachedException, PromptBuilder) to verify the gap, and searched this repository's existing issues (finding #193 as the closest related-but-distinct report) before drafting this write-up. The human reviewed and directed the investigation and approved filing this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions