Standard ASR

standard_asr.contract.capabilities

The hierarchical capability tree: engine authors declare what they support, applications query it at runtime via engine.supports().

Hierarchical capability system for Standard ASR engines.

Engines declare what they support with a single hierarchical tree grouped by mode domain (batch / streaming), plus engine-global orthogonal flags (streaming_input / streaming_output). This module implements the normative capability model (spec, section "Capabilities").

Two layers exist:

  • DeclaredCapabilities -- the static, class-level (ClassVar) full capability set, discoverable without instantiating or authenticating the engine. Used by show, the registry, UI generation and REST.
  • effective_capabilities -- an instance-level subset that may narrow the declared set based on runtime configuration. The invariant effective ⊆ declared is enforced by compliance tests (see DeclaredCapabilities.covers).

Every leaf node is one of three archetypes -- flag, bounded, or enum/mode -- and all expose a uniform is_supported boolean so that strict / best_effort gating is consistent across the tree. Applications query capabilities exclusively through DeclaredCapabilities.supports with a dot-path; missing keys are fail-closed (return False).

BatchCapabilities#classSource

class BatchCapabilities(_Container)

Capability tree for the batch mode domain.

Attributes
NameTypeDescription
language
= LanguageCaps()
LanguageCaps

Language capabilities.

word_timestamps
= WordTimestampsCap()
WordTimestampsCap

Word-timestamp capability.

guidance
= GuidanceCaps()
GuidanceCaps

Guidance-family capabilities.

diarization
= DiarizationCap()
DiarizationCap

Diarization capability.

CandidateLanguagesCap#classSource

class CandidateLanguagesCap(_FlagLikeNode)

Bounded capability for candidate languages.

Attributes
NameTypeDescription
constraints
= None
CandidateLanguagesConstraints | None

Limits (for example, max) when supported.

supportedbool

Whether candidate languages are supported.

CandidateLanguagesConstraints#classSource

class CandidateLanguagesConstraints(_JsonExtraModel)

Constraints for the candidate-languages capability.

Attributes
NameTypeDescription
maxint
gt=0

Maximum number of candidate languages accepted.

DeclaredCapabilities#classSource

class DeclaredCapabilities(_Container)

The full capability tree declared by an engine.

Mode domains are optional: omitting a domain means the mode is not supported (fail-closed). Engine-global orthogonal flags live at the top level.

Attributes
NameTypeDescription
batch
= None
BatchCapabilities | None

Batch-mode capabilities, or None if batch is unsupported.

streaming
= None
StreamingCapabilities | None

Streaming-mode capabilities, or None if unsupported.

streaming_input
= FlagCap()
FlagCap

Whether the engine accepts incremental audio. May only be supported when a streaming domain is declared.

streaming_output
= FlagCap()
FlagCap

Whether the engine returns results incrementally. May only be supported when a streaming domain is declared.

self_resamples
= FlagCap()
FlagCap

Whether the engine resamples audio internally. This is one of the behavioral facts the spec declares in Capabilities rather than Properties -- alongside the per-mode diarization.always_on and the streaming behavior flags; unlike those it is engine-global (a static behavior of the engine, not per-mode), so it lives at the top level alongside streaming_input / streaming_output.

It is purely informational: accepted_sample_rates remains authoritative for every resampling decision, so this flag has no decision power and does NOT change whether the standard resamples. It lets a client-side resampling engine (for example, faster-whisper, which declares accepted_sample_rates="any") advertise that incoming audio is downsampled inside the engine rather than by the standard. Absent ⇒ False (fail-closed).

supports#methodSource

def DeclaredCapabilities.supports(dot_path: str) -> bool

Return whether the capability at dot_path is supported.

The only standard way to query capabilities. Walks the tree segment by segment; any missing segment returns False (fail-closed). Resolving a present mode-domain or container also returns True.

Parameters
NameTypeDescription
dot_pathstr

Dotted capability path without the capabilities. prefix (for example, "batch.word_timestamps", "streaming.guidance.phrase_hints", "streaming_input").

Returns
  • bool

    True if supported, otherwise False.

node_at#methodSource

def DeclaredCapabilities.node_at(dot_path: str) -> _CapNode | None

Return the typed capability node at dot_path, or None.

Unlike supports (which returns a bool), this returns the leaf node object itself so callers can inspect its constraints / enums (for example, a WordTimestampsCap to validate a requested granularity against WordTimestampsCap.granularities). Returns None if the path is absent or does not resolve to a capability leaf node.

