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 / partial_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 promises.

The rule lives in the streaming section of the protocol specification, section 4.2, under the list of what may still change at each stage.

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

final or closed. With final, the engine does not promise a closed final for each segment, and it may still send one: a post-processing restatement that changes how the text is written. With closed, the engine MUST bring every segment that reached final, and that no supersede retired, to closed before the session ends with done. A session that has the engine's capabilities checks this at done, and so does check_event_sequence when it is given them; both report a segment left final as finality_level_not_reached.

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.

partial_stability
= FlagCap()
FlagCap

Whether a partial event may carry non-empty stable_text. A final is outside this capability: it marks its whole text stable on every engine.

reconnect
= ReconnectCap()
ReconnectCap

Reconnect capability mode.

finality_level
= FinalityCap()
FinalityCap

Whether the engine promises a closed final for each finalized segment (see FinalityCap).

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). The current generation 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