Documentation
¶
Overview ¶
Package workflows contains reusable, context-first agent workflows.
Index ¶
- Constants
- Variables
- func CreateCallerHangupSpeech(ctx context.Context, session WarmTransferSession, speech WarmTransferSpeech, ...) (*voice.SpeechHandle, error)
- func CreateWarmTransferSpeech(ctx context.Context, session WarmTransferSession, speech WarmTransferSpeech, ...) (*voice.SpeechHandle, error)
- func FormatWarmTransferConversation(chat *llm.ChatContext) string
- func ResolveHumanAgentRoomName(callerRoomName string, override *string) (string, error)
- func ResolveWarmTransferInstructions(config WarmTransferInstructionConfig, chat *llm.ChatContext) string
- func SummarizeChatContext(ctx context.Context, model llm.LLM, chat *llm.ChatContext) (*llm.ChatContext, error)
- type AgentTaskAdapter
- func (a *AgentTaskAdapter[Result, UserData]) AgentTask() *voice.AgentTask[Result, UserData]
- func (a *AgentTaskAdapter[Result, UserData]) ChatContext() *llm.ChatContext
- func (a *AgentTaskAdapter[Result, UserData]) Run(ctx context.Context) (any, error)
- func (a *AgentTaskAdapter[Result, UserData]) ToolContext() *llm.Context
- func (a *AgentTaskAdapter[Result, UserData]) UpdateChatContext(ctx context.Context, chat *llm.ChatContext) error
- func (a *AgentTaskAdapter[Result, UserData]) UpdateTools(ctx context.Context, tools *llm.Context) error
- type ChatSummarizer
- type ChatSummarizerFunc
- type InstructionPart
- type InstructionParts
- type Task
- type TaskCompletedEvent
- type TaskFactory
- type TaskGroup
- func (g *TaskGroup) Add(factory TaskFactory, registration TaskRegistration) *TaskGroup
- func (g *TaskGroup) AddTask(factory TaskFactory, registration TaskRegistration) error
- func (g *TaskGroup) ChatContext() *llm.ChatContext
- func (g *TaskGroup) Done() bool
- func (g *TaskGroup) PreserveFunctionCallHistory() bool
- func (g *TaskGroup) Result() (TaskGroupResult, error)
- func (g *TaskGroup) Run(ctx context.Context) (TaskGroupResult, error)
- type TaskGroupOptions
- type TaskGroupResult
- type TaskRegistration
- type TaskRunner
- type WarmTransferBackend
- type WarmTransferBackendFuncs
- func (b WarmTransferBackendFuncs) CallerDisconnected() <-chan WarmTransferParticipantEvent
- func (b WarmTransferBackendFuncs) CallerLocalIdentity(ctx context.Context) (string, error)
- func (b WarmTransferBackendFuncs) CallerPresent(ctx context.Context) (bool, error)
- func (b WarmTransferBackendFuncs) CallerRoomName(ctx context.Context) (string, error)
- func (b WarmTransferBackendFuncs) CaptureCallerIO(ctx context.Context) (WarmTransferIOState, error)
- func (b WarmTransferBackendFuncs) DeleteCallerRoomOnDisconnect(ctx context.Context, room string) error
- func (b WarmTransferBackendFuncs) DeleteRoom(ctx context.Context, room string) error
- func (b WarmTransferBackendFuncs) Dial(ctx context.Context, request WarmTransferDialRequest) (WarmTransferConsultation, error)
- func (b WarmTransferBackendFuncs) MoveParticipant(ctx context.Context, from, identity, to string) error
- func (b WarmTransferBackendFuncs) RemoveParticipant(ctx context.Context, room, identity string) error
- func (b WarmTransferBackendFuncs) SetCallerIO(ctx context.Context, state WarmTransferIOState) error
- func (b WarmTransferBackendFuncs) StartHold(ctx context.Context, audio WarmTransferHoldAudio) (WarmTransferHold, error)
- type WarmTransferConsultation
- type WarmTransferDialRequest
- type WarmTransferHold
- type WarmTransferHoldAudio
- type WarmTransferIOState
- type WarmTransferInstructionConfig
- type WarmTransferParticipantEvent
- type WarmTransferPostMergeBackend
- type WarmTransferResult
- type WarmTransferSession
- type WarmTransferSpeech
- type WarmTransferTask
- func CreateWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) (*WarmTransferTask[UserData], error)
- func MustWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) *WarmTransferTask[UserData]
- func NewWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) (*WarmTransferTask[UserData], error)
- func (t *WarmTransferTask[UserData]) Instructions() llm.Instructions
- func (t *WarmTransferTask[UserData]) Run(ctx context.Context) (result WarmTransferResult, runErr error)
- func (t *WarmTransferTask[UserData]) ToolContext() *llm.Context
- func (t *WarmTransferTask[UserData]) VoiceTask() *voice.AgentTask[WarmTransferResult, UserData]
- func (t *WarmTransferTask[UserData]) WaitReady(ctx context.Context) error
- type WarmTransferTaskOptions
Constants ¶
const ( HumanAgentIdentity = "human-agent-sip" DefaultCallerHangupNoticeTimeout = 30 * time.Second DefaultCallerHangupCleanupTimeout = 10 * time.Second DefaultWarmTransferCleanupTimeout = 10 * time.Second DefaultWarmTransferMergeTimeout = 30 * time.Second DefaultWarmTransferDialDrainTimeout = 10 * time.Second BuiltinHoldMusic = "hold_music" )
const CallerHangupInstruction = `` /* 156-byte string literal not displayed */
const DefaultTaskGroupMaxExecutions = 1024
const WarmTransferInstructionsTemplate = `{persona}
# Context
In the conversation, user refers to the human agent, caller refers to the person who's transcript is included.
Remember, you are not speaking to the caller right now, you are speaking to the human agent.
## Conversation history with caller
{_conversation_history}
## End of conversation history with caller
Once the human agent has confirmed, you should call the tool ` + "`connect_to_caller`" + ` to connect them to the caller.
You are talking to the human agent now, start by giving them a summary of the conversation so far, and answer any questions they might have.
{extra}
`
const WarmTransferPersona = `` /* 376-byte string literal not displayed */
Variables ¶
var ( ErrTaskGroupAlreadyStarted = errors.New("workflows: task group has already started") ErrTaskGroupNotComplete = errors.New("workflows: task group is not complete") ErrTaskGroupExecutionLimit = errors.New("workflows: task group execution limit exceeded") ErrTaskGroupSummarizerNeeded = errors.New("workflows: summarizeChatCtx requires a standard LLM or summarizer") )
var ( ErrWarmTransferAlreadyStarted = errors.New("workflows: warm transfer has already started") ErrWarmTransferNotStarted = errors.New("workflows: warm transfer has not started") ErrWarmTransferAlreadyDone = errors.New("workflows: warm transfer is already complete") ErrWarmTransferNotReady = errors.New("workflows: warm transfer is not ready to merge") ErrWarmTransferCallerGone = errors.New("workflows: caller hung up before the transfer completed") ErrWarmTransferVoicemail = errors.New("workflows: voicemail detected") ErrWarmTransferDeclined = errors.New("workflows: human agent declined to connect") ErrWarmTransferRoomClosed = errors.New("workflows: human agent room closed") )
Functions ¶
func CreateCallerHangupSpeech ¶
func CreateCallerHangupSpeech(ctx context.Context, session WarmTransferSession, speech WarmTransferSpeech, instruction *string) (*voice.SpeechHandle, error)
func CreateWarmTransferSpeech ¶
func CreateWarmTransferSpeech(ctx context.Context, session WarmTransferSession, speech WarmTransferSpeech, options voice.SayOptions) (*voice.SpeechHandle, error)
func FormatWarmTransferConversation ¶
func FormatWarmTransferConversation(chat *llm.ChatContext) string
func ResolveWarmTransferInstructions ¶
func ResolveWarmTransferInstructions(config WarmTransferInstructionConfig, chat *llm.ChatContext) string
ResolveWarmTransferInstructions renders the pinned agents-js prompt. A full string bypasses templating; unset parts preserve defaults and explicit empty parts remove their section.
func SummarizeChatContext ¶
func SummarizeChatContext(ctx context.Context, model llm.LLM, chat *llm.ChatContext) (*llm.ChatContext, error)
SummarizeChatContext applies the same keepLastTurns=0 summarization used by agents-js TaskGroup. The source context is never mutated.
Types ¶
type AgentTaskAdapter ¶
type AgentTaskAdapter[Result, UserData any] struct { // contains filtered or unexported fields }
AgentTaskAdapter erases a voice task's result type without erasing errors or its chat/tool context.
func AdaptAgentTask ¶
func AdaptAgentTask[Result, UserData any](task *voice.AgentTask[Result, UserData], runner TaskRunner[Result, UserData]) (*AgentTaskAdapter[Result, UserData], error)
AdaptAgentTask wraps a typed voice.AgentTask for TaskGroup. If runner is nil, Run waits on task.Run; callers that need the group to perform the foreground handoff should supply their session's task runner.
func (*AgentTaskAdapter[Result, UserData]) AgentTask ¶
func (a *AgentTaskAdapter[Result, UserData]) AgentTask() *voice.AgentTask[Result, UserData]
func (*AgentTaskAdapter[Result, UserData]) ChatContext ¶
func (a *AgentTaskAdapter[Result, UserData]) ChatContext() *llm.ChatContext
func (*AgentTaskAdapter[Result, UserData]) Run ¶
func (a *AgentTaskAdapter[Result, UserData]) Run(ctx context.Context) (any, error)
func (*AgentTaskAdapter[Result, UserData]) ToolContext ¶
func (a *AgentTaskAdapter[Result, UserData]) ToolContext() *llm.Context
func (*AgentTaskAdapter[Result, UserData]) UpdateChatContext ¶
func (a *AgentTaskAdapter[Result, UserData]) UpdateChatContext(ctx context.Context, chat *llm.ChatContext) error
func (*AgentTaskAdapter[Result, UserData]) UpdateTools ¶
type ChatSummarizer ¶
type ChatSummarizer interface {
SummarizeChatContext(context.Context, *llm.ChatContext) (*llm.ChatContext, error)
}
ChatSummarizer replaces a chat history with its bounded summary.
type ChatSummarizerFunc ¶
type ChatSummarizerFunc func(context.Context, *llm.ChatContext) (*llm.ChatContext, error)
ChatSummarizerFunc adapts a function to ChatSummarizer.
func (ChatSummarizerFunc) SummarizeChatContext ¶
func (f ChatSummarizerFunc) SummarizeChatContext(ctx context.Context, chat *llm.ChatContext) (*llm.ChatContext, error)
type InstructionPart ¶
type InstructionPart struct {
// contains filtered or unexported fields
}
InstructionPart is one replaceable section of a built-in workflow prompt. TextInstruction is the convenient form for ordinary text; ModalInstruction preserves separate audio and text instructions.
func InstructionPartPtr ¶
func InstructionPartPtr(value InstructionPart) *InstructionPart
InstructionPartPtr is a convenience for struct literals.
func ModalInstruction ¶
func ModalInstruction(value llm.Instructions) InstructionPart
ModalInstruction constructs a workflow instruction section from LiveKit's modality-aware Instructions value.
func TextInstruction ¶
func TextInstruction(value string) InstructionPart
TextInstruction constructs a workflow instruction section from plain text.
func (InstructionPart) Instructions ¶
func (p InstructionPart) Instructions() llm.Instructions
Instructions returns the modality-aware instruction value.
func (InstructionPart) Value ¶
func (p InstructionPart) Value() string
Value returns the audio/default representation of the instruction section.
type InstructionParts ¶
type InstructionParts struct {
Persona *InstructionPart
Extra *InstructionPart
}
InstructionParts customizes sections of built-in workflow prompts. Nil preserves the workflow default; a pointer to TextInstruction("") removes the section. This distinction matches agents-js and agents-python.
type Task ¶
type Task interface {
Run(context.Context) (any, error)
ChatContext() *llm.ChatContext
UpdateChatContext(context.Context, *llm.ChatContext) error
ToolContext() *llm.Context
UpdateTools(context.Context, *llm.Context) error
}
Task is the small surface TaskGroup needs from an agent task. The adapter returned by AdaptAgentTask makes every *voice.AgentTask usable here while a custom implementation is useful for non-voice or deterministic tasks.
type TaskCompletedEvent ¶
TaskCompletedEvent is emitted after a child completes and its chat context has been merged into the group.
type TaskFactory ¶
type TaskFactory func() Task
type TaskGroup ¶
type TaskGroup struct {
// contains filtered or unexported fields
}
TaskGroup runs registered tasks sequentially and lets later tasks regress to already-visited tasks through a generated out_of_scope tool. It is one-shot.
func MustTaskGroup ¶
func MustTaskGroup(options TaskGroupOptions) *TaskGroup
func NewTaskGroup ¶
func NewTaskGroup(options TaskGroupOptions) (*TaskGroup, error)
func (*TaskGroup) Add ¶
func (g *TaskGroup) Add(factory TaskFactory, registration TaskRegistration) *TaskGroup
Add registers or replaces a task and returns the group for fluent setup. As in JavaScript Map.set, replacing an ID preserves its original ordering. Bad registrations are reported by Run; AddTask is the eager-validation variant.
func (*TaskGroup) AddTask ¶
func (g *TaskGroup) AddTask(factory TaskFactory, registration TaskRegistration) error
func (*TaskGroup) ChatContext ¶
func (g *TaskGroup) ChatContext() *llm.ChatContext
func (*TaskGroup) PreserveFunctionCallHistory ¶
func (*TaskGroup) Result ¶
func (g *TaskGroup) Result() (TaskGroupResult, error)
type TaskGroupOptions ¶
type TaskGroupOptions struct {
// Nil preserves the agents-js default (true).
SummarizeChatCtx *bool
ReturnExceptions bool
ChatCtx *llm.ChatContext
OnTaskCompleted func(context.Context, TaskCompletedEvent) error
// PreserveFunctionCallHistory is exposed for parity with AgentTask even
// though TaskGroup always retains tool results until optional summarization.
PreserveFunctionCallHistory bool
// LLM supplies the agents-js standard-LLM summarizer. Summarizer overrides
// LLM and is useful for custom/realtime model stacks.
LLM llm.LLM
Summarizer ChatSummarizer
// MaxExecutions bounds regressions caused by out_of_scope. Zero selects
// DefaultTaskGroupMaxExecutions.
MaxExecutions int
}
type TaskGroupResult ¶
TaskGroupResult contains the last successful/error value for every completed task ID. A fresh map is returned to every observer.
type TaskRegistration ¶
type TaskRunner ¶
type TaskRunner[Result, UserData any] func(context.Context, *voice.AgentTask[Result, UserData]) (Result, error)
TaskRunner starts a voice task in its owning session and waits for its typed result. It is separate from voice.AgentTask.Run because the latter only waits for completion; the session/runtime owns the foreground handoff.
type WarmTransferBackend ¶
type WarmTransferBackend interface {
CallerRoomName(context.Context) (string, error)
CallerLocalIdentity(context.Context) (string, error)
CallerPresent(context.Context) (bool, error)
CallerDisconnected() <-chan WarmTransferParticipantEvent
CaptureCallerIO(context.Context) (WarmTransferIOState, error)
SetCallerIO(context.Context, WarmTransferIOState) error
StartHold(context.Context, WarmTransferHoldAudio) (WarmTransferHold, error)
Dial(context.Context, WarmTransferDialRequest) (WarmTransferConsultation, error)
MoveParticipant(context.Context, string, string, string) error
RemoveParticipant(context.Context, string, string) error
DeleteRoom(context.Context, string) error
}
WarmTransferBackend isolates RTC/SIP ownership from the deterministic workflow state machine. Methods that may block are context-first. The caller event stream must be bounded by the implementation and must never be closed while Run is active without first carrying the terminal disconnect event.
type WarmTransferBackendFuncs ¶
type WarmTransferBackendFuncs struct {
CallerRoomNameFunc func(context.Context) (string, error)
CallerLocalIdentityFunc func(context.Context) (string, error)
CallerPresentFunc func(context.Context) (bool, error)
CallerDisconnectedChan <-chan WarmTransferParticipantEvent
CaptureCallerIOFunc func(context.Context) (WarmTransferIOState, error)
SetCallerIOFunc func(context.Context, WarmTransferIOState) error
StartHoldFunc func(context.Context, WarmTransferHoldAudio) (WarmTransferHold, error)
DialFunc func(context.Context, WarmTransferDialRequest) (WarmTransferConsultation, error)
MoveParticipantFunc func(context.Context, string, string, string) error
RemoveParticipantFunc func(context.Context, string, string) error
DeleteRoomFunc func(context.Context, string) error
PostMergeCleanupFunc func(context.Context, string) error
}
WarmTransferBackendFuncs is a zero-allocation adapter for applications that already own RTC callbacks, RoomIO, or a custom consultation session.
func (WarmTransferBackendFuncs) CallerDisconnected ¶
func (b WarmTransferBackendFuncs) CallerDisconnected() <-chan WarmTransferParticipantEvent
func (WarmTransferBackendFuncs) CallerLocalIdentity ¶
func (b WarmTransferBackendFuncs) CallerLocalIdentity(ctx context.Context) (string, error)
func (WarmTransferBackendFuncs) CallerPresent ¶
func (b WarmTransferBackendFuncs) CallerPresent(ctx context.Context) (bool, error)
func (WarmTransferBackendFuncs) CallerRoomName ¶
func (b WarmTransferBackendFuncs) CallerRoomName(ctx context.Context) (string, error)
func (WarmTransferBackendFuncs) CaptureCallerIO ¶
func (b WarmTransferBackendFuncs) CaptureCallerIO(ctx context.Context) (WarmTransferIOState, error)
func (WarmTransferBackendFuncs) DeleteCallerRoomOnDisconnect ¶
func (b WarmTransferBackendFuncs) DeleteCallerRoomOnDisconnect(ctx context.Context, room string) error
func (WarmTransferBackendFuncs) DeleteRoom ¶
func (b WarmTransferBackendFuncs) DeleteRoom(ctx context.Context, room string) error
func (WarmTransferBackendFuncs) Dial ¶
func (b WarmTransferBackendFuncs) Dial(ctx context.Context, request WarmTransferDialRequest) (WarmTransferConsultation, error)
func (WarmTransferBackendFuncs) MoveParticipant ¶
func (b WarmTransferBackendFuncs) MoveParticipant(ctx context.Context, from, identity, to string) error
func (WarmTransferBackendFuncs) RemoveParticipant ¶
func (b WarmTransferBackendFuncs) RemoveParticipant(ctx context.Context, room, identity string) error
func (WarmTransferBackendFuncs) SetCallerIO ¶
func (b WarmTransferBackendFuncs) SetCallerIO(ctx context.Context, state WarmTransferIOState) error
func (WarmTransferBackendFuncs) StartHold ¶
func (b WarmTransferBackendFuncs) StartHold(ctx context.Context, audio WarmTransferHoldAudio) (WarmTransferHold, error)
type WarmTransferConsultation ¶
type WarmTransferConsultation interface {
RoomName() string
Session() WarmTransferSession
Disconnected() <-chan error
Close(context.Context) error
}
WarmTransferConsultation owns the private human-agent room and its session. Disconnected must return a stable, close-only/read-only channel; a nil value is rejected so room failures cannot be silently missed.
type WarmTransferDialRequest ¶
type WarmTransferDialRequest struct {
CallerRoomName string
CallerIdentity string
HumanRoomName string
HumanIdentity string
SIPCallTo string
SIPTrunkID string
SIPConnection *livekit.SIPOutboundConfig
SIPNumber string
SIPHeaders map[string]string
DTMF *string
RingingTimeout *time.Duration
Instructions llm.Instructions
ChatContext *llm.ChatContext
Tools *llm.Context
AllowInterruptions *bool
STT agents.Override[stt.STT]
VAD agents.Override[vad.VAD]
LLM agents.Override[llm.LLM]
TTS agents.Override[tts.TTS]
TurnHandling *voice.TurnHandlingOptions
}
func (WarmTransferDialRequest) Clone ¶
func (r WarmTransferDialRequest) Clone() WarmTransferDialRequest
type WarmTransferHold ¶
WarmTransferHold is owned by the backend and stopped exactly once.
type WarmTransferHoldAudio ¶
type WarmTransferIOState ¶
type WarmTransferInstructionConfig ¶
type WarmTransferInstructionConfig struct {
Full *string
Parts *InstructionParts
}
WarmTransferInstructionConfig models the string | InstructionParts union. Full replaces the prompt; Parts retains the template. Both nil selects the built-in prompt.
func FullWarmTransferInstructions ¶
func FullWarmTransferInstructions(value string) WarmTransferInstructionConfig
func PartialWarmTransferInstructions ¶
func PartialWarmTransferInstructions(value InstructionParts) WarmTransferInstructionConfig
type WarmTransferParticipantEvent ¶
type WarmTransferParticipantEvent struct {
Identity string
Kind livekit.ParticipantInfo_Kind
}
type WarmTransferPostMergeBackend ¶
type WarmTransferPostMergeBackend interface {
DeleteCallerRoomOnDisconnect(context.Context, string) error
}
WarmTransferPostMergeBackend optionally installs the caller-room cleanup listener after a successful merge. Ownership moves to the backend because the foreground task is about to return.
type WarmTransferResult ¶
type WarmTransferResult struct {
HumanAgentIdentity string `json:"humanAgentIdentity"`
}
type WarmTransferSession ¶
type WarmTransferSession interface {
Say(context.Context, string, voice.SayOptions) (*voice.SpeechHandle, error)
GenerateReply(context.Context, voice.GenerateReplyOptions) (*voice.SpeechHandle, error)
Interrupt(context.Context, bool) error
Close(context.Context, ...voice.CloseOptions) error
}
WarmTransferSession is the consultation surface used by the workflow. Every *voice.AgentSession[T] satisfies it.
type WarmTransferSpeech ¶
type WarmTransferSpeech struct {
Text *string
Start func(context.Context, WarmTransferSession) (*voice.SpeechHandle, error)
}
WarmTransferSpeech is exact text or a callback that starts speech in the consultation session. Its zero value means no speech.
func SpeechFunc ¶
func SpeechFunc(start func(context.Context, WarmTransferSession) (*voice.SpeechHandle, error)) WarmTransferSpeech
func TextSpeech ¶
func TextSpeech(text string) WarmTransferSpeech
type WarmTransferTask ¶
type WarmTransferTask[UserData any] struct { // contains filtered or unexported fields }
func CreateWarmTransferTask ¶
func CreateWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) (*WarmTransferTask[UserData], error)
CreateWarmTransferTask is the functional constructor name used by agents-js. Go returns validation errors instead of throwing.
func MustWarmTransferTask ¶
func MustWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) *WarmTransferTask[UserData]
func NewWarmTransferTask ¶
func NewWarmTransferTask[UserData any](options WarmTransferTaskOptions[UserData]) (*WarmTransferTask[UserData], error)
func (*WarmTransferTask[UserData]) Instructions ¶
func (t *WarmTransferTask[UserData]) Instructions() llm.Instructions
func (*WarmTransferTask[UserData]) Run ¶
func (t *WarmTransferTask[UserData]) Run(ctx context.Context) (result WarmTransferResult, runErr error)
func (*WarmTransferTask[UserData]) ToolContext ¶
func (t *WarmTransferTask[UserData]) ToolContext() *llm.Context
func (*WarmTransferTask[UserData]) VoiceTask ¶
func (t *WarmTransferTask[UserData]) VoiceTask() *voice.AgentTask[WarmTransferResult, UserData]
type WarmTransferTaskOptions ¶
type WarmTransferTaskOptions[UserData any] struct { AbortContext context.Context Backend WarmTransferBackend SIPCallTo string SIPTrunkID agents.Override[string] SIPConnection *livekit.SIPOutboundConfig SIPNumber string SIPHeaders map[string]string DTMF *string RingingTimeout *time.Duration RoomName *string // Zero inherits the agents-js default hold music at volume 0.8. Use // agents.Disable[WarmTransferHoldAudio]() for holdAudio: null. HoldAudio agents.Override[WarmTransferHoldAudio] GreetingSpeech WarmTransferSpeech CallerHangupSpeech WarmTransferSpeech CallerHangupInstruction *string // Deprecated: prefer CallerHangupSpeech. Instructions WarmTransferInstructionConfig ChatCtx *llm.ChatContext Tools *llm.Context STT agents.Override[stt.STT] VAD agents.Override[vad.VAD] LLM agents.Override[llm.LLM] TTS agents.Override[tts.TTS] TurnHandling *voice.TurnHandlingOptions AllowInterruptions *bool CallerHangupNoticeTimeout time.Duration CallerHangupCleanupTimeout time.Duration CleanupTimeout time.Duration MergeTimeout time.Duration DialDrainTimeout time.Duration OnError func(error) }