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 byshow, the registry, UI generation and REST.effective_capabilities-- an instance-level subset that may narrow the declared set based on runtime configuration. The invarianteffective ⊆ declaredis enforced by compliance tests (seeDeclaredCapabilities.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.
| Name | Type | Description |
|---|---|---|
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.
| Name | Type | Description |
|---|---|---|
constraints= None | CandidateLanguagesConstraints | None | Limits (for example, |
supported | bool | Whether candidate languages are supported. |
CandidateLanguagesConstraints#classSource
class CandidateLanguagesConstraints(_JsonExtraModel)Constraints for the candidate-languages capability.
| Name | Type | Description |
|---|---|---|
max | intgt=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.
| Name | Type | Description |
|---|---|---|
batch= None | BatchCapabilities | None | Batch-mode capabilities, or |
streaming= None | StreamingCapabilities | None | Streaming-mode capabilities, or |
streaming_input= FlagCap() | FlagCap | Whether the engine accepts incremental audio. May only
be supported when a |
streaming_output= FlagCap() | FlagCap | Whether the engine returns results incrementally. May
only be supported when a |
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
It is purely informational: |
supports#methodSource
def DeclaredCapabilities.supports(dot_path: str) -> boolReturn 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.
| Name | Type | Description |
|---|---|---|
dot_path | str | Dotted capability path without the |
boolTrueif supported, otherwiseFalse.
node_at#methodSource
def DeclaredCapabilities.node_at(dot_path: str) -> _CapNode | NoneReturn 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.
| Name | Type | Description |
|---|---|---|
dot_path | str | Dotted capability path without the |
_CapNode | NoneThe 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.
strDot-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.
strDot-paths of every capability node, container, submodel, and
strextension subtree in the tree.
covers#methodSource
def DeclaredCapabilities.covers(other: DeclaredCapabilities) -> boolReturn 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
otheris 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-equalmax, a subset ofgranularities, amodethat is the same or a reduction). A widening (declaredmax=2-> effectivemax=999) is rejected.
| Name | Type | Description |
|---|---|---|
other | DeclaredCapabilities | A (typically narrowed, effective) capability tree. |
boolTrueifotheris 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).
dict[str, Any]A JSON-serializable capability tree with
supportedon 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.
| Name | Type | Description |
|---|---|---|
always_on= FlagCap() | FlagCap | Whether diarization is architecturally non-disableable
(labels may appear unrequested). May only be supported when
|
constraints= DiarizationConstraints() | DiarizationConstraints | Limits when supported. |
supported | bool | Whether diarization is supported. |
DiarizationConstraints#classSource
class DiarizationConstraints(_JsonExtraModel)Constraints for the diarization capability.
| Name | Type | Description |
|---|---|---|
max_speakers= None | int | Nonegt=0 | Optional maximum number of speakers. |
FinalityCap#classSource
class FinalityCap(_CapNode)Streaming finality level the engine can guarantee.
| Name | Type | Description |
|---|---|---|
mode= 'final' | Literal['final', 'closed'] |
|
is_supported | bool | Whether a finality level is guaranteed (always |
FlagCap#classSource
class FlagCap(_FlagLikeNode)A simple supported / not-supported flag.
GuidanceCaps#classSource
class GuidanceCaps(_Container)Guidance-family capabilities for one mode.
| Name | Type | Description |
|---|---|---|
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]) -> boolReturn 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.
| Name | Type | Description |
|---|---|---|
granularities | Sequence[str] | The declared granularity list (possibly empty). |
boolTrueif the list is empty (unbounded -- every granularity offered).
LanguageCaps#classSource
class LanguageCaps(_Container)Language capabilities for one mode.
| Name | Type | Description |
|---|---|---|
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.
| Name | Type | Description |
|---|---|---|
constraints= PhraseHintsConstraints() | PhraseHintsConstraints | Limits when supported. |
supported | bool | Whether phrase hints are supported. |
PhraseHintsConstraints#classSource
class PhraseHintsConstraints(_JsonExtraModel)Constraints for the phrase-hints guidance channel.
| Name | Type | Description |
|---|---|---|
max_terms= None | int | Nonegt=0 | Optional maximum number of phrase-hint terms. |
max_chars_per_term= None | int | Nonegt=0 | Optional maximum characters per term. |
max_words_per_term= None | int | Nonegt=0 | Optional maximum words per term. |
PromptCap#classSource
class PromptCap(_FlagLikeNode)Guidance channel: free-text prompt.
| Name | Type | Description |
|---|---|---|
constraints= PromptConstraints() | PromptConstraints | Limits when supported. |
supported | bool | Whether prompt guidance is supported. |
PromptConstraints#classSource
class PromptConstraints(_JsonExtraModel)Constraints for the prompt guidance channel.
| Name | Type | Description |
|---|---|---|
max_tokens= None | int | Nonegt=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 |
ReconnectCap#classSource
class ReconnectCap(_CapNode)Streaming reconnect capability.
| Name | Type | Description |
|---|---|---|
mode= 'unsupported' | Literal['seamless', 'lossy', 'unsupported'] |
|
is_supported | bool | Whether reconnect is supported. |
StreamTimestampsCap#classSource
class StreamTimestampsCap(_CapNode)Source of streaming timestamps.
| Name | Type | Description |
|---|---|---|
mode= 'none' | Literal['native_frame_aligned', 'post_align', 'none'] |
|
is_supported | bool | Whether streaming timestamps are provided. |
StreamingCapabilities#classSource
class StreamingCapabilities(_Container)Capability tree for the streaming mode domain.
| Name | Type | Description |
|---|---|---|
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 |
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 |
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.
| Name | Type | Description |
|---|---|---|
mutable_mid_stream= FlagCap() | FlagCap | Whether guidance may be updated mid-session. |
prompt | PromptCap | Free-text prompt channel. |
phrase_hints | PhraseHintsCap | 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).
| Name | Type | Description |
|---|---|---|
granularities= lambda: cast('list[WordTimestampGranularityName]', [])() | list[WordTimestampGranularityName] | Supported granularities ( |
supported | bool | Whether word timestamps are supported. |