Model: openai/gpt-5.4 Generated: 2026-04-01 Book: Claude Code VS OpenCode: Architecture, Design and The Road Ahead Chapter: 6 — LLM Provider Abstraction Token Usage: Approx. 1,500 output tokens for this section
6.2 Model Capability Detection
Supporting many models is only the first half of provider abstraction. The second half is knowing what those models can actually do at runtime. A modern coding agent cannot safely assume that every endpoint supports the same sampling controls, the same context length, the same multimodal inputs, or the same reasoning features. That is why capability detection is not a cosmetic feature. It is a negotiation layer between the agent runtime and the model backend.
Why runtime capability negotiation exists
In theory, the agent could send the same parameters to every provider and let the remote API reject what it does not understand. In practice, that would produce brittle behavior, wasted requests, confusing user experience, and unnecessary token cost. A strong runtime instead inspects or encodes model capabilities in advance and shapes requests accordingly.
The mismatches are real. Some providers support temperature but interpret its range differently. Some support top_p; others ignore it. Some expose max_tokens; others split this into input and output limits or cap it differently by model family. Some models can accept image or PDF inputs; some are text-only. Some expose explicit reasoning or thinking modes, while others only simulate step-by-step behavior through prompting.
This is a classic systems problem: a supposedly common interface sits on top of a heterogeneous substrate. The abstraction survives only if the runtime actively manages variance.
OpenCode: transform-driven capability normalization
OpenCode handles much of this in packages/opencode/src/provider/transform.ts. That file is a good example of capability detection through normalization rules rather than through one giant capability registry. The transform layer maps npm package names to provider option keys, rewrites messages to fit provider constraints, strips empty content that Anthropic rejects, sanitizes tool-call IDs for Claude and Mistral, inserts assistant bridge messages for Mistral sequencing quirks, rewrites reasoning payloads into provider-specific fields, and downgrades unsupported image or file inputs into explicit error text for the model to relay.
This last point is particularly important. If a model lacks image support, OpenCode does not simply crash. It transforms the unsupported input into a textual explanation such as “this model does not support image input.” That is an example of capability-aware degradation. The runtime preserves the conversation loop even when the requested modality is unavailable.
OpenCode’s design also reflects another reality: capability detection is sometimes indirect. You do not always have a clean machine-readable capability manifest from the provider. Instead, you infer capability from provider identity, model metadata, naming conventions, or known incompatibility rules. That is why ProviderTransform contains so much conditional logic. Runtime negotiation in the real world is often heuristic, not purely declarative.
Claude Code: explicit capability tracking for the Claude ecosystem
Claude Code is narrower in provider scope, but stronger in explicit capability accounting. src/utils/model/modelCapabilities.ts caches model metadata retrieved from Anthropic’s model listing endpoint and stores fields such as max_input_tokens and max_tokens in a local cache file. That may sound small, but it has major architectural significance. Claude Code is not guessing context size from branding alone; it is building a local capability record that can influence runtime decisions.
This is complemented by other files in the same model subsystem. contextWindowUpgradeCheck.ts encodes logic for context upgrades such as opus[1m] or sonnet[1m], while model.ts and related files reason about aliases, defaults, provider branches, and model availability. Together, these files act like a capability-aware control plane.
The phrase context window deserves a precise definition because it is often used casually. In textbook terms, it is the maximum amount of input a model can consider in one inference request, measured in tokens rather than characters. Tokens are subword units used by the model’s tokenizer. A larger context window changes agent behavior materially: it affects whether a tool result must be truncated, whether a large diff can be inlined, whether compaction must happen early, and whether a planning model can keep long task history in memory.
Claude Code’s approach is therefore less about universal provider negotiation and more about precise operating knowledge of the Claude family and its hosted variants. That fits its Anthropic-first philosophy.
Reasoning mode and thinking support
One of the newest capability dimensions is reasoning support. Different vendors expose it differently. Anthropic uses extended or interleaved thinking modes; OpenAI reasoning families such as o1 introduced a distinct reasoning-oriented interaction style; other providers may expose hidden thinking, explicit reasoning blocks, or no special control at all.
This creates a subtle challenge. “Reasoning” is not a single API standard. It is a vendor-specific feature family. OpenCode’s transform layer reflects that by moving reasoning content into provider-specific fields when a model’s interleaved capability definition demands it. Claude Code, because it is tuned around Claude-family models, can assume more coherent semantics when enabling thinking-related behaviors. OMO, sitting on top of OpenCode, inherits the lower-level complexity and must rely on underlying model selection and provider normalization to avoid assigning thinking-heavy workloads to weak or unsupported models.
For agent design, reasoning support matters because it changes planning quality, tool choice discipline, and latency/cost tradeoffs. A deep-thinking model may produce better decomposition but at higher latency and higher token use. A quick model may be sufficient for file lookup or formatting work. Capability detection therefore feeds orchestration policy, not just request formatting.
Vision and multimodal support
Vision capability detection is another practical necessity. Coding agents increasingly inspect screenshots, diagrams, PDFs, and UI mockups. But multimodal support is uneven. Some providers support images but not PDFs. Some support image understanding but not tool-call-rich agent loops. Some support vision only on certain endpoints.
OpenCode’s transform layer handles this with explicit modality checks and fallback text when a model cannot consume image, audio, video, or PDF input. Claude Code, being more tightly coupled to its supported model family, can integrate capability assumptions more directly into model policy. In both cases, the lesson is the same: multimodal support must be tested as a real capability dimension, not assumed from marketing copy.
Parameter support variance
Even classic controls like temperature, top_p, and max_tokens are not stable across providers. A model abstraction layer must decide whether to omit unsupported parameters, translate them, clamp them, or reject them. This is one reason OpenCode’s provider transform exists at all. The runtime is effectively doing protocol mediation between one agent interface and many subtly incompatible APIs.
That mediation affects agent behavior. If the runtime cannot rely on temperature, it may need to achieve determinism through prompt structure or model selection instead. If max_tokens differs drastically, the agent may need more aggressive output truncation or chunking. Capability detection is thus operational, not merely descriptive.
Design lesson
The essential lesson is that model support must be treated as negotiated capability, not assumed identity. “Using model X” does not mean the same thing across providers, regions, hosted variants, or API generations. Good agent runtimes therefore need at least four capability dimensions:
- Sampling controls: temperature, top-p, token caps.
- Modalities: text, image, PDF, audio, video.
- Reasoning features: thinking modes, reasoning channels, interleaving.
- Context budget: maximum input and output token windows.
OpenCode shows how to survive heterogeneity with aggressive transformation. Claude Code shows the value of precise, cached capability knowledge in a narrower ecosystem. OMO reminds us that capability detection eventually shapes orchestration policy: the agent should not just know what a model can do, but choose work based on that knowledge.