Codex.Voice.Result (Codex SDK v0.7.2)

Copy Markdown View Source

Streamed audio result from a voice pipeline.

This module provides the output type for voice pipelines. Results are streamed as events that can be consumed incrementally, allowing for real-time audio playback while the pipeline is still processing.

Usage

{:ok, result} = Pipeline.run(pipeline, audio_input)

result
|> Result.stream()
|> Enum.each(fn event ->
  case event do
    %VoiceStreamEventAudio{data: data} ->
      play_audio(data)

    %VoiceStreamEventLifecycle{event: :turn_ended} ->
      IO.puts("Turn completed")

    %VoiceStreamEventLifecycle{event: :session_ended} ->
      IO.puts("Session ended")

    %VoiceStreamEventError{error: error} ->
      Logger.error("Error: #{inspect(error)}")
  end
end)

Architecture

The result uses an Agent-backed queue to buffer events between the pipeline producer and the consumer. The pipeline runs in a Task and pushes events to the queue, while stream/1 consumes them.

Summary

Functions

Create a new streamed result.

Stream events from the result.

Types

t()

@type t() :: %Codex.Voice.Result{
  config: Codex.Voice.Config.t(),
  queue: pid(),
  task: term() | nil,
  total_output_text: String.t(),
  tts_model: struct(),
  tts_settings: Codex.Voice.Config.TTSSettings.t()
}

Functions

new(tts_model, tts_settings, config)

Create a new streamed result.

Parameters

  • tts_model - The TTS model to use for converting text to audio
  • tts_settings - Settings for the TTS model
  • config - Voice pipeline configuration

Examples

tts_model = OpenAITTS.new()
tts_settings = TTSSettings.new(voice: :nova)
config = Config.new()

result = Result.new(tts_model, tts_settings, config)

stream(result)

@spec stream(t()) :: Enumerable.t()

Stream events from the result.

Returns a Stream that yields VoiceStreamEvent structs as they become available. The stream completes when the pipeline signals completion with a session_ended lifecycle event.

Note: If the queue is empty and the pipeline is still producing, this will poll with a 10ms delay. For high-performance use cases, consider using a different consumption strategy.

Examples

result
|> Result.stream()
|> Enum.each(&handle_event/1)