Parameters
NameTypeDescription
dot_pathstr

Dotted capability path without the capabilities. prefix (for example, "batch.word_timestamps").

Returns
  • _CapNode | None

    The capability leaf node, or None.

iter_supported_paths#methodSource

def DeclaredCapabilities.iter_supported_paths() -> Iterator[str]

Yield every dot-path in the tree whose node is supported.

Only the children of a supported typed node are descended into, so an unsupported feature's constraint sub-containers (which are always present, never None) do not appear. A raw x_* dict subtree is walked unconditionally (see _iter_paths) so nested explicit vendor capabilities stay discoverable. Used to verify the effective ⊆ declared invariant.

Yields
  • str

    Dot-paths of supported capability nodes and present containers.

iter_queryable_paths#methodSource

def DeclaredCapabilities.iter_queryable_paths() -> Iterator[str]

Yield the dot-path of every NODE in the tree -- supported or not.

The node set is pinned by the two-layer isomorphism: exactly the paths at which canonical_json renders a JSON object and at which supports resolves a model/dict -- capability leaves, containers, constraint submodels, and x_* extension subtrees (typed or raw-dict; model extras pass the same x_* gate as every other traversal, so a non-extension unknown key is not a node). Scalar field values (a supported bool, a mode token, a granularities list) are field internals, not nodes: neither yielded nor descended. None children (an absent mode domain, a constraints=None) are skipped.

Unlike iter_supported_paths (the supported-only view behind effective ⊆ declared), UNSUPPORTED nodes are yielded and descended, so a consumer can verify the fail-closed False answers too -- for example, an unsupported feature's constraints submodel MUST probe False. The compliance suite sweeps this set to assert a hand-written supports() agrees with the tree on every node.

Yields
  • str

    Dot-paths of every capability node, container, submodel, and

  • str

    extension subtree in the tree.

covers#methodSource

def DeclaredCapabilities.covers(other: DeclaredCapabilities) -> bool

Return whether other is a valid narrowing of this tree.

Enforces the normative effective ⊆ declared invariant: the effective set may only close declared capabilities, never widen them. This checks two things:

  • Set containment -- every supported path in other is also supported here (no feature is enabled that this tree did not declare).
  • Constraint narrowing -- where both trees support a bounded or enum/mode node, other's limits MUST be no looser than this tree's (for example, a smaller-or-equal max, a subset of granularities, a mode that is the same or a reduction). A widening (declared max=2 -> effective max=999) is rejected.
Parameters
NameTypeDescription
otherDeclaredCapabilities

A (typically narrowed, effective) capability tree.

Returns
  • bool

    True if other is a subset narrowing of this tree.

canonical_json#methodSource

def DeclaredCapabilities.canonical_json() -> dict[str, Any]

Serialize to canonical JSON with a derived supported at every node.

