LLMProvider

Interface: LLMProvider

Defined in: src/provider-contract/types.ts:646

Properties

carriesForcedToolChoice?

readonly optional carriesForcedToolChoice?: boolean

Defined in: src/provider-contract/types.ts:730

v7.26 — whether this adapter puts LLMRequest.toolChoice on its wire as a forced choice of one named tool.

Absence means NO, not "probably". That is the opposite of carriesInMessages, whose absence means the floor every wire supports, and the difference is what the two capabilities are for. A role that quietly vanishes costs a message; a tool choice that quietly vanishes costs the guarantee the consumer selected the strategy FOR — the model would answer in whatever shape it liked while the config said the shape was constrained. So an agent using strategy: 'tool-forced' on a provider that has not declared this refuses at run start, by name.

Declare it only where it is true of the endpoint, not of the SDK: the OpenAI adapter declares it for real OpenAI and Azure and NOT behind a custom baseURL (Ollama, vLLM, Together, …), because what an OpenAI-compatible server does with tool_choice is that server's business and this library does not get to promise it.

A WRAPPER must forward it; withFallback publishes the AND of the two providers it holds. Model-specific restrictions are declared separately by supportsForcedToolChoice; this existing wire flag remains boolean.


carriesInMessages?

readonly optional carriesInMessages?: readonly WireRole[]

Defined in: src/provider-contract/types.ts:706

v7.21 — which roles this provider carries INSIDE the messages array.

The wires disagree, and the disagreement is invisible from the outside: the Anthropic-family adapters (Anthropic, Bedrock, Browser Anthropic) DROP a role: 'system' message inside messages because system rides a separate top-level field, while the OpenAI-family adapters carry it. So a slot: 'messages' injection with role: 'system' would arrive on one provider and vanish on another — and nothing in the recording would tell the two apart. Declaring the capability is what lets the engine refuse at run start instead, naming the provider and the roles it does carry.

Consulted at DELIVERY time by the agent's Deliver stage. A role that is not listed is REFUSED, never silently re-roled: changing who appears to speak is a meaning change the app must make, not the library.

Optional, and absence is not "carries everything" — a provider that omits it is treated as ['user', 'assistant'] (DEFAULT_CARRIES_IN_MESSAGES), the floor every known wire supports. Declare it if your adapter carries more.

A WRAPPER must forward it (the three src/resilience/ decorators do); withFallback publishes the INTERSECTION of the two providers it holds, because a role only one of them carries is a role the call might drop.


carriesNativeOutputSchema?

readonly optional carriesNativeOutputSchema?: boolean

Defined in: src/provider-contract/types.ts:750

Whether this adapter puts LLMRequest.outputFormat on its wire — the provider's own structured output, strategy: 'native'. Absence means NO, for the reason carriesForcedToolChoice gives: a format that quietly vanishes costs the guarantee the strategy was chosen for. Declared by anthropic(), browserAnthropic() and the mock; read with nativeOutputSchemaFor(provider, model). A WRAPPER must forward it; withFallback publishes the AND of its pair.


name

readonly name: string

Defined in: src/provider-contract/types.ts:647


promptCaching?

readonly optional promptCaching?: PromptCaching | ((model) => PromptCaching | undefined)

Defined in: src/provider-contract/types.ts:657

How this provider's wire caches a repeated prompt prefix (PromptCaching, from agentfootprint/cache). The agent picks its cache strategy from this, never from name. Absent = no caching the agent drives or meters. A wrapper must forward it, like carriesInMessages. A model-aware declaration returns undefined for an unknown/unsupported model. cacheStrategyFor(provider, model) resolves either form; adapters must consult the same rule before putting cache markers on the wire.


supportsForcedToolChoice?

readonly optional supportsForcedToolChoice?: (model) => boolean

Defined in: src/provider-contract/types.ts:740

Optional model-specific restriction on the forced-choice wire capability. Read with forcedToolChoiceFor(provider, model): the wire flag must be true AND this predicate (when present) must answer true. Absence preserves the wire flag's existing behaviour. The adapter resolves its shorthand.

Like thinkingMode, this function must not depend on this; wrappers forward it as a value. withFallback intersects both sides per model.

Parameters

model

string

Returns

boolean


supportsNativeOutputSchema?

readonly optional supportsNativeOutputSchema?: (model) => boolean

Defined in: src/provider-contract/types.ts:756

Optional per-model restriction on carriesNativeOutputSchema, the supportsForcedToolChoice twin: both must answer true. A plain function of the model id (no this); the adapter resolves its own shorthand.

Parameters

model

string

Returns

boolean


thinkingHandler?

readonly optional thinkingHandler?: ThinkingHandler

Defined in: src/provider-contract/types.ts:665

The handler that normalizes this wire's thinking (rawThinking). The agent uses it unless .thinkingHandler() overrides it; absent = no thinking stage. Never chosen by name — a wrapper must forward it.


thinkingMode?

readonly optional thinkingMode?: (model) => ThinkingMode

Defined in: src/provider-contract/types.ts:680

Which thinking request each model takes on this wire — 'budget', 'adaptive' or 'none' (ThinkingMode, from agentfootprint/providers), asked with the model id a request names (the adapter resolves its own shorthand, e.g. 'anthropic'). The adapter maps LLMRequest.thinking to the right wire shape for that model; the agent reads this at build to refuse .thinking() for a model that cannot think and to say, in dev mode, when 'adaptive' will not send the budget.

Absent = no per-model claim: requests carry thinking: { budget } and the adapter decides. A plain function of the model id — it must not use this, because a wrapper forwards it as a value, like carriesInMessages; withFallback answers for its pair.

Parameters

model

string

Returns

ThinkingMode

Methods

complete()

complete(req, hooks?): Promise<LLMResponse>

Defined in: src/provider-contract/types.ts:764

hooks (v7.8) is optional and additive — implementations may declare complete(req) with no second parameter and stay assignable. A LEAF provider (one that talks to a vendor) may ignore it. A WRAPPER must forward it, or everything it wraps goes silently dark — see the LLMCallHooks docs above.

Parameters

req

LLMRequest

hooks?

LLMCallHooks

Returns

Promise<LLMResponse>


stream()?

optional stream(req, hooks?): AsyncIterable<LLMChunk>

Defined in: src/provider-contract/types.ts:765

Parameters

req

LLMRequest

hooks?

LLMCallHooks

Returns

AsyncIterable<LLMChunk>

On this page