-
Notifications
You must be signed in to change notification settings - Fork 0
Capability Negotiation
How core matches a session's needs against a provider/model's capabilities at session start and on every /model or /provider switch.
contractVersion: 1.0.1
Provider and model capabilities are not static: a user may switch between a streaming-capable model and a non-streaming one, between a tool-calling model and one that cannot call tools, between a large-context model and a small one. A session depends on capabilities declared by its attached State Machine, configured Context Providers, and active Hooks. A mid-session switch that drops a required capability would silently break the session.
Capability Negotiation is the check that prevents that: every switch is a fail-fast on incompatibility. See Capability Mismatch Switch flow.
Per-model claims are registered against the bundled provider extensions and resolved per (providerId, modelId). The negotiator uses that registry as the source of truth for the selected pair; when the pair is unknown it falls back to a default capability vector whose promptCaching is probed (detect-on-use).
A provider's contracts/Providers shape carries a capabilities set. The common v1 capabilities:
classDiagram
class ModelCapabilities {
streaming : bool
toolCalling : bool
structuredOutput : bool
multimodal : MultimodalKinds
reasoning : bool
contextWindow : int
promptCaching : bool
}
class MultimodalKinds {
image : bool
audio : bool
video : bool
}
ModelCapabilities --> MultimodalKinds
See Model Capabilities for per-capability semantics.
A session's required set is computed from:
| Source | Contribution |
|---|---|
| Attached State Machine |
toolCalling: hard is always contributed — the stage pipeline's completion channel depends on strict tool calling (structured calls core can parse; malformed payloads returnable as tool-call results, not plain text). See Stage Definitions — Provider capability requirements. An SM may additionally contribute capabilities its stages rely on (e.g., streaming for token-stream hooks). |
| Active Context Providers | Providers declaring they produce tool-hint or resource-binding content require tool-calling; ones with large contributions require a minimum context window. |
| Active Hooks | Guard or transform hooks that operate on streaming token events require streaming. |
| Security mode |
allowlist with tool-oriented workflows requires tool-calling. |
The session's required set is fixed at session start for the initial provider/model choice and re-evaluated on each switch. A provider/model that cannot satisfy toolCalling: hard fails the capability check on /sm attach and on /model or /provider switch while an SM is attached.
A subagent session inherits the parent's required capability set at spawn. If the orchestrator's LLM overrides the subagent's (providerId, modelId) via the delegate tool's model arg (see Subagent Sessions § Model selection), the new model must satisfy the same set. A mismatch fails the spawn with Subagent/ModelCapabilityMismatch before any IP request fires — distinct from the /model mid-session switch path, which negotiates against the orchestrator session's required set rather than a child's.
sequenceDiagram
autonumber
actor User
participant Core
participant NewProvider as Target provider
User->>Core: /model small-gpt
Core->>NewProvider: describeCapabilities(small-gpt)
NewProvider-->>Core: capabilities
Core->>Core: diff required vs capabilities
alt compatible
Core-->>User: switch accepted
else missing capability
Core-->>User: switch rejected<br/>(list what's missing)
end
A rejected switch leaves the session on the previous choice. The user sees the specific missing capability and picks another target. Nothing silently downgrades.
A capability may be required in one of three senses:
| Level | Meaning |
|---|---|
hard |
Without it, the session cannot run correctly. Failure is fatal. |
preferred |
Without it, the session runs in a degraded mode but runs. Failure is a warning. |
probed |
Only relevant if a specific feature is invoked. Failure surfaces at the point of invocation. |
A State Machine that advertises streaming as hard will reject a non-streaming model. A Context Provider that marks promptCaching as preferred will accept any model; it just won't get cache hits on the provider that lacks it.
The table below shows every v1 capability against every requirement level and the negotiation outcome:
| Capability |
hard miss result |
preferred miss result |
probed result |
|---|---|---|---|
streaming |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
toolCalling |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
structuredOutput |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
multimodal |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
reasoning |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
contextWindow |
ProviderCapability/MissingCapability if claim < minimum
|
preferred-unmet if claim < minimum
|
probe-pending if claim is 'probed'
|
promptCaching |
ProviderCapability/MissingCapability — switch rejected |
preferred-unmet warning |
probe-pending warning |
contextWindow differs from the other six: the provider claim is number | 'probed' (not a discrete level). A requirement may carry a minimum token count; the negotiator compares the numeric claim against it. A 'probed' claim is always deferred regardless of the requirement level.
| Trigger | Behavior |
|---|---|
/model switch |
Full re-negotiation against the target model. |
/provider switch |
Full re-negotiation against the target provider's current choice model. |
| State Machine attach | Recompute required set; re-negotiate against current provider/model. |
| Reload adding a new active Context Provider | Recompute required set; re-negotiate. |
| Context window exhaustion mid-turn | Not a negotiation trigger — that is a Compaction trigger. |
Capability negotiation is runtime. Contract versioning (see Versioning and Compatibility) handles load-time compatibility. They are independent axes:
- A session's contract versions may all be compatible with core, but the current model may drop a runtime capability the SM needs — that is a runtime fail.
- A session's capabilities may all be satisfied, but the SM's contract version may be incompatible with core — that is a load-time fail.
A failed or warned negotiation produces a diagnostic carrying:
| Field | Meaning |
|---|---|
| Target | Provider + model the user asked to switch to. |
| Missing | List of { capability, requiredBy } pairs. |
| Previous | The session's pre-switch provider + model (still in force). |
| Suggestion | Optional — a target that would satisfy the session. |
paramsAffected |
Optional — list of { paramPath[], reason, activeModelId, currentValue, sourceLayer } entries enumerating session provider params that will not apply on the destination model. Surfaced for preferred-unmet and probe-pending cases (the switch is not blocked but params are dropped). currentValue is redacted via the same pipeline that produces audit redacted-deltas — secret-shaped values never appear verbatim. sourceLayer is one of defaultParams, launch, or /params. |
The diagnostic emits on the event bus and into the Audit Trail.
-
Provider-declared capabilities are untrusted input. A malicious provider may overstate its capabilities. Core treats declarations as hints and verifies them against known values where possible (
contextWindow,multimodal). See Trust Model. -
Downgrade requests are audited. A user accepting a switch despite a
preferredcapability loss lands in the audit trail so operators can see when sessions silently degraded. - No automatic fallback. Core does not pick a "close enough" model when the user's requested one is rejected; the user chooses explicitly.
- Model Capabilities
- Providers
- State Machines
- Hot Model Switch flow
- Capability Mismatch Switch flow
- Versioning and Compatibility
- Capability Negotiation spec as documented above. Declared v1 capability set; fail-fast on mid-session switch incompatibility; consumer-declared needs from SM, Context Providers, Hooks.
- Diagnostic shape gains an optional
paramsAffectedfield enumerating session provider params that will not apply on the destination model after a/modelor/providerswitch. Surfaced forpreferred-unmetandprobe-pendingcases. Field shape:{ paramPath[], reason, activeModelId, currentValue, sourceLayer }[].currentValueis redacted;sourceLayeris one ofdefaultParams/launch//params. - No contract break: pre-existing consumers ignore the new field; the four pre-existing fields are unchanged.
- Execution Model
- Message Loop
- Concurrency and Cancellation
- Error Model
- Event and Command Ordering
- Event Bus
- Command Model
- Interaction Protocol
- Hook Taxonomy
- Host API
- Extension Lifecycle
- Env Provider
- Prompt Registry
- Resource Registry
- Session Lifecycle
- Session Manifest
- Persistence and Recovery
- Stage Executions
- Subagent Sessions
- Contract Pattern
- Versioning and Compatibility
- Deprecation Policy
- Capability Negotiation
- Dependency Resolution
- Validation Pipeline
- Cardinality and Activation
- Extension State
- Conformance and Testing
- Providers
- Provider Params
- Tools
- Hooks
- UI
- Loggers
- State Machines
- SM Stage Lifecycle
- Stage Definitions
- Commands
- Session Store
- Context Providers
- Settings Shape
- Trust Model
- Project Trust
- Extension Isolation
- Extension Integrity
- LLM Context Isolation
- Secrets Hygiene
- Security Modes
- Tool Approvals
- MCP Trust
- Sandboxing
- Configuration Scopes
- Project Root
- Extension Discovery
- Extension Installation
- Extension Reloading
- Headless and Interactor
- Determinism and Ordering
- Launch Arguments
- Network Policy
- Platform Integration
Tools
UI
Session Stores
Loggers
Providers
Hooks
Context Providers
Commands
- First Run
- Default Chat
- Tool Call Cycle
- Hook Interception
- Guard Deny Reproposal
- State Machine Workflow
- SM Stage Retry
- Hot Model Switch
- Capability Mismatch Switch
- Session Resume
- Session Resume Drift
- Approval and Auth
- Interaction Timeout
- Headless Run
- Parallel Tool Approvals
- Subagent Delegation
- Scope Layering
- Project First-Run Trust
- Reload Mid-Turn
- Compaction Warning
- MCP Remote Tool Call
- MCP Prompt Consume
- MCP Resource Bind
- MCP Reconnect