Documentation
¶
Overview ¶
Package turns manages the user-turn lifecycle, ported from Pipecat's turns subsystem. A UserTurnProcessor drives a UserTurnController (which runs pluggable start and stop strategies) and a UserIdleController. Turn detection is decoupled: voice activity comes from a vad.Processor upstream as VADUser*SpeakingFrames, and the end-of-turn model lives inside a stop strategy; the subsystem reasons over frames, not raw audio (except the turn-analyzer stop strategy, which is fed InputAudioRawFrames).
Index ¶
- Constants
- func CompletionInstructions(cfg UserTurnCompletionConfig) string
- type AlwaysUserMute
- type CompletionFilter
- type Config
- type ControllerHooks
- type Emitter
- type ExternalCompletionStop
- type ExternalStart
- type ExternalStop
- type ExternalStopConfig
- type FirstSpeechUserMute
- type FunctionCallUserMute
- type IdleCallback
- type IdleConfig
- type MinWordsStart
- type MinWordsStartConfig
- type MuteStrategy
- type MuteUntilFirstBotComplete
- type ProcessFrameResult
- type SpeechTimeoutConfig
- type SpeechTimeoutStop
- type StartStrategy
- type StartStrategyBase
- type StopStrategy
- type StopStrategyBase
- func (b *StopStrategyBase) Broadcast(f frames.Frame)
- func (b *StopStrategyBase) Cleanup()
- func (b *StopStrategyBase) Push(f frames.Frame, dir processor.Direction)
- func (b *StopStrategyBase) Reset()
- func (b *StopStrategyBase) TriggerFinalized()
- func (b *StopStrategyBase) TriggerInferenceTriggered()
- func (b *StopStrategyBase) TriggerStopped()
- type TranscriptionStart
- type TranscriptionStartConfig
- type TurnAnalyzerConfig
- type TurnAnalyzerStop
- type UserIdleController
- func (c *UserIdleController) Broadcast(ctx context.Context, f frames.Frame) error
- func (c *UserIdleController) Cleanup()
- func (c *UserIdleController) Process(f frames.Frame)
- func (c *UserIdleController) Push(ctx context.Context, f frames.Frame, dir processor.Direction) error
- func (c *UserIdleController) Setup(ctx context.Context, emit Emitter)
- type UserTurnCompletionConfig
- type UserTurnController
- type UserTurnProcessor
- func (p *UserTurnProcessor) Broadcast(ctx context.Context, f frames.Frame) error
- func (p *UserTurnProcessor) Cleanup(ctx context.Context) error
- func (p *UserTurnProcessor) ProcessFrame(ctx context.Context, f frames.Frame, dir processor.Direction) error
- func (p *UserTurnProcessor) Push(ctx context.Context, f frames.Frame, dir processor.Direction) error
- func (p *UserTurnProcessor) Setup(ctx context.Context, s processor.Setup) error
- type UserTurnStartedParams
- type UserTurnStoppedParams
- type UserTurnStrategies
- type VADStart
- type WakePhraseStart
- type WakePhraseStartConfig
Constants ¶
const (
// MarkerComplete means the user's turn was complete; respond normally.
MarkerComplete = "✓"
)
Turn-completion markers the LLM is instructed to prefix its reply with.
Variables ¶
This section is empty.
Functions ¶
func CompletionInstructions ¶
func CompletionInstructions(cfg UserTurnCompletionConfig) string
CompletionInstructions returns the marker-protocol instructions to prepend to the LLM system prompt for turn-completion gating.
Types ¶
type AlwaysUserMute ¶
type AlwaysUserMute struct {
// contains filtered or unexported fields
}
AlwaysUserMute mutes the user whenever the bot is speaking.
func NewAlwaysUserMute ¶
func NewAlwaysUserMute() *AlwaysUserMute
NewAlwaysUserMute builds an always-while-bot-speaking mute strategy.
func (*AlwaysUserMute) ShouldMute ¶
func (s *AlwaysUserMute) ShouldMute(f frames.Frame) bool
ShouldMute reports muted while the bot speaks.
type CompletionFilter ¶
CompletionFilter parses the LLM's turn-completion markers in its streamed output. On "✓" it broadcasts a UserTurnInferenceCompletedFrame (which a FilterIncompleteUserTurnStrategies finalizer turns into the user's turn end) and forwards the reply; on "○"/"◐" it suppresses the reply and, after a timeout, re-prompts the LLM. Place it immediately after the LLM service.
func NewCompletionFilter ¶
func NewCompletionFilter(cfg UserTurnCompletionConfig) *CompletionFilter
NewCompletionFilter builds a turn-completion filter.
func (*CompletionFilter) Cleanup ¶
func (f *CompletionFilter) Cleanup(ctx context.Context) error
Cleanup stops any pending re-prompt timer.
func (*CompletionFilter) ProcessFrame ¶
func (f *CompletionFilter) ProcessFrame(ctx context.Context, fr frames.Frame, dir processor.Direction) error
ProcessFrame parses markers in the LLM output stream.
type Config ¶
type Config struct {
// Strategies are the start/stop strategy chains; the zero value uses the
// defaults (VAD + transcription start, Smart-Turn stop) — but the Smart-Turn
// default needs a turn.Analyzer, so most callers build Strategies explicitly.
Strategies UserTurnStrategies
// StopTimeout is the watchdog that force-stops a stuck turn; 0 uses 5s.
StopTimeout time.Duration
// IdleTimeout enables the idle watchdog; a value <= 0 disables it.
IdleTimeout time.Duration
// OnIdle fires when the conversation goes idle. Required to enable idle.
OnIdle IdleCallback
// MuteStrategies suppress user input while engaged (e.g. while the bot
// speaks or a tool call runs). They are OR-reduced; empty means never mute.
MuteStrategies []MuteStrategy
}
Config configures a UserTurnProcessor.
type ControllerHooks ¶
type ControllerHooks struct {
Started func(ctx context.Context, params UserTurnStartedParams)
Stopped func(ctx context.Context, params UserTurnStoppedParams)
InferenceTriggered func(ctx context.Context)
StopTimeout func(ctx context.Context)
ResetAggregation func(ctx context.Context)
Push func(ctx context.Context, f frames.Frame, dir processor.Direction)
Broadcast func(ctx context.Context, f frames.Frame)
}
ControllerHooks are the callbacks the controller invokes upward (to the UserTurnProcessor). They all run with the controller's mutex held.
type Emitter ¶
type Emitter interface {
// Push sends a frame to the neighbor in dir.
Push(ctx context.Context, f frames.Frame, dir processor.Direction) error
// Broadcast sends a frame both downstream and upstream.
Broadcast(ctx context.Context, f frames.Frame) error
}
Emitter lets a controller or strategy push frames into the pipeline. The UserTurnProcessor implements it. Broadcast sends a frame both downstream and upstream (the analog of Pipecat's broadcast_frame), which is how turn decisions and interruptions reach the whole pipeline.
type ExternalCompletionStop ¶
type ExternalCompletionStop struct {
StopStrategyBase
}
ExternalCompletionStop finalizes a turn when an external judge emits a UserTurnInferenceCompletedFrame. It is the base for LLM-gated completion.
func NewExternalCompletionStop ¶
func NewExternalCompletionStop() *ExternalCompletionStop
NewExternalCompletionStop builds an external-completion stop strategy.
func (*ExternalCompletionStop) Process ¶
func (s *ExternalCompletionStop) Process(f frames.Frame) ProcessFrameResult
Process finalizes the turn on a completion frame.
type ExternalStart ¶
type ExternalStart struct {
StartStrategyBase
}
ExternalStart relays a turn-start decided by another processor (it triggers on an inbound UserStartedSpeakingFrame) without re-emitting speaking frames or interruptions.
func NewExternalStart ¶
func NewExternalStart() *ExternalStart
NewExternalStart builds an external start strategy.
func (*ExternalStart) Process ¶
func (s *ExternalStart) Process(f frames.Frame) ProcessFrameResult
Process triggers on an inbound user-started frame.
type ExternalStop ¶
type ExternalStop struct {
StopStrategyBase
// contains filtered or unexported fields
}
ExternalStop ends a turn when another processor emits a UserStoppedSpeakingFrame.
func NewExternalStop ¶
func NewExternalStop(cfg ExternalStopConfig) *ExternalStop
NewExternalStop builds an external stop strategy.
func (*ExternalStop) Process ¶
func (s *ExternalStop) Process(f frames.Frame) ProcessFrameResult
Process relays an external stop, debounced for late transcripts.
type ExternalStopConfig ¶
type ExternalStopConfig struct {
// Timeout debounces late transcripts after the external stop; 0 uses 500ms.
Timeout time.Duration
// WaitForTranscript holds the turn open until a transcript arrives; nil
// defaults to true.
WaitForTranscript *bool
}
ExternalStopConfig configures an ExternalStop strategy.
type FirstSpeechUserMute ¶
type FirstSpeechUserMute struct {
// contains filtered or unexported fields
}
FirstSpeechUserMute mutes the user only during the bot's first speaking turn, allowing pre-speech input and never muting afterward.
func NewFirstSpeechUserMute ¶
func NewFirstSpeechUserMute() *FirstSpeechUserMute
NewFirstSpeechUserMute builds a first-speech mute strategy.
func (*FirstSpeechUserMute) ShouldMute ¶
func (s *FirstSpeechUserMute) ShouldMute(f frames.Frame) bool
ShouldMute reports muted only during the bot's first speech.
type FunctionCallUserMute ¶
type FunctionCallUserMute struct {
// contains filtered or unexported fields
}
FunctionCallUserMute mutes the user while any tool call is in flight.
func NewFunctionCallUserMute ¶
func NewFunctionCallUserMute() *FunctionCallUserMute
NewFunctionCallUserMute builds a function-call mute strategy.
func (*FunctionCallUserMute) ShouldMute ¶
func (s *FunctionCallUserMute) ShouldMute(f frames.Frame) bool
ShouldMute reports muted while one or more tool calls are running.
type IdleCallback ¶
type IdleCallback func(ctx context.Context, c *UserIdleController) error
IdleCallback runs when the conversation has stayed quiet past the configured timeout. It receives the controller so it can Push or Broadcast frames (a reminder, or an EndFrame to hang up). It runs off the frame path. Following Pipecat, it fires once per arming; escalation/retry, if wanted, is the caller's responsibility.
type IdleConfig ¶
type IdleConfig struct {
// Timeout is how long the conversation may stay quiet after the bot stops
// speaking before Callback fires. A value <= 0 disables idle detection.
Timeout time.Duration
// Callback fires on idle. A nil callback disables idle detection.
Callback IdleCallback
}
IdleConfig configures a UserIdleController.
type MinWordsStart ¶
type MinWordsStart struct {
StartStrategyBase
// contains filtered or unexported fields
}
MinWordsStart opens a turn only once enough words are heard, raising the bar for interrupting the bot.
func NewMinWordsStart ¶
func NewMinWordsStart(cfg MinWordsStartConfig) *MinWordsStart
NewMinWordsStart builds a min-words start strategy.
func (*MinWordsStart) Process ¶
func (s *MinWordsStart) Process(f frames.Frame) ProcessFrameResult
Process counts words and triggers once the threshold is met.
type MinWordsStartConfig ¶
type MinWordsStartConfig struct {
// MinWords is the word count required to open a turn while the bot is
// speaking (to gate barge-in); a single word suffices when the bot is silent.
MinWords int
// UseInterim counts interim transcripts too; nil defaults to true.
UseInterim *bool
}
MinWordsStartConfig configures a MinWordsStart strategy.
type MuteStrategy ¶
MuteStrategy decides whether user input should be suppressed right now. ShouldMute is called for every frame (so the strategy can track state) and returns the muted state as of that frame. The UserTurnProcessor OR-reduces all strategies and, while muted, drops the user-input frames before they reach turn detection — so the user can neither barge in nor pollute the context at the wrong moment. Strategies are driven only from the processor (under its mute mutex) and need no locking of their own.
type MuteUntilFirstBotComplete ¶
type MuteUntilFirstBotComplete struct {
// contains filtered or unexported fields
}
MuteUntilFirstBotComplete mutes the user from the start of the session until the bot finishes its first speech.
func NewMuteUntilFirstBotComplete ¶
func NewMuteUntilFirstBotComplete() *MuteUntilFirstBotComplete
NewMuteUntilFirstBotComplete builds a mute-until-first-bot-complete strategy.
func (*MuteUntilFirstBotComplete) ShouldMute ¶
func (s *MuteUntilFirstBotComplete) ShouldMute(f frames.Frame) bool
ShouldMute reports muted until the bot's first speech completes.
type ProcessFrameResult ¶
type ProcessFrameResult int
ProcessFrameResult is what a strategy returns from Process to control the per-frame strategy loop.
const ( // Continue evaluates the next strategy in the chain. Continue ProcessFrameResult = iota // Stop short-circuits the remaining strategies for this frame. Stop )
type SpeechTimeoutConfig ¶
type SpeechTimeoutConfig struct {
// UserSpeechTimeout is the silence the user gets to resume after the VAD
// stops; 0 uses 600ms.
UserSpeechTimeout time.Duration
// WaitForTranscript holds the turn open until a transcript arrives; nil
// defaults to true.
WaitForTranscript *bool
}
SpeechTimeoutConfig configures a SpeechTimeoutStop strategy.
type SpeechTimeoutStop ¶
type SpeechTimeoutStop struct {
StopStrategyBase
// contains filtered or unexported fields
}
SpeechTimeoutStop ends a turn purely on silence timers after the VAD reports the user stopped — no model. It is the model-free default stop strategy.
func NewSpeechTimeoutStop ¶
func NewSpeechTimeoutStop(cfg SpeechTimeoutConfig) *SpeechTimeoutStop
NewSpeechTimeoutStop builds a speech-timeout stop strategy.
func (*SpeechTimeoutStop) Process ¶
func (s *SpeechTimeoutStop) Process(f frames.Frame) ProcessFrameResult
Process runs the silence timers and decides end-of-turn.
type StartStrategy ¶
type StartStrategy interface {
// Process examines one frame; returning Stop short-circuits the start chain
// for that frame. It runs with the shared mutex held.
Process(f frames.Frame) ProcessFrameResult
// Reset clears per-turn state at the start of each turn.
Reset()
// Cleanup releases resources (timers).
Cleanup()
// contains filtered or unexported methods
}
StartStrategy decides when the user's turn begins. Concrete strategies embed StartStrategyBase and implement Process.
func DefaultStartStrategies ¶
func DefaultStartStrategies() []StartStrategy
DefaultStartStrategies returns the default start chain: VAD onset, with transcription as a fallback for soft speech the VAD misses.
type StartStrategyBase ¶
type StartStrategyBase struct {
// EnableInterruptions broadcasts an InterruptionFrame on turn start.
EnableInterruptions bool
// EnableUserSpeakingFrames broadcasts a UserStartedSpeakingFrame on turn start.
EnableUserSpeakingFrames bool
// contains filtered or unexported fields
}
StartStrategyBase is embedded by every start strategy. It carries the open-turn flags and the trigger helpers.
func (*StartStrategyBase) Cleanup ¶
func (b *StartStrategyBase) Cleanup()
Cleanup is the default no-op.
func (*StartStrategyBase) TriggerResetAggregation ¶
func (b *StartStrategyBase) TriggerResetAggregation()
TriggerResetAggregation asks the user aggregator to drop the in-progress aggregation (e.g. pre-wake-phrase speech).
func (*StartStrategyBase) TriggerStarted ¶
func (b *StartStrategyBase) TriggerStarted()
TriggerStarted signals that the user's turn has begun.
type StopStrategy ¶
type StopStrategy interface {
// Process examines one frame; returning Stop short-circuits the stop chain.
// Stop strategies usually return Continue and signal via Trigger*. It runs
// with the shared mutex held.
Process(f frames.Frame) ProcessFrameResult
// Reset clears per-turn state.
Reset()
// Cleanup releases resources (timers).
Cleanup()
// contains filtered or unexported methods
}
StopStrategy decides when the user's turn ends. Concrete strategies embed StopStrategyBase and implement Process.
func DefaultStopStrategies ¶
func DefaultStopStrategies() []StopStrategy
DefaultStopStrategies returns the default, model-free stop chain: a speech-timeout after VAD stop. For Smart-Turn, pass a chain built with NewTurnAnalyzerStop instead.
func Deferred ¶
func Deferred(inner StopStrategy) StopStrategy
Deferred wraps inner so it can drive inference-triggering but never finalize a turn; pair it with a finalizer such as ExternalCompletionStop.
func NewLLMTurnCompletionStop ¶
func NewLLMTurnCompletionStop() StopStrategy
NewLLMTurnCompletionStop builds the stop strategy that finalizes a turn when the CompletionFilter broadcasts a completion. Pair it with deferred detectors via FilterIncompleteUserTurnStrategies.
type StopStrategyBase ¶
type StopStrategyBase struct {
// EnableUserSpeakingFrames broadcasts a UserStoppedSpeakingFrame on turn stop.
EnableUserSpeakingFrames bool
// contains filtered or unexported fields
}
StopStrategyBase is embedded by every stop strategy.
func (*StopStrategyBase) Broadcast ¶
func (b *StopStrategyBase) Broadcast(f frames.Frame)
Broadcast sends a frame both downstream and upstream.
func (*StopStrategyBase) Cleanup ¶
func (b *StopStrategyBase) Cleanup()
Cleanup is the default no-op.
func (*StopStrategyBase) Push ¶
func (b *StopStrategyBase) Push(f frames.Frame, dir processor.Direction)
Push sends a frame to the neighbor in dir.
func (*StopStrategyBase) TriggerFinalized ¶
func (b *StopStrategyBase) TriggerFinalized()
TriggerFinalized signals that the turn is semantically final.
func (*StopStrategyBase) TriggerInferenceTriggered ¶
func (b *StopStrategyBase) TriggerInferenceTriggered()
TriggerInferenceTriggered signals that there is enough evidence to start LLM inference, without finalizing the turn.
func (*StopStrategyBase) TriggerStopped ¶
func (b *StopStrategyBase) TriggerStopped()
TriggerStopped fires inference-triggered then finalized — the usual "turn is over" signal.
type TranscriptionStart ¶
type TranscriptionStart struct {
StartStrategyBase
// contains filtered or unexported fields
}
TranscriptionStart opens a turn on a transcript, a fallback for soft speech a VAD misses.
func NewTranscriptionStart ¶
func NewTranscriptionStart(cfg TranscriptionStartConfig) *TranscriptionStart
NewTranscriptionStart builds a transcription-based start strategy.
func (*TranscriptionStart) Process ¶
func (s *TranscriptionStart) Process(f frames.Frame) ProcessFrameResult
Process triggers the turn on a transcript.
type TranscriptionStartConfig ¶
type TranscriptionStartConfig struct {
// UseInterim also triggers on interim transcripts; nil defaults to true.
UseInterim *bool
}
TranscriptionStartConfig configures a TranscriptionStart strategy.
type TurnAnalyzerConfig ¶
type TurnAnalyzerConfig struct {
// Analyzer is the end-of-turn model (e.g. Smart Turn V3). Required.
Analyzer turn.Analyzer
// WaitForTranscript holds the turn open until a transcript arrives; nil
// defaults to true. Set false for realtime services that bypass STT.
WaitForTranscript *bool
}
TurnAnalyzerConfig configures a TurnAnalyzerStop strategy.
type TurnAnalyzerStop ¶
type TurnAnalyzerStop struct {
StopStrategyBase
// contains filtered or unexported fields
}
TurnAnalyzerStop ends a turn using an end-of-turn model fed the user's audio, gated on a finalized transcript (or a safety-net timeout). This is the Smart-Turn stop strategy.
func NewTurnAnalyzerStop ¶
func NewTurnAnalyzerStop(cfg TurnAnalyzerConfig) *TurnAnalyzerStop
NewTurnAnalyzerStop builds a Smart-Turn stop strategy.
func (*TurnAnalyzerStop) Process ¶
func (s *TurnAnalyzerStop) Process(f frames.Frame) ProcessFrameResult
Process feeds the analyzer and decides end-of-turn.
type UserIdleController ¶
type UserIdleController struct {
// contains filtered or unexported fields
}
UserIdleController fires IdleConfig.Callback when the conversation stays quiet after the bot finishes speaking. It is owned by a UserTurnProcessor, which feeds it every frame plus synthetic user-speaking frames on its turn decisions. The timer arms on BotStoppedSpeakingFrame (only when no user turn is in progress and no tool calls are pending) and is canceled by bot/user speech onset or a tool call.
func NewUserIdleController ¶
func NewUserIdleController(cfg IdleConfig) *UserIdleController
NewUserIdleController builds a user-idle controller.
func (*UserIdleController) Broadcast ¶
Broadcast sends a frame both downstream and upstream (for use from the callback).
func (*UserIdleController) Cleanup ¶
func (c *UserIdleController) Cleanup()
Cleanup cancels any pending timer.
func (*UserIdleController) Process ¶
func (c *UserIdleController) Process(f frames.Frame)
Process updates idle state from one frame and arms/cancels the timer.
type UserTurnCompletionConfig ¶
type UserTurnCompletionConfig struct {
// Instructions overrides the marker-protocol system-prompt block.
Instructions string
// IncompleteShortTimeout is how long to wait after a "○" before re-prompting;
// 0 uses 5s.
IncompleteShortTimeout time.Duration
// IncompleteLongTimeout is how long to wait after a "◐"; 0 uses 10s.
IncompleteLongTimeout time.Duration
// IncompleteShortPrompt / IncompleteLongPrompt are the re-prompt messages.
IncompleteShortPrompt string
IncompleteLongPrompt string
}
UserTurnCompletionConfig configures LLM turn-completion gating.
type UserTurnController ¶
type UserTurnController struct {
// contains filtered or unexported fields
}
UserTurnController runs the start and stop strategy chains and owns the user-turn state machine: double-start/stop guards and a stop-timeout watchdog. A single mutex serializes every state mutation — Process and all strategy timer callbacks acquire it — so strategies need no locking of their own.
func NewUserTurnController ¶
func NewUserTurnController(strategies UserTurnStrategies, stopTimeout time.Duration) *UserTurnController
NewUserTurnController builds a controller. A zero stopTimeout uses 5s; empty strategy lists fall back to the defaults.
func (*UserTurnController) Cleanup ¶
func (c *UserTurnController) Cleanup()
Cleanup stops the watchdog and cleans up the strategies.
func (*UserTurnController) Process ¶
func (c *UserTurnController) Process(f frames.Frame)
Process taps one frame: it updates the speaking flag, re-arms the watchdog, and runs the start then stop strategy chains. It holds the mutex throughout, so the strategies' synchronous Trigger* callbacks run safely without re-locking.
func (*UserTurnController) SetHooks ¶
func (c *UserTurnController) SetHooks(h ControllerHooks)
SetHooks installs the upward callbacks. Call before Setup.
func (*UserTurnController) Setup ¶
func (c *UserTurnController) Setup(ctx context.Context)
Setup records the session context and binds each strategy to the shared environment.
type UserTurnProcessor ¶
UserTurnProcessor is the pipeline node that drives the turn and idle controllers. It is transparent — every frame is forwarded unchanged and also tapped to the controllers — and emits its turn decisions (UserStarted/StoppedSpeakingFrame) and interruptions via broadcast. Place it downstream of the VAD processor, STT, and the LLM/TTS services so it sees the speaking, transcription, response and tool-call frames that define a turn.
func NewUserTurnProcessor ¶
func NewUserTurnProcessor(cfg Config) *UserTurnProcessor
NewUserTurnProcessor builds a UserTurnProcessor.
func (*UserTurnProcessor) Broadcast ¶
Broadcast implements Emitter, sending a frame both downstream and upstream so turn decisions reach the whole pipeline.
func (*UserTurnProcessor) Cleanup ¶
func (p *UserTurnProcessor) Cleanup(ctx context.Context) error
Cleanup tears down the controllers.
func (*UserTurnProcessor) ProcessFrame ¶
func (p *UserTurnProcessor) ProcessFrame(ctx context.Context, f frames.Frame, dir processor.Direction) error
ProcessFrame forwards every frame downstream and taps it to both controllers.
type UserTurnStartedParams ¶
type UserTurnStartedParams struct {
// EnableInterruptions broadcasts an InterruptionFrame so the bot is barged
// in on turn start.
EnableInterruptions bool
// EnableUserSpeakingFrames broadcasts a UserStartedSpeakingFrame on turn
// start. External integrations disable this when they emit it themselves.
EnableUserSpeakingFrames bool
}
UserTurnStartedParams describes how a start strategy wants a turn opened.
func DefaultStartedParams ¶
func DefaultStartedParams() UserTurnStartedParams
DefaultStartedParams is the params a typical start strategy uses.
type UserTurnStoppedParams ¶
type UserTurnStoppedParams struct {
// EnableUserSpeakingFrames broadcasts a UserStoppedSpeakingFrame on turn
// stop.
EnableUserSpeakingFrames bool
}
UserTurnStoppedParams describes how a stop strategy wants a turn closed.
func DefaultStoppedParams ¶
func DefaultStoppedParams() UserTurnStoppedParams
DefaultStoppedParams is the params a typical stop strategy uses.
type UserTurnStrategies ¶
type UserTurnStrategies struct {
Start []StartStrategy
Stop []StopStrategy
}
UserTurnStrategies holds the start and stop strategy chains a controller runs. Per frame, start strategies run in order until one returns Stop; then stop strategies run the same way (they usually return Continue and signal via their triggers).
func ExternalStrategies ¶
func ExternalStrategies() UserTurnStrategies
ExternalStrategies returns strategies for when an external processor (e.g. a speech-to-speech service) emits the UserStarted/StoppedSpeakingFrames itself: the turn processor relays them without re-emitting speaking frames or interruptions.
func FilterIncompleteUserTurnStrategies ¶
func FilterIncompleteUserTurnStrategies(detectors []StopStrategy) UserTurnStrategies
FilterIncompleteUserTurnStrategies builds a stop chain where the detectors only trigger LLM inference (they are deferred) and final turn-completion is decided by the LLM marker protocol. Pass your detector stop strategies (e.g. Smart-Turn); empty uses the defaults. Use with a CompletionFilter after the LLM and CompletionInstructions in the system prompt.
type VADStart ¶
type VADStart struct {
StartStrategyBase
}
VADStart opens a user turn as soon as the VAD reports speech.
type WakePhraseStart ¶
type WakePhraseStart struct {
StartStrategyBase
// contains filtered or unexported fields
}
WakePhraseStart gates a turn behind a spoken wake phrase. Place it first in the start chain: while asleep it blocks the other start strategies; once awake it lets them run until an inactivity timeout puts it back to sleep.
func NewWakePhraseStart ¶
func NewWakePhraseStart(cfg WakePhraseStartConfig) *WakePhraseStart
NewWakePhraseStart builds a wake-phrase start strategy.
func (*WakePhraseStart) Cleanup ¶
func (s *WakePhraseStart) Cleanup()
Cleanup stops the inactivity timer.
func (*WakePhraseStart) Process ¶
func (s *WakePhraseStart) Process(f frames.Frame) ProcessFrameResult
Process matches the wake phrase while asleep and keeps the session alive while awake.
func (*WakePhraseStart) Reset ¶
func (s *WakePhraseStart) Reset()
Reset re-requires the wake phrase for the next turn when single-activation.
type WakePhraseStartConfig ¶
type WakePhraseStartConfig struct {
// Phrases are the wake phrases (case-insensitive, whitespace-flexible).
Phrases []string
// Timeout is how long the session stays awake without activity; 0 uses 10s.
Timeout time.Duration
// SingleActivation requires the phrase again for every turn.
SingleActivation bool
}
WakePhraseStartConfig configures a WakePhraseStart strategy.