Documentation
¶
Overview ¶
Package avatar implements provider-independent LiveKit avatar sessions and bounded PCM transports.
The canonical inference flow is:
- Construct an InferenceSession.
- Start it before starting voice.AgentSession.
- WaitForJoin until the avatar publishes video.
- Start the voice session and always Close the avatar during shutdown.
Rooms created with voice/roomio should pass roomioadapter.ReadyWaiter to the session. The adapter lives in a subpackage so queue/WebSocket avatar plugins do not import the raw-media codec stack during process startup.
Package avatar provides bounded voice I/O and lifecycle primitives for LiveKit avatar workers.
Index ¶
- Constants
- Variables
- func MarshalPlaybackFinishedPayload(event voice.PlaybackFinishedEvent) ([]byte, error)
- func ParsePlaybackFinishedPayload(payload string) voice.PlaybackFinishedEvent
- type AudioReceiver
- type AudioSegmentEnd
- type AvatarSession
- func (s *AvatarSession[UserData]) AClose(ctx context.Context) error
- func (s *AvatarSession[UserData]) AvatarIdentity() string
- func (s *AvatarSession[UserData]) Close(ctx context.Context) error
- func (s *AvatarSession[UserData]) OnMetrics(fn func(metrics.Avatar)) func()
- func (s *AvatarSession[UserData]) Provider() string
- func (s *AvatarSession[UserData]) RollbackStart(ctx context.Context) error
- func (s *AvatarSession[UserData]) Start(ctx context.Context, agent *voice.AgentSession[UserData], room *lksdk.Room) error
- func (s *AvatarSession[UserData]) WaitForJoin(ctx context.Context, options ...WaitForJoinOptions) error
- type AvatarSessionOptions
- type ByteStreamOptions
- type ByteStreamWriter
- type DataStreamAudioOutput
- func (o *DataStreamAudioOutput) AClose(ctx context.Context) error
- func (o *DataStreamAudioOutput) CanPause() bool
- func (o *DataStreamAudioOutput) CaptureFrame(ctx context.Context, frame agents.AudioFrame) error
- func (o *DataStreamAudioOutput) CapturedPlayoutSegments() uint64
- func (o *DataStreamAudioOutput) ClearBuffer(ctx context.Context) error
- func (o *DataStreamAudioOutput) Close(ctx context.Context) error
- func (o *DataStreamAudioOutput) Flush(ctx context.Context) error
- func (o *DataStreamAudioOutput) OnAttached()
- func (o *DataStreamAudioOutput) OnDetached()
- func (o *DataStreamAudioOutput) OnPlaybackFinished(fn func(voice.PlaybackFinishedEvent)) func()
- func (o *DataStreamAudioOutput) OnPlaybackStarted(fn func(voice.PlaybackStartedEvent)) func()
- func (o *DataStreamAudioOutput) Pause(ctx context.Context) error
- func (o *DataStreamAudioOutput) PendingPlayoutSegments() uint64
- func (o *DataStreamAudioOutput) Resume(ctx context.Context) error
- func (o *DataStreamAudioOutput) SampleRate() int
- func (o *DataStreamAudioOutput) SetAttached(attached bool)
- func (o *DataStreamAudioOutput) WaitForPlayout(ctx context.Context) (voice.PlaybackFinishedEvent, error)
- type DataStreamAudioOutputOptions
- type DataStreamTransport
- type InferenceSession
- func (s *InferenceSession[UserData]) AClose(ctx context.Context) error
- func (s *InferenceSession[UserData]) AudioOutput() *DataStreamAudioOutput
- func (s *InferenceSession[UserData]) AvatarIdentity() string
- func (s *InferenceSession[UserData]) Base() *AvatarSession[UserData]
- func (s *InferenceSession[UserData]) Close(ctx context.Context) error
- func (s *InferenceSession[UserData]) Gateway() *inference.AvatarSession
- func (s *InferenceSession[UserData]) Provider() string
- func (s *InferenceSession[UserData]) Start(ctx context.Context, agent *voice.AgentSession[UserData], room *lksdk.Room, ...) error
- func (s *InferenceSession[UserData]) WaitForJoin(ctx context.Context, options ...WaitForJoinOptions) error
- type InferenceSessionOptions
- type InferenceSessionStartOptions
- type ParticipantRemover
- type QueueAudioOutput
- func (o *QueueAudioOutput) AClose(context.Context) error
- func (o *QueueAudioOutput) CanPause() bool
- func (o *QueueAudioOutput) CaptureFrame(ctx context.Context, frame agents.AudioFrame) error
- func (o *QueueAudioOutput) CapturedPlayoutSegments() uint64
- func (o *QueueAudioOutput) ClearBuffer(ctx context.Context) error
- func (o *QueueAudioOutput) Close() error
- func (o *QueueAudioOutput) Closed() bool
- func (o *QueueAudioOutput) Flush(ctx context.Context) error
- func (o *QueueAudioOutput) NotifyPlaybackFinished(playbackPosition time.Duration, interrupted bool) error
- func (o *QueueAudioOutput) NotifyPlaybackFinishedEvent(event voice.PlaybackFinishedEvent) error
- func (o *QueueAudioOutput) NotifyPlaybackStarted(createdAt ...time.Time)
- func (o *QueueAudioOutput) OnAttached()
- func (o *QueueAudioOutput) OnClearBuffer(fn func(QueueAudioOutputClearEvent)) func()
- func (o *QueueAudioOutput) OnDetached()
- func (o *QueueAudioOutput) OnPlaybackFinished(fn func(voice.PlaybackFinishedEvent)) func()
- func (o *QueueAudioOutput) OnPlaybackStarted(fn func(voice.PlaybackStartedEvent)) func()
- func (o *QueueAudioOutput) Pause(ctx context.Context) error
- func (o *QueueAudioOutput) PendingPlayoutSegments() uint64
- func (o *QueueAudioOutput) Recv(ctx context.Context) (QueueAudioOutputItem, error)
- func (o *QueueAudioOutput) Resume(ctx context.Context) error
- func (o *QueueAudioOutput) SampleRate() int
- func (o *QueueAudioOutput) SetAttached(attached bool)
- func (o *QueueAudioOutput) Start(context.Context) error
- func (o *QueueAudioOutput) WaitForPlayout(ctx context.Context) (voice.PlaybackFinishedEvent, error)
- type QueueAudioOutputClearEvent
- type QueueAudioOutputItem
- type QueueAudioOutputOptions
- type RPCInvocation
- type ReadyWaiter
- type WaitForJoinOptions
Constants ¶
const ( RPCClearBuffer = "lk.clear_buffer" RPCPlaybackFinished = "lk.playback_finished" RPCPlaybackStarted = "lk.playback_started" AudioStreamTopic = "lk.audio_stream" )
const DefaultClearBufferTimeout = 2 * time.Second
const DefaultQueueAudioCapacity = 64
const DefaultWaitForJoinTimeout = 30 * time.Second
Variables ¶
var ( ErrDataStreamAudioOutputClosed = errors.New("avatar DataStream audio output is closed") ErrAvatarRTCBridgeRequired = errors.New("avatar RTC bridge is required while waiting for a participant or track") )
var ( ErrAvatarSessionActive = errors.New("avatar session is already active") ErrAvatarJoinTimeout = errors.New("timed out waiting for avatar participant") )
var ErrQueueAudioOutputClosed = errors.New("avatar queue audio output is closed")
Functions ¶
func MarshalPlaybackFinishedPayload ¶
func MarshalPlaybackFinishedPayload(event voice.PlaybackFinishedEvent) ([]byte, error)
MarshalPlaybackFinishedPayload emits the Python AvatarRunner's canonical snake_case protocol with playback_position represented in seconds.
func ParsePlaybackFinishedPayload ¶
func ParsePlaybackFinishedPayload(payload string) voice.PlaybackFinishedEvent
ParsePlaybackFinishedPayload is deliberately total: malformed input yields a safe zero event so an RPC handler can always release WaitForPlayout. The protocol-canonical snake_case fields are preferred, with camelCase accepted for JavaScript producers.
Types ¶
type AudioReceiver ¶
type AudioReceiver interface {
stream.Reader[QueueAudioOutputItem]
Start(context.Context) error
OnClearBuffer(func(QueueAudioOutputClearEvent)) func()
NotifyPlaybackStarted(...time.Time)
NotifyPlaybackFinished(time.Duration, bool) error
Close() error
}
AudioReceiver is the provider-worker side of queue I/O. DataStream receivers require stronger RTC reader cancellation than server-sdk-go v2.18.1 exposes, while QueueAudioOutput implements this interface without background work.
type AudioSegmentEnd ¶
type AudioSegmentEnd struct{}
AudioSegmentEnd marks the ordered boundary after one flushed or interrupted audio segment.
type AvatarSession ¶
type AvatarSession[UserData any] struct { // contains filtered or unexported fields }
AvatarSession owns the provider-independent avatar lifecycle. The generic parameter matches AgentSession user data and enables typed job shutdown registration without a process-global job context.
func NewAvatarSession ¶
func NewAvatarSession[UserData any](options AvatarSessionOptions) *AvatarSession[UserData]
func (*AvatarSession[UserData]) AClose ¶
func (s *AvatarSession[UserData]) AClose(ctx context.Context) error
AClose is the Python/TypeScript-compatible spelling.
func (*AvatarSession[UserData]) AvatarIdentity ¶
func (s *AvatarSession[UserData]) AvatarIdentity() string
func (*AvatarSession[UserData]) Close ¶
func (s *AvatarSession[UserData]) Close(ctx context.Context) error
Close removes the room participant when credentials/remover are available, then always rolls back local state. Not-found is benign; other removal errors are logged to match the pinned Python/TypeScript lifecycle contract.
func (*AvatarSession[UserData]) OnMetrics ¶
func (s *AvatarSession[UserData]) OnMetrics(fn func(metrics.Avatar)) func()
func (*AvatarSession[UserData]) Provider ¶
func (s *AvatarSession[UserData]) Provider() string
func (*AvatarSession[UserData]) RollbackStart ¶
func (s *AvatarSession[UserData]) RollbackStart(ctx context.Context) error
RollbackStart releases only local lifecycle state. It intentionally does not remove the participant and is safe after an ambiguous gateway create failure.
func (*AvatarSession[UserData]) Start ¶
func (s *AvatarSession[UserData]) Start(ctx context.Context, agent *voice.AgentSession[UserData], room *lksdk.Room) error
Start attaches lifecycle and metrics tracking. Provider implementations should call this before provisioning and RollbackStart if provisioning fails.
func (*AvatarSession[UserData]) WaitForJoin ¶
func (s *AvatarSession[UserData]) WaitForJoin(ctx context.Context, options ...WaitForJoinOptions) error
type AvatarSessionOptions ¶
type AvatarSessionOptions struct {
AvatarIdentity string
Provider string
ParentContext context.Context
ReadyWaiter ReadyWaiter
RemoveParticipant ParticipantRemover
Logger *slog.Logger
}
type ByteStreamOptions ¶
type ByteStreamWriter ¶
type DataStreamAudioOutput ¶
type DataStreamAudioOutput struct {
// contains filtered or unexported fields
}
DataStreamAudioOutput sends strict little-endian PCM16 in one bounded RTC byte stream per speech segment and uses avatar RPCs for playout accounting.
func NewDataStreamAudioOutput ¶
func NewDataStreamAudioOutput(options DataStreamAudioOutputOptions) (*DataStreamAudioOutput, error)
func (*DataStreamAudioOutput) AClose ¶
func (o *DataStreamAudioOutput) AClose(ctx context.Context) error
func (*DataStreamAudioOutput) CanPause ¶
func (o *DataStreamAudioOutput) CanPause() bool
func (*DataStreamAudioOutput) CaptureFrame ¶
func (o *DataStreamAudioOutput) CaptureFrame(ctx context.Context, frame agents.AudioFrame) error
func (*DataStreamAudioOutput) CapturedPlayoutSegments ¶
func (o *DataStreamAudioOutput) CapturedPlayoutSegments() uint64
func (*DataStreamAudioOutput) ClearBuffer ¶
func (o *DataStreamAudioOutput) ClearBuffer(ctx context.Context) error
func (*DataStreamAudioOutput) Close ¶
func (o *DataStreamAudioOutput) Close(ctx context.Context) error
func (*DataStreamAudioOutput) Flush ¶
func (o *DataStreamAudioOutput) Flush(ctx context.Context) error
func (*DataStreamAudioOutput) OnAttached ¶
func (o *DataStreamAudioOutput) OnAttached()
func (*DataStreamAudioOutput) OnDetached ¶
func (o *DataStreamAudioOutput) OnDetached()
func (*DataStreamAudioOutput) OnPlaybackFinished ¶
func (o *DataStreamAudioOutput) OnPlaybackFinished(fn func(voice.PlaybackFinishedEvent)) func()
func (*DataStreamAudioOutput) OnPlaybackStarted ¶
func (o *DataStreamAudioOutput) OnPlaybackStarted(fn func(voice.PlaybackStartedEvent)) func()
func (*DataStreamAudioOutput) Pause ¶
func (o *DataStreamAudioOutput) Pause(ctx context.Context) error
func (*DataStreamAudioOutput) PendingPlayoutSegments ¶
func (o *DataStreamAudioOutput) PendingPlayoutSegments() uint64
func (*DataStreamAudioOutput) Resume ¶
func (o *DataStreamAudioOutput) Resume(ctx context.Context) error
func (*DataStreamAudioOutput) SampleRate ¶
func (o *DataStreamAudioOutput) SampleRate() int
func (*DataStreamAudioOutput) SetAttached ¶
func (o *DataStreamAudioOutput) SetAttached(attached bool)
func (*DataStreamAudioOutput) WaitForPlayout ¶
func (o *DataStreamAudioOutput) WaitForPlayout(ctx context.Context) (voice.PlaybackFinishedEvent, error)
type DataStreamTransport ¶
type DataStreamTransport interface {
WaitReady(context.Context, string, lksdk.TrackKind) error
OpenByteStream(context.Context, ByteStreamOptions) (ByteStreamWriter, error)
PerformRPC(context.Context, string, string, string) (string, error)
RegisterRPC(string, string, func(RPCInvocation) string) (func(), error)
}
DataStreamTransport isolates RTC mechanics for deterministic tests and custom room implementations. RegisterRPC must multiplex identities for the same method and return an idempotent unregister function.
type InferenceSession ¶
type InferenceSession[UserData any] struct { // contains filtered or unexported fields }
InferenceSession is the one-step voice adapter around the cycle-free inference.AvatarSession gateway lifecycle.
func NewInferenceSession ¶
func NewInferenceSession[UserData any](options InferenceSessionOptions) (*InferenceSession[UserData], error)
func (*InferenceSession[UserData]) AClose ¶
func (s *InferenceSession[UserData]) AClose(ctx context.Context) error
func (*InferenceSession[UserData]) AudioOutput ¶
func (s *InferenceSession[UserData]) AudioOutput() *DataStreamAudioOutput
func (*InferenceSession[UserData]) AvatarIdentity ¶
func (s *InferenceSession[UserData]) AvatarIdentity() string
func (*InferenceSession[UserData]) Base ¶
func (s *InferenceSession[UserData]) Base() *AvatarSession[UserData]
func (*InferenceSession[UserData]) Close ¶
func (s *InferenceSession[UserData]) Close(ctx context.Context) error
func (*InferenceSession[UserData]) Gateway ¶
func (s *InferenceSession[UserData]) Gateway() *inference.AvatarSession
func (*InferenceSession[UserData]) Provider ¶
func (s *InferenceSession[UserData]) Provider() string
func (*InferenceSession[UserData]) Start ¶
func (s *InferenceSession[UserData]) Start(ctx context.Context, agent *voice.AgentSession[UserData], room *lksdk.Room, options ...InferenceSessionStartOptions) error
func (*InferenceSession[UserData]) WaitForJoin ¶
func (s *InferenceSession[UserData]) WaitForJoin(ctx context.Context, options ...WaitForJoinOptions) error
type InferenceSessionOptions ¶
type InferenceSessionOptions struct {
Gateway inference.AvatarSessionOptions
ParentContext context.Context
ReadyWaiter ReadyWaiter
RemoveParticipant ParticipantRemover
Logger *slog.Logger
}
type InferenceSessionStartOptions ¶
type InferenceSessionStartOptions struct {
LiveKitURL string
}
type QueueAudioOutput ¶
type QueueAudioOutput struct {
// contains filtered or unexported fields
}
QueueAudioOutput is a bounded, single-stream AudioOutput for provider WebSocket adapters and AvatarRunner implementations. Capture, Flush, and ClearBuffer are linearized so a clear can never erase the boundary of the next segment.
func NewQueueAudioOutput ¶
func NewQueueAudioOutput(options QueueAudioOutputOptions) (*QueueAudioOutput, error)
func (*QueueAudioOutput) AClose ¶
func (o *QueueAudioOutput) AClose(context.Context) error
AClose is the Python/TypeScript-compatible spelling.
func (*QueueAudioOutput) CanPause ¶
func (o *QueueAudioOutput) CanPause() bool
func (*QueueAudioOutput) CaptureFrame ¶
func (o *QueueAudioOutput) CaptureFrame(ctx context.Context, frame agents.AudioFrame) error
func (*QueueAudioOutput) CapturedPlayoutSegments ¶
func (o *QueueAudioOutput) CapturedPlayoutSegments() uint64
func (*QueueAudioOutput) ClearBuffer ¶
func (o *QueueAudioOutput) ClearBuffer(ctx context.Context) error
func (*QueueAudioOutput) Close ¶
func (o *QueueAudioOutput) Close() error
Close gracefully closes the readable stream after already accepted items. It is idempotent and unblocks producers currently applying backpressure.
func (*QueueAudioOutput) Closed ¶
func (o *QueueAudioOutput) Closed() bool
func (*QueueAudioOutput) NotifyPlaybackFinished ¶
func (o *QueueAudioOutput) NotifyPlaybackFinished(playbackPosition time.Duration, interrupted bool) error
NotifyPlaybackFinished mirrors the Python/TypeScript transport callback.
func (*QueueAudioOutput) NotifyPlaybackFinishedEvent ¶
func (o *QueueAudioOutput) NotifyPlaybackFinishedEvent(event voice.PlaybackFinishedEvent) error
NotifyPlaybackFinishedEvent additionally preserves synchronized transcript.
func (*QueueAudioOutput) NotifyPlaybackStarted ¶
func (o *QueueAudioOutput) NotifyPlaybackStarted(createdAt ...time.Time)
func (*QueueAudioOutput) OnAttached ¶
func (o *QueueAudioOutput) OnAttached()
func (*QueueAudioOutput) OnClearBuffer ¶
func (o *QueueAudioOutput) OnClearBuffer(fn func(QueueAudioOutputClearEvent)) func()
func (*QueueAudioOutput) OnDetached ¶
func (o *QueueAudioOutput) OnDetached()
func (*QueueAudioOutput) OnPlaybackFinished ¶
func (o *QueueAudioOutput) OnPlaybackFinished(fn func(voice.PlaybackFinishedEvent)) func()
func (*QueueAudioOutput) OnPlaybackStarted ¶
func (o *QueueAudioOutput) OnPlaybackStarted(fn func(voice.PlaybackStartedEvent)) func()
func (*QueueAudioOutput) PendingPlayoutSegments ¶
func (o *QueueAudioOutput) PendingPlayoutSegments() uint64
func (*QueueAudioOutput) Recv ¶
func (o *QueueAudioOutput) Recv(ctx context.Context) (QueueAudioOutputItem, error)
Recv reads from the one shared stream. Multiple concurrent readers split items rather than broadcast them and should only be used intentionally.
func (*QueueAudioOutput) SampleRate ¶
func (o *QueueAudioOutput) SampleRate() int
func (*QueueAudioOutput) SetAttached ¶
func (o *QueueAudioOutput) SetAttached(attached bool)
func (*QueueAudioOutput) Start ¶
func (o *QueueAudioOutput) Start(context.Context) error
Start satisfies the receiver side of the Python queue-I/O contract. Queue output is ready immediately and owns no background goroutine.
func (*QueueAudioOutput) WaitForPlayout ¶
func (o *QueueAudioOutput) WaitForPlayout(ctx context.Context) (voice.PlaybackFinishedEvent, error)
type QueueAudioOutputClearEvent ¶
type QueueAudioOutputClearEvent struct {
WasCapturing bool
}
type QueueAudioOutputItem ¶
type QueueAudioOutputItem struct {
Frame agents.AudioFrame
SegmentEnd bool
}
QueueAudioOutputItem is a type-safe union. Exactly one of Frame or SegmentEnd is meaningful; SegmentEnd avoids a pointer allocation per marker.
func AudioFrameItem ¶
func AudioFrameItem(frame agents.AudioFrame) QueueAudioOutputItem
func AudioSegmentEndItem ¶
func AudioSegmentEndItem() QueueAudioOutputItem
type QueueAudioOutputOptions ¶
type RPCInvocation ¶
type ReadyWaiter ¶
ReadyWaiter bridges the server SDK's lack of post-construction Room callback registration. It is only needed when the destination has not already joined. voice/avatar/roomioadapter provides one for roomio.RTCBridge.
type WaitForJoinOptions ¶
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package roomioadapter connects avatar readiness waits to a roomio RTCBridge.
|
Package roomioadapter connects avatar readiness waits to a roomio RTCBridge. |