Member Junction
    Preparing search index...

    Function GetProviderVoiceSettings

    • Resolves the voice settings for a resolved realtime driver — the ONE place authored voice becomes a driver config bag, and the reason a host never has to know which vendor will run.

      Two sources, merged key-level:

      1. Provider-specific (RealtimeVoiceConfig.providers) — keys (openai, elevenlabs, gemini, assemblyai, …) are matched against the vendor DriverClass (e.g. OpenAIRealtime) by normalized-prefix: both sides are lowercased and stripped of non-alphanumerics, then the driver class must START WITH the provider key (openairealtime.startsWith(openai)). A bare provider name (e.g. 'openai' from ClientRealtimeSessionConfig.Provider) matches the same way. The LONGEST matching key wins when several match.
      2. Provider-agnostic — the persona's WIRE-level slots (RealtimeVoicePersona.voice and RealtimeVoicePersona.firstMessage) supply their own keys for whatever driver resolved, and OVERRIDE a matched provider entry's value for those keys.

      Each agnostic value wins its OWN key. The merge is per-key, so a matched provider bag's other (opaque) settings still ride along. When the persona authors no wire-level slot this is byte-for-byte the pre-#3530 behavior.

      "Opaque pact" describes what this function and the drivers DO with the bag at runtime — it is not a statement about what an author may write in agent metadata. The agent type's ConfigSchema declares providers.<key> with additionalProperties: false and only voice/voiceId, so a metadata-authored bag carrying anything else fails validation on save. Keys beyond voice therefore reach a driver only via runtime ConfigOverridesJson, which bypasses that validator. (Pre-existing asymmetry, not introduced here; loosening the schema is a separate call because it would relax validation for every existing config.)

      Known limitation. This runs AFTER the cascade has been deep-merged, so it has no layer provenance: "agnostic wins" is absolute, not "the higher layer wins". That is right for the case that exists — every host builder emits the agnostic form, so an agnostic value is always the session-scoped pick and must beat a vendor-pinned value authored in agent metadata. It is wrong for a config that HAND-AUTHORS a providers.<key>.voice in a RUNTIME override while agent metadata sets default.voice: the metadata would outrank the override. Nothing emits that shape today. Making it correct means resolving voice precedence per-layer inside ResolveEffectiveRealtimeConfig, which is where layer identity still exists.

      The same absoluteness produces a SAME-LAYER specificity inversion, which the schema permits: agent metadata authoring both default.voice (intended as a fallback) and providers.openai.voice (a pin) gets the general beating the specific — the inverse of normal config intuition. Only the runtime-override case actually NEEDS the agnostic value to win, so "agnostic is a fallback unless it came from a runtime override" would be more predictable; it is not implemented because it needs the same per-layer provenance described above. Until then the authoring rule is the one stated on RealtimeVoicePersona.voice: pin per-vendor OR author agnostic, not both.

      Callers that need to know whether an authored provider key actually MATCHED (rather than what the driver should receive) must use MatchProviderVoiceSettings — this function is truthy for every driver once an agnostic voice is set, so it cannot answer that question.

      Parameters

      • config: RealtimeCoAgentConfig

        The effective configuration.

      • driverClassOrProvider: string

        The vendor DriverClass or the provider key itself.

      Returns JSONObjectLike

      The settings object (opaque driver pact), or null when nothing applies.