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:
- Discover a model's context window size from the SDK, so they could truncate/summarize history themselves.
- 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)
- 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).
- 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.
- 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.
Summary
ModelMetadatahas no concept of a model's context window (maximum input/total token count), andTokenLimitReachedExceptionis declared in the SDK but never thrown anywhere in it. There's currently no way for a provider, aPromptBuilderconsumer, 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) exposesid,name,supportedCapabilities, andsupportedOptions— nothing describing the model's context window or max input tokens.ModelConfig::maxTokens(→OptionEnum::maxTokens()) only ever maps to the output-sidemax_tokensrequest 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 agetMaxTokens()accessor — but grepping the SDK, it is never actually thrown by any provider implementation or byPromptBuilder. It's a defined contract with no implementation.PromptBuilderbuilds 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:
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_reasonhit the length cap, and asks forTokenLimitReachedExceptionto 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
TokenLimitReachedExceptionclass, 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)
ModelMetadata(e.g.contextWindowormaxInputTokens), populated by providers that know it (static per-model tables for hosted providers; leftnullfor providers, like OpenAI-compatible self-hosted servers, where it's genuinely unknowable/configurable).ModelMetadata/PromptBuilderthat estimates whether a set of messages fits, or havingTokenLimitReachedExceptionthrown proactively when the caller supplies/knows the limit and the assembled prompt exceeds it.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_lengthsetting 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.