Cross-language clients read capabilities from this JSON. Flag and bounded nodes carry supported as a real field, but enum/mode nodes derive it from mode (a Python property, absent from model_dump). This method injects the uniform boolean at every capability node and present container so a client never has to special-case archetypes or know the "none"/"unsupported" sentinels (enum/mode nodes' supported is server-injected). The root object itself carries no supported key (it is the container of all modes, not a capability); an absent mode domain serializes as null (fail-closed).

Returns
  • dict[str, Any]

    A JSON-serializable capability tree with supported on each node.

DiarizationCap#classSource

class DiarizationCap(_FlagLikeNode)

Capability for speaker diarization (requested via RuntimeParams.diarization).

always_on is a behavioral fact, in the same family as self_resamples (and the streaming behavior flags emits_partials / re_segments / word_stability): it describes what the engine does -- its architecture cannot DISABLE diarization, so speaker labels may appear even when diarization is not requested -- and grants nothing an application could request.

It is nonetheless a regular queryable flag node (a FlagCap), uniform with self_resamples: supports("<mode>.diarization.always_on") works, it appears in iter_supported_paths when supported, canonical_json injects a uniform supported boolean for it, and covers treats a declared-unsupported -> effective-supported change as a rejected widening (declaration drift) by plain set containment.

The one thing that distinguishes always_on from every other flag is a semantic inversion: for every other flag True means "you MAY request this", whereas for always_on True means "this is imposed on you" -- speaker labels may appear even when you did not ask for them (the documented exemption to request-gated diarization). That inversion is documented prose, not a difference in representation.

It is NOT placed inside constraints (constraints are machine-checkable request limits, and always_on is a behavioral fact, not a limit). It is reserved for architecturally non-disableable engines: an engine that CAN disable diarization MUST disable it when diarization is not requested (can-disable-must-disable), and MUST NOT declare always_on for adapter convenience.

Attributes
NameTypeDescription
always_on
= FlagCap()
FlagCap

Whether diarization is architecturally non-disableable (labels may appear unrequested). May only be supported when supported is True.

constraints
= DiarizationConstraints()
DiarizationConstraints

Limits when supported.

supportedbool

Whether diarization is supported.

DiarizationConstraints#classSource

class DiarizationConstraints(_JsonExtraModel)

Constraints for the diarization capability.

Attributes
NameTypeDescription
max_speakers
= None
int | None
gt=0

Optional maximum number of speakers.

FinalityCap#classSource

class FinalityCap(_CapNode)

Streaming finality level the engine can guarantee.

Attributes
NameTypeDescription
mode
= 'final'
Literal['final', 'closed']

final (may still be revised by post-processing) or closed.

is_supportedbool

Whether a finality level is guaranteed (always True here).

FlagCap#classSource

class FlagCap(_FlagLikeNode)

A simple supported / not-supported flag.

GuidanceCaps#classSource

class GuidanceCaps(_Container)

Guidance-family capabilities for one mode.

Attributes
NameTypeDescription
prompt
= PromptCap()
PromptCap

Free-text prompt channel.

phrase_hints
= PhraseHintsCap()
PhraseHintsCap

Phrase-hint channel.

granularity_offers_all#functionSource

def granularity_offers_all(granularities: Sequence[str]) -> bool

Return whether a declared granularities list means "unbounded (all)".

An empty enumeration on a bounded node is the "engine did not enumerate" / unbounded case, not "offers nothing" (on a bounded archetype an empty enumeration list does not constrain). The only consumer is the capability-narrowing comparison _node_narrows / DeclaredCapabilities.covers, and there only on the raw dict / x_* path: a typed WordTimestampsCap cannot reach this case because its validator makes supported=True with an empty granularities unrepresentable, so "empty == all" survives solely for untyped JSON-sourced nodes.

This is deliberately NOT shared with runtime parameter gating: runtime.gating._gate_granularity does not call this function and takes the opposite stance (a supported WordTimestampsCap always enumerates its granularities, so a requested value MUST be one of them -- no "empty => honor anything"). The two modules agree because that typed-validator invariant closes the empty case, not because they share this helper.

Parameters
NameTypeDescription
granularitiesSequence[str]

The declared granularity list (possibly empty).

Returns
  • bool

    True if the list is empty (unbounded -- every granularity offered).

LanguageCaps#classSource

class LanguageCaps(_Container)

Language capabilities for one mode.

Attributes
NameTypeDescription
runtime_override
= FlagCap()
FlagCap

Whether per-request language override is allowed.

candidate_languages
= CandidateLanguagesCap()
CandidateLanguagesCap

Candidate-language support and limits.

ModeName#attributeSource

ModeName = Literal['batch', 'streaming']

PhraseHintsCap#classSource

class PhraseHintsCap(_FlagLikeNode)

Guidance channel: phrase-hint term boosting.

Attributes
NameTypeDescription
constraints
= PhraseHintsConstraints()
PhraseHintsConstraints

Limits when supported.

supportedbool

Whether phrase hints are supported.

PhraseHintsConstraints#classSource

class PhraseHintsConstraints(_JsonExtraModel)

Constraints for the phrase-hints guidance channel.

Attributes
NameTypeDescription
max_terms
= None
int | None
gt=0

Optional maximum number of phrase-hint terms.

max_chars_per_term
= None
int | None
gt=0

Optional maximum characters per term.

max_words_per_term
= None
int | None
gt=0

Optional maximum words per term.

PromptCap#classSource

class PromptCap(_FlagLikeNode)

Guidance channel: free-text prompt.

Attributes
NameTypeDescription
constraints
= PromptConstraints()
PromptConstraints

Limits when supported.

supportedbool

Whether prompt guidance is supported.

PromptConstraints#classSource

class PromptConstraints(_JsonExtraModel)

Constraints for the prompt guidance channel.

Attributes
NameTypeDescription
max_tokens
= None
int | None
gt=0

Optional maximum prompt length in tokens. The standard layer has no engine tokenizer, so it enforces this bound against a conservative, script-aware approximation -- whitespace-delimited words plus one unit per space-less (CJK, kana, Hangul, Thai, and so on) codepoint -- not the engine's exact token count. Honest scope of the guarantee: the approximation never under-counts relative to that whitespace + no-space-script tokenization, but it MAY under-count an engine's subword (BPE) tokenization of long Latin words / URLs / digit runs (counted as 1 here, often 6-17 BPE tokens), so such a prompt can exceed the engine's true budget despite passing the gate. Declare max_tokens with headroom below the engine's hard limit rather than at it; the standard never exceeds the declared value.

ReconnectCap#classSource

class ReconnectCap(_CapNode)

Streaming reconnect capability.

Attributes
NameTypeDescription
mode
= 'unsupported'
Literal['seamless', 'lossy', 'unsupported']

seamless / lossy / unsupported.

is_supportedbool

Whether reconnect is supported.

StreamTimestampsCap#classSource

class StreamTimestampsCap(_CapNode)

Source of streaming timestamps.

Attributes
NameTypeDescription
mode
= 'none'
Literal['native_frame_aligned', 'post_align', 'none']

native_frame_aligned / post_align / none.

is_supportedbool

Whether streaming timestamps are provided.

StreamingCapabilities#classSource

class StreamingCapabilities(_Container)

Capability tree for the streaming mode domain.

Attributes
NameTypeDescription
language
= LanguageCaps()
LanguageCaps

Language capabilities (MAY differ from batch).

word_timestamps
= WordTimestampsCap()
WordTimestampsCap

Word-timestamp capability.

diarization
= DiarizationCap()
DiarizationCap

Diarization capability (MAY differ from batch).

guidance
= StreamingGuidanceCaps()
GuidanceCaps

Guidance-family capabilities (MAY differ from batch); the streaming variant additionally exposes mutable_mid_stream.

emits_partials
= FlagCap()
FlagCap

Whether partial events are emitted.

re_segments
= FlagCap()
FlagCap

Whether supersede events may occur.

word_stability
= FlagCap()
FlagCap

Whether a meaningful stable_until is provided.

reconnect
= ReconnectCap()
ReconnectCap

Reconnect capability mode.

finality_level
= FinalityCap()
FinalityCap

Finality level guaranteed.

timestamps
= StreamTimestampsCap()
StreamTimestampsCap

Source of streaming timestamps.

StreamingGuidanceCaps#classSource

class StreamingGuidanceCaps(GuidanceCaps)

Streaming guidance-family capabilities (adds mid-stream mutability).

Identical to GuidanceCaps plus mutable_mid_stream -- the declaration site for the "guidance may change mid-stream" flag. It lives only on the streaming guidance family because mid-stream mutability is meaningless for batch (a single shot); batch guidance keeps the plain GuidanceCaps.

A supported mutable_mid_stream means the engine MAY accept updated guidance after start_transcription (otherwise RuntimeParams is frozen for the whole session). v1 reserves the flag as the standard query path (supports("streaming.guidance.mutable_mid_stream")) and does NOT promise an update_guidance() method; default supported=False coincides with the fail-closed "session-locked" semantics, so the compliance suite requires no behavior for it. Modeled as a FlagCap (not a bare bool) so it derives a uniform supported and covers() set-containment auto-rejects a declared=false -> effective=true widening.

Attributes
NameTypeDescription
mutable_mid_stream
= FlagCap()
FlagCap

Whether guidance may be updated mid-session.

promptPromptCap

Free-text prompt channel.

phrase_hintsPhraseHintsCap

Phrase-hint channel.

WordTimestampGranularityName#attributeSource

WordTimestampGranularityName = Literal['word', 'segment', 'char']

WordTimestampsCap#classSource

class WordTimestampsCap(_FlagLikeNode)

Capability for word-level timestamps.

A supported word-timestamp capability MUST enumerate at least one granularity: an engine that declares supported=True but lists no granularities is ambiguous -- gating could not tell whether a requested granularity is offered, and silently honoring an unlisted one is the cardinal sin. Requiring explicit enumeration makes the "supported but unenumerated" state unrepresentable, so gating always validates against a real set. When supported=False the list is ignored (it defaults to empty and carries no meaning).

Attributes
NameTypeDescription
granularities
= lambda: cast('list[WordTimestampGranularityName]', [])()
list[WordTimestampGranularityName]

Supported granularities (word/segment/char); MUST be non-empty when supported is True.

supportedbool

Whether word timestamps are supported.

On this page