From f77a2afca6571780d4ceb5b82a822e9d14b8fb89 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 5 Feb 2026 21:02:02 +0530 Subject: [PATCH] feat: add hold music --- api/assets/transfer_hold_ring_16000.wav | Bin 0 -> 32044 bytes api/assets/transfer_hold_ring_8000.wav | Bin 0 -> 16044 bytes api/routes/tool.py | 19 ++- api/services/pipecat/run_pipeline.py | 1 + api/services/workflow/pipecat_engine.py | 16 +- .../workflow/pipecat_engine_custom_tools.py | 70 ++++++++- api/tests/test_pipecat_engine_tool_calls.py | 3 + api/utils/hold_audio.py | 80 ++++++++++ pipecat | 2 +- ui/src/client/sdk.gen.ts | 60 +++++++- ui/src/client/types.gen.ts | 141 +++++++++++++++++- 11 files changed, 372 insertions(+), 20 deletions(-) create mode 100644 api/assets/transfer_hold_ring_16000.wav create mode 100644 api/assets/transfer_hold_ring_8000.wav create mode 100644 api/utils/hold_audio.py diff --git a/api/assets/transfer_hold_ring_16000.wav b/api/assets/transfer_hold_ring_16000.wav new file mode 100644 index 0000000000000000000000000000000000000000..5cab0216660fcaca1d522b6dd085bb746fc1c9b0 GIT binary patch literal 32044 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 literal 0 HcmV?d00001 diff --git a/api/assets/transfer_hold_ring_8000.wav b/api/assets/transfer_hold_ring_8000.wav new file mode 100644 index 0000000000000000000000000000000000000000..b1133b3a214072a2839cac750545f85480fdc019 GIT binary patch literal 16044 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 Idh1vG2Tr=tNB{r; literal 0 HcmV?d00001 diff --git a/api/routes/tool.py b/api/routes/tool.py index f6ee635b..b54d83f9 100644 --- a/api/routes/tool.py +++ b/api/routes/tool.py @@ -72,9 +72,26 @@ class EndCallToolDefinition(BaseModel): config: EndCallConfig = Field(description="End Call configuration") +class TransferCallConfig(BaseModel): + """Configuration for Transfer Call tools.""" + + transfer_number: str = Field(description="Number to transfer the call to") + transfer_message: Optional[str] = Field( + default=None, description="Message to play before transferring the call" + ) + + +class TransferCallToolDefinition(BaseModel): + """Tool definition for Transfer Call tools.""" + + schema_version: int = Field(default=1, description="Schema version") + type: Literal["transfer_call"] = Field(description="Tool type") + config: TransferCallConfig = Field(description="Transfer Call configuration") + + # Union type for tool definitions - Pydantic will discriminate based on 'type' field ToolDefinition = Annotated[ - Union[HttpApiToolDefinition, EndCallToolDefinition], + Union[HttpApiToolDefinition, EndCallToolDefinition, TransferCallToolDefinition], Field(discriminator="type"), ] diff --git a/api/services/pipecat/run_pipeline.py b/api/services/pipecat/run_pipeline.py index 00744f06..3db32f04 100644 --- a/api/services/pipecat/run_pipeline.py +++ b/api/services/pipecat/run_pipeline.py @@ -548,6 +548,7 @@ async def _run_pipeline( node_transition_callback=node_transition_callback, embeddings_api_key=embeddings_api_key, embeddings_model=embeddings_model, + audio_out_sample_rate=audio_config.transport_out_sample_rate, ) # Create pipeline components with audio configuration diff --git a/api/services/workflow/pipecat_engine.py b/api/services/workflow/pipecat_engine.py index b960bdfe..64ca54e6 100644 --- a/api/services/workflow/pipecat_engine.py +++ b/api/services/workflow/pipecat_engine.py @@ -70,6 +70,7 @@ class PipecatEngine: ] = None, embeddings_api_key: Optional[str] = None, embeddings_model: Optional[str] = None, + audio_out_sample_rate: int = 16000, ): self.task = task self.llm = llm @@ -111,6 +112,9 @@ class PipecatEngine: self._embeddings_api_key: Optional[str] = embeddings_api_key self._embeddings_model: Optional[str] = embeddings_model + # Output audio sample rate for playback (8000 or 16000) + self._audio_out_sample_rate: int = audio_out_sample_rate + async def _get_organization_id(self) -> Optional[int]: """Get and cache the organization ID from workflow run.""" if self._custom_tool_manager: @@ -697,10 +701,14 @@ class PipecatEngine: connection: The StasisRTPConnection instance, or None for non-Stasis transports """ self._stasis_connection = connection - if connection: - logger.debug( - f"Stasis connection set for immediate transfers: {connection.channel_id}" - ) + + def mute_pipeline(self) -> None: + """Mute the pipeline to prevent further LLM generations. + + Call this before playing final messages (like transfer announcements) + to ensure the pipeline doesn't process any more user input. + """ + self._mute_pipeline = True async def handle_llm_text_frame(self, text: str): """Accumulate LLM text frames to build reference text.""" diff --git a/api/services/workflow/pipecat_engine_custom_tools.py b/api/services/workflow/pipecat_engine_custom_tools.py index 79e29c33..74815371 100644 --- a/api/services/workflow/pipecat_engine_custom_tools.py +++ b/api/services/workflow/pipecat_engine_custom_tools.py @@ -6,6 +6,7 @@ during workflow execution. from __future__ import annotations +import asyncio from typing import TYPE_CHECKING, Any, Optional from loguru import logger @@ -24,8 +25,13 @@ from api.services.workflow.transfer_event_protocol import ( TransferEventType, wait_for_transfer_signal, ) +from api.utils.hold_audio import get_hold_audio_duration_ms, load_hold_audio from pipecat.adapters.schemas.function_schema import FunctionSchema -from pipecat.frames.frames import FunctionCallResultProperties, TTSSpeakFrame +from pipecat.frames.frames import ( + FunctionCallResultProperties, + OutputAudioRawFrame, + TTSSpeakFrame, +) from pipecat.services.llm_service import FunctionCallParams from pipecat.utils.enums import EndTaskReason @@ -249,11 +255,48 @@ class CustomToolManager: Async handler function for the transfer call tool """ + async def play_hold_music_loop(stop_event: asyncio.Event) -> None: + """Play hold music in a loop until stop_event is set.""" + sample_rate = self._engine._audio_out_sample_rate + try: + hold_audio = load_hold_audio(sample_rate) + duration_ms = get_hold_audio_duration_ms(sample_rate) + duration_secs = duration_ms / 1000.0 + + logger.info( + f"Starting hold music loop at {sample_rate}Hz, " + f"duration={duration_secs:.2f}s per loop" + ) + + while not stop_event.is_set(): + # Queue the hold audio frame + frame = OutputAudioRawFrame( + audio=hold_audio, + sample_rate=sample_rate, + num_channels=1, + ) + await self._engine.task.queue_frame(frame) + + # Wait for the audio to play or until stopped + try: + await asyncio.wait_for(stop_event.wait(), timeout=duration_secs) + break # Stop event was set + except asyncio.TimeoutError: + pass # Continue looping + + logger.info("Hold music loop stopped") + + except Exception as e: + logger.error(f"Error playing hold music: {e}") + async def transfer_call_handler( function_call_params: FunctionCallParams, ) -> None: logger.info(f"Transfer Call Tool EXECUTED: {function_name}") + stop_hold_music = asyncio.Event() + hold_music_task: Optional[asyncio.Task] = None + try: # Get the transfer call configuration config = tool.definition.get("config", {}) @@ -269,6 +312,9 @@ class CustomToolManager: logger.info(f"Initiating transfer to: {transfer_number}") + # Mute pipeline before playing transfer message + self._engine.mute_pipeline() + # Play transfer message if configured if transfer_message: logger.info(f"Playing transfer message: {transfer_message}") @@ -278,6 +324,11 @@ class CustomToolManager: self._engine._gathered_context["transfer_requested"] = True self._engine._gathered_context["transfer_number"] = transfer_number + # Start playing hold music in the background + hold_music_task = asyncio.create_task( + play_hold_music_loop(stop_hold_music) + ) + # Wait for external signal to proceed with transfer (30s timeout) workflow_run_id = self._engine._workflow_run_id logger.info( @@ -286,9 +337,12 @@ class CustomToolManager: transfer_event = await wait_for_transfer_signal( workflow_run_id=workflow_run_id, - timeout_seconds=30.0, + timeout_seconds=8.0, ) + # Stop hold music + stop_hold_music.set() + if transfer_event is None: # Timeout - transfer failed logger.warning("Transfer signal timed out") @@ -329,8 +383,16 @@ class CustomToolManager: f"Transfer call tool '{function_name}' execution failed: {e}" ) await function_call_params.result_callback( - {"status": "error", "error": str(e)}, - properties=properties, + {"status": "error", "error": str(e)} ) + finally: + # Ensure hold music is stopped + stop_hold_music.set() + if hold_music_task and not hold_music_task.done(): + hold_music_task.cancel() + try: + await hold_music_task + except asyncio.CancelledError: + pass return transfer_call_handler diff --git a/api/tests/test_pipecat_engine_tool_calls.py b/api/tests/test_pipecat_engine_tool_calls.py index a8f04e57..f6b0094d 100644 --- a/api/tests/test_pipecat_engine_tool_calls.py +++ b/api/tests/test_pipecat_engine_tool_calls.py @@ -102,6 +102,7 @@ async def run_pipeline_with_tool_calls( workflow=workflow, call_context_vars={"customer_name": "Test User"}, workflow_run_id=1, + audio_out_sample_rate=16000, ) # Create the pipeline with the mock LLM and TTS @@ -371,6 +372,8 @@ class TestPipecatEngineToolCalls: # Callback to send transfer signal while handler is waiting async def send_signal(engine: PipecatEngine): + # Wait a bit to allow hold music to play + await asyncio.sleep(0.5) # Send the transfer signal to unblock the waiting handler await send_transfer_signal( workflow_run_id=engine._workflow_run_id, diff --git a/api/utils/hold_audio.py b/api/utils/hold_audio.py new file mode 100644 index 00000000..a54601dd --- /dev/null +++ b/api/utils/hold_audio.py @@ -0,0 +1,80 @@ +"""Utility for loading and playing hold audio files.""" + +from typing import Dict + +import soundfile as sf +from loguru import logger + +from api.constants import APP_ROOT_DIR + +# Cache for loaded audio data +_audio_cache: Dict[str, bytes] = {} + + +def load_hold_audio(sample_rate: int) -> bytes: + """Load hold audio file as raw PCM bytes for the given sample rate. + + Args: + sample_rate: The sample rate to load (8000 or 16000) + + Returns: + Raw PCM audio bytes (16-bit signed, mono) + + Raises: + FileNotFoundError: If the audio file doesn't exist + ValueError: If sample rate is not supported + """ + if sample_rate not in (8000, 16000): + raise ValueError( + f"Unsupported sample rate: {sample_rate}. Must be 8000 or 16000" + ) + + cache_key = f"hold_ring_{sample_rate}" + + if cache_key in _audio_cache: + return _audio_cache[cache_key] + + # Construct path to the audio file + assets_dir = APP_ROOT_DIR / "assets" + audio_file = assets_dir / f"transfer_hold_ring_{sample_rate}.wav" + + if not audio_file.exists(): + raise FileNotFoundError(f"Hold audio file not found: {audio_file}") + + # Load the audio file + audio_data, file_sample_rate = sf.read(str(audio_file), dtype="int16") + + if file_sample_rate != sample_rate: + logger.warning( + f"Audio file sample rate ({file_sample_rate}) doesn't match " + f"requested rate ({sample_rate})" + ) + + # Convert to bytes + audio_bytes = audio_data.tobytes() + + # Cache for future use + _audio_cache[cache_key] = audio_bytes + + logger.debug( + f"Loaded hold audio: {audio_file.name}, " + f"duration={len(audio_data) / sample_rate:.2f}s" + ) + + return audio_bytes + + +def get_hold_audio_duration_ms(sample_rate: int) -> int: + """Get the duration of the hold audio in milliseconds. + + Args: + sample_rate: The sample rate (8000 or 16000) + + Returns: + Duration in milliseconds + """ + audio_bytes = load_hold_audio(sample_rate) + # 2 bytes per sample (16-bit PCM) + num_samples = len(audio_bytes) // 2 + duration_ms = int((num_samples / sample_rate) * 1000) + return duration_ms diff --git a/pipecat b/pipecat index 866bf1c5..e618bb98 160000 --- a/pipecat +++ b/pipecat @@ -1 +1 @@ -Subproject commit 866bf1c5685e7fadf2af012d8769ebbc35297db0 +Subproject commit e618bb98dfde6224ef9f4e15769580790719b269 diff --git a/ui/src/client/sdk.gen.ts b/ui/src/client/sdk.gen.ts index 88159cbc..6bc37e9a 100644 --- a/ui/src/client/sdk.gen.ts +++ b/ui/src/client/sdk.gen.ts @@ -3,7 +3,7 @@ import type { Client,Options as ClientOptions, TDataShape } from '@hey-api/client-fetch'; import { client as _heyApiClient } from './client.gen'; -import type { ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteData, ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteError, ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteResponse, ArchiveServiceKeyApiV1UserServiceKeysServiceKeyIdDeleteData, ArchiveServiceKeyApiV1UserServiceKeysServiceKeyIdDeleteError, CreateApiKeyApiV1UserApiKeysPostData, CreateApiKeyApiV1UserApiKeysPostError, CreateApiKeyApiV1UserApiKeysPostResponse, CreateCampaignApiV1CampaignCreatePostData, CreateCampaignApiV1CampaignCreatePostError, CreateCampaignApiV1CampaignCreatePostResponse, CreateCredentialApiV1CredentialsPostData, CreateCredentialApiV1CredentialsPostError, CreateCredentialApiV1CredentialsPostResponse, CreateLoadTestApiV1LooptalkLoadTestsPostData, CreateLoadTestApiV1LooptalkLoadTestsPostError, CreateLoadTestApiV1LooptalkLoadTestsPostResponse, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostData, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostError, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostResponse, CreateServiceKeyApiV1UserServiceKeysPostData, CreateServiceKeyApiV1UserServiceKeysPostError, CreateServiceKeyApiV1UserServiceKeysPostResponse, CreateSessionApiV1IntegrationSessionPostData, CreateSessionApiV1IntegrationSessionPostError, CreateSessionApiV1IntegrationSessionPostResponse, CreateTestSessionApiV1LooptalkTestSessionsPostData, CreateTestSessionApiV1LooptalkTestSessionsPostError, CreateTestSessionApiV1LooptalkTestSessionsPostResponse, CreateToolApiV1ToolsPostData, CreateToolApiV1ToolsPostError, CreateToolApiV1ToolsPostResponse, CreateWorkflowApiV1WorkflowCreateDefinitionPostData, CreateWorkflowApiV1WorkflowCreateDefinitionPostError, CreateWorkflowApiV1WorkflowCreateDefinitionPostResponse, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostData, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostError, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostResponse, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostData, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostError, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostResponse, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteData, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteError, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteResponse, DeleteCredentialApiV1CredentialsCredentialUuidDeleteData, DeleteCredentialApiV1CredentialsCredentialUuidDeleteError, DeleteCredentialApiV1CredentialsCredentialUuidDeleteResponse, DeleteDocumentApiV1KnowledgeBaseDocumentsDocumentUuidDeleteData, DeleteDocumentApiV1KnowledgeBaseDocumentsDocumentUuidDeleteError, DeleteToolApiV1ToolsToolUuidDeleteData, DeleteToolApiV1ToolsToolUuidDeleteError, DeleteToolApiV1ToolsToolUuidDeleteResponse, DownloadWorkflowArtifactApiV1PublicDownloadWorkflowTokenArtifactTypeGetData, DownloadWorkflowArtifactApiV1PublicDownloadWorkflowTokenArtifactTypeGetError, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostData, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostError, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostResponse, GetActiveTestsApiV1LooptalkActiveTestsGetData, GetActiveTestsApiV1LooptalkActiveTestsGetError, GetApiKeysApiV1UserApiKeysGetData, GetApiKeysApiV1UserApiKeysGetError, GetApiKeysApiV1UserApiKeysGetResponse, GetAuthUserApiV1UserAuthUserGetData, GetAuthUserApiV1UserAuthUserGetError, GetAuthUserApiV1UserAuthUserGetResponse, GetCampaignApiV1CampaignCampaignIdGetData, GetCampaignApiV1CampaignCampaignIdGetError, GetCampaignApiV1CampaignCampaignIdGetResponse, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetData, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetError, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetResponse, GetCampaignProgressApiV1CampaignCampaignIdProgressGetData, GetCampaignProgressApiV1CampaignCampaignIdProgressGetError, GetCampaignProgressApiV1CampaignCampaignIdProgressGetResponse, GetCampaignRunsApiV1CampaignCampaignIdRunsGetData, GetCampaignRunsApiV1CampaignCampaignIdRunsGetError, GetCampaignRunsApiV1CampaignCampaignIdRunsGetResponse, GetCampaignsApiV1CampaignGetData, GetCampaignsApiV1CampaignGetError, GetCampaignsApiV1CampaignGetResponse, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetData, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetError, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetResponse, GetCredentialApiV1CredentialsCredentialUuidGetData, GetCredentialApiV1CredentialsCredentialUuidGetError, GetCredentialApiV1CredentialsCredentialUuidGetResponse, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetData, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetError, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponse, GetDailyReportApiV1OrganizationsReportsDailyGetData, GetDailyReportApiV1OrganizationsReportsDailyGetError, GetDailyReportApiV1OrganizationsReportsDailyGetResponse, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetData, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetError, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetResponse, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetData, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetError, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetResponse, GetDefaultConfigurationsApiV1UserConfigurationsDefaultsGetData, GetDefaultConfigurationsApiV1UserConfigurationsDefaultsGetResponse, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetData, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetError, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetResponse, GetEmbedConfigApiV1PublicEmbedConfigTokenGetData, GetEmbedConfigApiV1PublicEmbedConfigTokenGetError, GetEmbedConfigApiV1PublicEmbedConfigTokenGetResponse, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetData, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetError, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetResponse, GetFileMetadataApiV1S3FileMetadataGetData, GetFileMetadataApiV1S3FileMetadataGetError, GetFileMetadataApiV1S3FileMetadataGetResponse, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetData, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetError, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetResponse, GetIntegrationsApiV1IntegrationGetData, GetIntegrationsApiV1IntegrationGetError, GetIntegrationsApiV1IntegrationGetResponse, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetData, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetError, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetResponse, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostData, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostError, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostResponse, GetServiceKeysApiV1UserServiceKeysGetData, GetServiceKeysApiV1UserServiceKeysGetError, GetServiceKeysApiV1UserServiceKeysGetResponse, GetSignedUrlApiV1S3SignedUrlGetData, GetSignedUrlApiV1S3SignedUrlGetError, GetSignedUrlApiV1S3SignedUrlGetResponse, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetData, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetError, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetResponse, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetData, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetError, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetResponse, GetTestSessionConversationApiV1LooptalkTestSessionsTestSessionIdConversationGetData, GetTestSessionConversationApiV1LooptalkTestSessionsTestSessionIdConversationGetError, GetToolApiV1ToolsToolUuidGetData, GetToolApiV1ToolsToolUuidGetError, GetToolApiV1ToolsToolUuidGetResponse, GetTurnCredentialsApiV1TurnCredentialsGetData, GetTurnCredentialsApiV1TurnCredentialsGetError, GetTurnCredentialsApiV1TurnCredentialsGetResponse, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostData, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostError, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostResponse, GetUsageHistoryApiV1OrganizationsUsageRunsGetData, GetUsageHistoryApiV1OrganizationsUsageRunsGetError, GetUsageHistoryApiV1OrganizationsUsageRunsGetResponse, GetUserConfigurationsApiV1UserConfigurationsUserGetData, GetUserConfigurationsApiV1UserConfigurationsUserGetError, GetUserConfigurationsApiV1UserConfigurationsUserGetResponse, GetVoicesApiV1UserConfigurationsVoicesProviderGetData, GetVoicesApiV1UserConfigurationsVoicesProviderGetError, GetVoicesApiV1UserConfigurationsVoicesProviderGetResponse, GetWorkflowApiV1WorkflowFetchWorkflowIdGetData, GetWorkflowApiV1WorkflowFetchWorkflowIdGetError, GetWorkflowApiV1WorkflowFetchWorkflowIdGetResponse, GetWorkflowCountApiV1WorkflowCountGetData, GetWorkflowCountApiV1WorkflowCountGetError, GetWorkflowCountApiV1WorkflowCountGetResponse, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetData, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetError, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetResponse, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetData, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetError, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetResponse, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetData, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetError, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetResponse, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetData, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetError, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetResponse, GetWorkflowsApiV1WorkflowFetchGetData, GetWorkflowsApiV1WorkflowFetchGetError, GetWorkflowsApiV1WorkflowFetchGetResponse, GetWorkflowsSummaryApiV1WorkflowSummaryGetData, GetWorkflowsSummaryApiV1WorkflowSummaryGetError, GetWorkflowsSummaryApiV1WorkflowSummaryGetResponse, GetWorkflowTemplatesApiV1WorkflowTemplatesGetData, GetWorkflowTemplatesApiV1WorkflowTemplatesGetResponse, HandleCloudonixCdrApiV1TelephonyCloudonixCdrPostData, HandleCloudonixStatusCallbackApiV1TelephonyCloudonixStatusCallbackWorkflowRunIdPostData, HandleCloudonixStatusCallbackApiV1TelephonyCloudonixStatusCallbackWorkflowRunIdPostError, HandleInboundFallbackApiV1TelephonyInboundFallbackPostData, HandleInboundTelephonyApiV1TelephonyInboundWorkflowIdPostData, HandleInboundTelephonyApiV1TelephonyInboundWorkflowIdPostError, HandleTwilioStatusCallbackApiV1TelephonyTwilioStatusCallbackWorkflowRunIdPostData, HandleTwilioStatusCallbackApiV1TelephonyTwilioStatusCallbackWorkflowRunIdPostError, HandleVobizHangupCallbackApiV1TelephonyVobizHangupCallbackWorkflowRunIdPostData, HandleVobizHangupCallbackApiV1TelephonyVobizHangupCallbackWorkflowRunIdPostError, HandleVobizHangupCallbackByWorkflowApiV1TelephonyVobizHangupCallbackWorkflowWorkflowIdPostData, HandleVobizHangupCallbackByWorkflowApiV1TelephonyVobizHangupCallbackWorkflowWorkflowIdPostError, HandleVobizRingCallbackApiV1TelephonyVobizRingCallbackWorkflowRunIdPostData, HandleVobizRingCallbackApiV1TelephonyVobizRingCallbackWorkflowRunIdPostError, HandleVonageEventsApiV1TelephonyVonageEventsWorkflowRunIdPostData, HandleVonageEventsApiV1TelephonyVonageEventsWorkflowRunIdPostError, HealthApiV1HealthGetData, HealthApiV1HealthGetResponse,ImpersonateApiV1SuperuserImpersonatePostData, ImpersonateApiV1SuperuserImpersonatePostError, ImpersonateApiV1SuperuserImpersonatePostResponse, InitializeEmbedSessionApiV1PublicEmbedInitPostData, InitializeEmbedSessionApiV1PublicEmbedInitPostError, InitializeEmbedSessionApiV1PublicEmbedInitPostResponse, InitiateCallApiV1PublicAgentUuidPostData, InitiateCallApiV1PublicAgentUuidPostError, InitiateCallApiV1PublicAgentUuidPostResponse, InitiateCallApiV1TelephonyInitiateCallPostData, InitiateCallApiV1TelephonyInitiateCallPostError, ListCredentialsApiV1CredentialsGetData, ListCredentialsApiV1CredentialsGetError, ListCredentialsApiV1CredentialsGetResponse, ListDocumentsApiV1KnowledgeBaseDocumentsGetData, ListDocumentsApiV1KnowledgeBaseDocumentsGetError, ListDocumentsApiV1KnowledgeBaseDocumentsGetResponse, ListTestSessionsApiV1LooptalkTestSessionsGetData, ListTestSessionsApiV1LooptalkTestSessionsGetError, ListTestSessionsApiV1LooptalkTestSessionsGetResponse, ListToolsApiV1ToolsGetData, ListToolsApiV1ToolsGetError, ListToolsApiV1ToolsGetResponse, OptionsConfigApiV1PublicEmbedConfigTokenOptionsData, OptionsConfigApiV1PublicEmbedConfigTokenOptionsError, OptionsInitApiV1PublicEmbedInitOptionsData, PauseCampaignApiV1CampaignCampaignIdPausePostData, PauseCampaignApiV1CampaignCampaignIdPausePostError, PauseCampaignApiV1CampaignCampaignIdPausePostResponse, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostData, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostError, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostResponse, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutData, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutError, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutResponse, ReactivateServiceKeyApiV1UserServiceKeysServiceKeyIdReactivatePutData, ReactivateServiceKeyApiV1UserServiceKeysServiceKeyIdReactivatePutError, ResumeCampaignApiV1CampaignCampaignIdResumePostData, ResumeCampaignApiV1CampaignCampaignIdResumePostError, ResumeCampaignApiV1CampaignCampaignIdResumePostResponse, SaveTelephonyConfigurationApiV1OrganizationsTelephonyConfigPostData, SaveTelephonyConfigurationApiV1OrganizationsTelephonyConfigPostError, SearchChunksApiV1KnowledgeBaseSearchPostData, SearchChunksApiV1KnowledgeBaseSearchPostError, SearchChunksApiV1KnowledgeBaseSearchPostResponse, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostData, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostError, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostResponse, StartCampaignApiV1CampaignCampaignIdStartPostData, StartCampaignApiV1CampaignCampaignIdStartPostError, StartCampaignApiV1CampaignCampaignIdStartPostResponse, StartTestSessionApiV1LooptalkTestSessionsTestSessionIdStartPostData, StartTestSessionApiV1LooptalkTestSessionsTestSessionIdStartPostError, StopTestSessionApiV1LooptalkTestSessionsTestSessionIdStopPostData, StopTestSessionApiV1LooptalkTestSessionsTestSessionIdStopPostError, UnarchiveToolApiV1ToolsToolUuidUnarchivePostData, UnarchiveToolApiV1ToolsToolUuidUnarchivePostError, UnarchiveToolApiV1ToolsToolUuidUnarchivePostResponse, UpdateCredentialApiV1CredentialsCredentialUuidPutData, UpdateCredentialApiV1CredentialsCredentialUuidPutError, UpdateCredentialApiV1CredentialsCredentialUuidPutResponse, UpdateIntegrationApiV1IntegrationIntegrationIdPutData, UpdateIntegrationApiV1IntegrationIntegrationIdPutError, UpdateIntegrationApiV1IntegrationIntegrationIdPutResponse, UpdateToolApiV1ToolsToolUuidPutData, UpdateToolApiV1ToolsToolUuidPutError, UpdateToolApiV1ToolsToolUuidPutResponse, UpdateUserConfigurationsApiV1UserConfigurationsUserPutData, UpdateUserConfigurationsApiV1UserConfigurationsUserPutError, UpdateUserConfigurationsApiV1UserConfigurationsUserPutResponse, UpdateWorkflowApiV1WorkflowWorkflowIdPutData, UpdateWorkflowApiV1WorkflowWorkflowIdPutError, UpdateWorkflowApiV1WorkflowWorkflowIdPutResponse, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutData, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutError, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutResponse, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetData, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetError, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetResponse, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostData, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostError, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostResponse } from './types.gen'; +import type { ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteData, ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteError, ArchiveApiKeyApiV1UserApiKeysApiKeyIdDeleteResponse, ArchiveServiceKeyApiV1UserServiceKeysServiceKeyIdDeleteData, ArchiveServiceKeyApiV1UserServiceKeysServiceKeyIdDeleteError, CreateApiKeyApiV1UserApiKeysPostData, CreateApiKeyApiV1UserApiKeysPostError, CreateApiKeyApiV1UserApiKeysPostResponse, CreateCampaignApiV1CampaignCreatePostData, CreateCampaignApiV1CampaignCreatePostError, CreateCampaignApiV1CampaignCreatePostResponse, CreateCredentialApiV1CredentialsPostData, CreateCredentialApiV1CredentialsPostError, CreateCredentialApiV1CredentialsPostResponse, CreateLoadTestApiV1LooptalkLoadTestsPostData, CreateLoadTestApiV1LooptalkLoadTestsPostError, CreateLoadTestApiV1LooptalkLoadTestsPostResponse, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostData, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostError, CreateOrUpdateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenPostResponse, CreateServiceKeyApiV1UserServiceKeysPostData, CreateServiceKeyApiV1UserServiceKeysPostError, CreateServiceKeyApiV1UserServiceKeysPostResponse, CreateSessionApiV1IntegrationSessionPostData, CreateSessionApiV1IntegrationSessionPostError, CreateSessionApiV1IntegrationSessionPostResponse, CreateTestSessionApiV1LooptalkTestSessionsPostData, CreateTestSessionApiV1LooptalkTestSessionsPostError, CreateTestSessionApiV1LooptalkTestSessionsPostResponse, CreateToolApiV1ToolsPostData, CreateToolApiV1ToolsPostError, CreateToolApiV1ToolsPostResponse, CreateWorkflowApiV1WorkflowCreateDefinitionPostData, CreateWorkflowApiV1WorkflowCreateDefinitionPostError, CreateWorkflowApiV1WorkflowCreateDefinitionPostResponse, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostData, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostError, CreateWorkflowFromTemplateApiV1WorkflowCreateTemplatePostResponse, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostData, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostError, CreateWorkflowRunApiV1WorkflowWorkflowIdRunsPostResponse, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteData, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteError, DeactivateEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenDeleteResponse, DeleteCredentialApiV1CredentialsCredentialUuidDeleteData, DeleteCredentialApiV1CredentialsCredentialUuidDeleteError, DeleteCredentialApiV1CredentialsCredentialUuidDeleteResponse, DeleteDocumentApiV1KnowledgeBaseDocumentsDocumentUuidDeleteData, DeleteDocumentApiV1KnowledgeBaseDocumentsDocumentUuidDeleteError, DeleteToolApiV1ToolsToolUuidDeleteData, DeleteToolApiV1ToolsToolUuidDeleteError, DeleteToolApiV1ToolsToolUuidDeleteResponse, DownloadWorkflowArtifactApiV1PublicDownloadWorkflowTokenArtifactTypeGetData, DownloadWorkflowArtifactApiV1PublicDownloadWorkflowTokenArtifactTypeGetError, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostData, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostError, DuplicateWorkflowTemplateApiV1WorkflowTemplatesDuplicatePostResponse, GetActiveTestsApiV1LooptalkActiveTestsGetData, GetActiveTestsApiV1LooptalkActiveTestsGetError, GetApiKeysApiV1UserApiKeysGetData, GetApiKeysApiV1UserApiKeysGetError, GetApiKeysApiV1UserApiKeysGetResponse, GetAuthUserApiV1UserAuthUserGetData, GetAuthUserApiV1UserAuthUserGetError, GetAuthUserApiV1UserAuthUserGetResponse, GetCampaignApiV1CampaignCampaignIdGetData, GetCampaignApiV1CampaignCampaignIdGetError, GetCampaignApiV1CampaignCampaignIdGetResponse, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetData, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetError, GetCampaignLimitsApiV1OrganizationsCampaignLimitsGetResponse, GetCampaignProgressApiV1CampaignCampaignIdProgressGetData, GetCampaignProgressApiV1CampaignCampaignIdProgressGetError, GetCampaignProgressApiV1CampaignCampaignIdProgressGetResponse, GetCampaignRunsApiV1CampaignCampaignIdRunsGetData, GetCampaignRunsApiV1CampaignCampaignIdRunsGetError, GetCampaignRunsApiV1CampaignCampaignIdRunsGetResponse, GetCampaignsApiV1CampaignGetData, GetCampaignsApiV1CampaignGetError, GetCampaignsApiV1CampaignGetResponse, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetData, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetError, GetCampaignSourceDownloadUrlApiV1CampaignCampaignIdSourceDownloadUrlGetResponse, GetCredentialApiV1CredentialsCredentialUuidGetData, GetCredentialApiV1CredentialsCredentialUuidGetError, GetCredentialApiV1CredentialsCredentialUuidGetResponse, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetData, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetError, GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponse, GetDailyReportApiV1OrganizationsReportsDailyGetData, GetDailyReportApiV1OrganizationsReportsDailyGetError, GetDailyReportApiV1OrganizationsReportsDailyGetResponse, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetData, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetError, GetDailyRunsDetailApiV1OrganizationsReportsDailyRunsGetResponse, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetData, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetError, GetDailyUsageBreakdownApiV1OrganizationsUsageDailyBreakdownGetResponse, GetDefaultConfigurationsApiV1UserConfigurationsDefaultsGetData, GetDefaultConfigurationsApiV1UserConfigurationsDefaultsGetResponse, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetData, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetError, GetDocumentApiV1KnowledgeBaseDocumentsDocumentUuidGetResponse, GetEmbedConfigApiV1PublicEmbedConfigTokenGetData, GetEmbedConfigApiV1PublicEmbedConfigTokenGetError, GetEmbedConfigApiV1PublicEmbedConfigTokenGetResponse, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetData, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetError, GetEmbedTokenApiV1WorkflowWorkflowIdEmbedTokenGetResponse, GetFileMetadataApiV1S3FileMetadataGetData, GetFileMetadataApiV1S3FileMetadataGetError, GetFileMetadataApiV1S3FileMetadataGetResponse, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetData, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetError, GetIntegrationAccessTokenApiV1IntegrationIntegrationIdAccessTokenGetResponse, GetIntegrationsApiV1IntegrationGetData, GetIntegrationsApiV1IntegrationGetError, GetIntegrationsApiV1IntegrationGetResponse, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetData, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetError, GetLoadTestStatsApiV1LooptalkLoadTestsLoadTestGroupIdStatsGetResponse, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostData, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostError, GetPresignedUploadUrlApiV1S3PresignedUploadUrlPostResponse, GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetData, GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetError, GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetResponse, GetServiceKeysApiV1UserServiceKeysGetData, GetServiceKeysApiV1UserServiceKeysGetError, GetServiceKeysApiV1UserServiceKeysGetResponse, GetSignedUrlApiV1S3SignedUrlGetData, GetSignedUrlApiV1S3SignedUrlGetError, GetSignedUrlApiV1S3SignedUrlGetResponse, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetData, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetError, GetTelephonyConfigurationApiV1OrganizationsTelephonyConfigGetResponse, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetData, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetError, GetTestSessionApiV1LooptalkTestSessionsTestSessionIdGetResponse, GetTestSessionConversationApiV1LooptalkTestSessionsTestSessionIdConversationGetData, GetTestSessionConversationApiV1LooptalkTestSessionsTestSessionIdConversationGetError, GetToolApiV1ToolsToolUuidGetData, GetToolApiV1ToolsToolUuidGetError, GetToolApiV1ToolsToolUuidGetResponse, GetTurnCredentialsApiV1TurnCredentialsGetData, GetTurnCredentialsApiV1TurnCredentialsGetError, GetTurnCredentialsApiV1TurnCredentialsGetResponse, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostData, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostError, GetUploadUrlApiV1KnowledgeBaseUploadUrlPostResponse, GetUsageHistoryApiV1OrganizationsUsageRunsGetData, GetUsageHistoryApiV1OrganizationsUsageRunsGetError, GetUsageHistoryApiV1OrganizationsUsageRunsGetResponse, GetUserConfigurationsApiV1UserConfigurationsUserGetData, GetUserConfigurationsApiV1UserConfigurationsUserGetError, GetUserConfigurationsApiV1UserConfigurationsUserGetResponse, GetVoicesApiV1UserConfigurationsVoicesProviderGetData, GetVoicesApiV1UserConfigurationsVoicesProviderGetError, GetVoicesApiV1UserConfigurationsVoicesProviderGetResponse, GetWorkflowApiV1WorkflowFetchWorkflowIdGetData, GetWorkflowApiV1WorkflowFetchWorkflowIdGetError, GetWorkflowApiV1WorkflowFetchWorkflowIdGetResponse, GetWorkflowCountApiV1WorkflowCountGetData, GetWorkflowCountApiV1WorkflowCountGetError, GetWorkflowCountApiV1WorkflowCountGetResponse, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetData, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetError, GetWorkflowOptionsApiV1OrganizationsReportsWorkflowsGetResponse, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetData, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetError, GetWorkflowRunApiV1WorkflowWorkflowIdRunsRunIdGetResponse, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetData, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetError, GetWorkflowRunsApiV1SuperuserWorkflowRunsGetResponse, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetData, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetError, GetWorkflowRunsApiV1WorkflowWorkflowIdRunsGetResponse, GetWorkflowsApiV1WorkflowFetchGetData, GetWorkflowsApiV1WorkflowFetchGetError, GetWorkflowsApiV1WorkflowFetchGetResponse, GetWorkflowsSummaryApiV1WorkflowSummaryGetData, GetWorkflowsSummaryApiV1WorkflowSummaryGetError, GetWorkflowsSummaryApiV1WorkflowSummaryGetResponse, GetWorkflowTemplatesApiV1WorkflowTemplatesGetData, GetWorkflowTemplatesApiV1WorkflowTemplatesGetResponse, HandleCloudonixCdrApiV1TelephonyCloudonixCdrPostData, HandleCloudonixStatusCallbackApiV1TelephonyCloudonixStatusCallbackWorkflowRunIdPostData, HandleCloudonixStatusCallbackApiV1TelephonyCloudonixStatusCallbackWorkflowRunIdPostError, HandleInboundFallbackApiV1TelephonyInboundFallbackPostData, HandleInboundTelephonyApiV1TelephonyInboundWorkflowIdPostData, HandleInboundTelephonyApiV1TelephonyInboundWorkflowIdPostError, HandleTwilioStatusCallbackApiV1TelephonyTwilioStatusCallbackWorkflowRunIdPostData, HandleTwilioStatusCallbackApiV1TelephonyTwilioStatusCallbackWorkflowRunIdPostError, HandleVobizHangupCallbackApiV1TelephonyVobizHangupCallbackWorkflowRunIdPostData, HandleVobizHangupCallbackApiV1TelephonyVobizHangupCallbackWorkflowRunIdPostError, HandleVobizHangupCallbackByWorkflowApiV1TelephonyVobizHangupCallbackWorkflowWorkflowIdPostData, HandleVobizHangupCallbackByWorkflowApiV1TelephonyVobizHangupCallbackWorkflowWorkflowIdPostError, HandleVobizRingCallbackApiV1TelephonyVobizRingCallbackWorkflowRunIdPostData, HandleVobizRingCallbackApiV1TelephonyVobizRingCallbackWorkflowRunIdPostError, HandleVonageEventsApiV1TelephonyVonageEventsWorkflowRunIdPostData, HandleVonageEventsApiV1TelephonyVonageEventsWorkflowRunIdPostError, HealthApiV1HealthGetData, HealthApiV1HealthGetResponse,ImpersonateApiV1SuperuserImpersonatePostData, ImpersonateApiV1SuperuserImpersonatePostError, ImpersonateApiV1SuperuserImpersonatePostResponse, InitializeEmbedSessionApiV1PublicEmbedInitPostData, InitializeEmbedSessionApiV1PublicEmbedInitPostError, InitializeEmbedSessionApiV1PublicEmbedInitPostResponse, InitiateCallApiV1PublicAgentUuidPostData, InitiateCallApiV1PublicAgentUuidPostError, InitiateCallApiV1PublicAgentUuidPostResponse, InitiateCallApiV1TelephonyInitiateCallPostData, InitiateCallApiV1TelephonyInitiateCallPostError, ListCredentialsApiV1CredentialsGetData, ListCredentialsApiV1CredentialsGetError, ListCredentialsApiV1CredentialsGetResponse, ListDocumentsApiV1KnowledgeBaseDocumentsGetData, ListDocumentsApiV1KnowledgeBaseDocumentsGetError, ListDocumentsApiV1KnowledgeBaseDocumentsGetResponse, ListTestSessionsApiV1LooptalkTestSessionsGetData, ListTestSessionsApiV1LooptalkTestSessionsGetError, ListTestSessionsApiV1LooptalkTestSessionsGetResponse, ListToolsApiV1ToolsGetData, ListToolsApiV1ToolsGetError, ListToolsApiV1ToolsGetResponse, OptionsConfigApiV1PublicEmbedConfigTokenOptionsData, OptionsConfigApiV1PublicEmbedConfigTokenOptionsError, OptionsInitApiV1PublicEmbedInitOptionsData, OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsData, OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsError, PauseCampaignApiV1CampaignCampaignIdPausePostData, PauseCampaignApiV1CampaignCampaignIdPausePostError, PauseCampaignApiV1CampaignCampaignIdPausePostResponse, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostData, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostError, ProcessDocumentApiV1KnowledgeBaseProcessDocumentPostResponse, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutData, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutError, ReactivateApiKeyApiV1UserApiKeysApiKeyIdReactivatePutResponse, ReactivateServiceKeyApiV1UserServiceKeysServiceKeyIdReactivatePutData, ReactivateServiceKeyApiV1UserServiceKeysServiceKeyIdReactivatePutError, ResumeCampaignApiV1CampaignCampaignIdResumePostData, ResumeCampaignApiV1CampaignCampaignIdResumePostError, ResumeCampaignApiV1CampaignCampaignIdResumePostResponse, SaveTelephonyConfigurationApiV1OrganizationsTelephonyConfigPostData, SaveTelephonyConfigurationApiV1OrganizationsTelephonyConfigPostError, SearchChunksApiV1KnowledgeBaseSearchPostData, SearchChunksApiV1KnowledgeBaseSearchPostError, SearchChunksApiV1KnowledgeBaseSearchPostResponse, SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostData, SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostError, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostData, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostError, SetAdminCommentApiV1SuperuserWorkflowRunsRunIdCommentPostResponse, StartCampaignApiV1CampaignCampaignIdStartPostData, StartCampaignApiV1CampaignCampaignIdStartPostError, StartCampaignApiV1CampaignCampaignIdStartPostResponse, StartTestSessionApiV1LooptalkTestSessionsTestSessionIdStartPostData, StartTestSessionApiV1LooptalkTestSessionsTestSessionIdStartPostError, StopTestSessionApiV1LooptalkTestSessionsTestSessionIdStopPostData, StopTestSessionApiV1LooptalkTestSessionsTestSessionIdStopPostError, UnarchiveToolApiV1ToolsToolUuidUnarchivePostData, UnarchiveToolApiV1ToolsToolUuidUnarchivePostError, UnarchiveToolApiV1ToolsToolUuidUnarchivePostResponse, UpdateCredentialApiV1CredentialsCredentialUuidPutData, UpdateCredentialApiV1CredentialsCredentialUuidPutError, UpdateCredentialApiV1CredentialsCredentialUuidPutResponse, UpdateIntegrationApiV1IntegrationIntegrationIdPutData, UpdateIntegrationApiV1IntegrationIntegrationIdPutError, UpdateIntegrationApiV1IntegrationIntegrationIdPutResponse, UpdateToolApiV1ToolsToolUuidPutData, UpdateToolApiV1ToolsToolUuidPutError, UpdateToolApiV1ToolsToolUuidPutResponse, UpdateUserConfigurationsApiV1UserConfigurationsUserPutData, UpdateUserConfigurationsApiV1UserConfigurationsUserPutError, UpdateUserConfigurationsApiV1UserConfigurationsUserPutResponse, UpdateWorkflowApiV1WorkflowWorkflowIdPutData, UpdateWorkflowApiV1WorkflowWorkflowIdPutError, UpdateWorkflowApiV1WorkflowWorkflowIdPutResponse, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutData, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutError, UpdateWorkflowStatusApiV1WorkflowWorkflowIdStatusPutResponse, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetData, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetError, ValidateUserConfigurationsApiV1UserConfigurationsUserValidateGetResponse, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostData, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostError, ValidateWorkflowApiV1WorkflowWorkflowIdValidatePostResponse } from './types.gen'; export type Options = ClientOptions & { /** @@ -150,6 +150,28 @@ export const handleCloudonixCdrApiV1TelephonyCloudonixCdrPost = (options: Options) => { + return (options.client ?? _heyApiClient).post({ + url: '/api/v1/telephony/transfer-signal/{workflow_run_id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options?.headers + } + }); +}; + /** * Impersonate * Impersonate a user as a super-admin. @@ -1337,6 +1359,37 @@ export const optionsConfigApiV1PublicEmbedConfigTokenOptions = (options: Options) => { + return (options.client ?? _heyApiClient).get({ + url: '/api/v1/public/embed/turn-credentials/{session_token}', + ...options + }); +}; + +/** + * Options Turn Credentials + * Handle CORS preflight for TURN credentials endpoint + */ +export const optionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptions = (options: Options) => { + return (options.client ?? _heyApiClient).options({ + url: '/api/v1/public/embed/turn-credentials/{session_token}', + ...options + }); +}; + /** * Initiate Call * Initiate a phone call via API trigger. @@ -1469,9 +1522,8 @@ export const getUploadUrlApiV1KnowledgeBaseUploadUrlPost = 'processing' -> 'completed' or 'failed'. * - * Embedding Services: - * * openai (default): High-quality 1536-dimensional embeddings (requires OPENAI_API_KEY) - * * sentence_transformer: Free, offline-capable, 384-dimensional embeddings + * Embedding: + * Uses OpenAI text-embedding-3-small (1536-dimensional embeddings, requires API key configured in Model Configurations). * * Access Control: * * Users can only process documents in their organization. diff --git a/ui/src/client/types.gen.ts b/ui/src/client/types.gen.ts index dc94d937..b954801a 100644 --- a/ui/src/client/types.gen.ts +++ b/ui/src/client/types.gen.ts @@ -258,7 +258,9 @@ export type CreateToolRequest = { type?: 'http_api'; } & HttpApiToolDefinition) | ({ type?: 'end_call'; - } & EndCallToolDefinition); + } & EndCallToolDefinition) | ({ + type?: 'transfer_call'; + } & TransferCallToolDefinition); }; export type CreateWorkflowRequest = { @@ -705,10 +707,6 @@ export type ProcessDocumentRequestSchema = { * S3 key of the uploaded file */ s3_key: string; - /** - * Embedding service to use for processing. Options: 'openai' (default, 1536-dim, requires API key) or 'sentence_transformer' (free, 384-dim) - */ - embedding_service?: 'sentence_transformer' | 'openai'; }; export type RetryConfigRequest = { @@ -860,6 +858,46 @@ export type ToolResponse = { created_by?: CreatedByResponse | null; }; +/** + * Configuration for Transfer Call tools. + */ +export type TransferCallConfig = { + /** + * Number to transfer the call to + */ + transfer_number: string; + /** + * Message to play before transferring the call + */ + transfer_message?: string | null; +}; + +/** + * Tool definition for Transfer Call tools. + */ +export type TransferCallToolDefinition = { + /** + * Schema version + */ + schema_version?: number; + /** + * Tool type + */ + type: 'transfer_call'; + /** + * Transfer Call configuration + */ + config: TransferCallConfig; +}; + +/** + * Request to send a transfer signal. + */ +export type TransferSignalRequest = { + action?: string; + message?: string | null; +}; + /** * Request model for triggering a call via API */ @@ -948,7 +986,9 @@ export type UpdateToolRequest = { type?: 'http_api'; } & HttpApiToolDefinition) | ({ type?: 'end_call'; - } & EndCallToolDefinition)) | null; + } & EndCallToolDefinition) | ({ + type?: 'transfer_call'; + } & TransferCallToolDefinition)) | null; status?: string | null; }; @@ -1530,6 +1570,35 @@ export type HandleCloudonixCdrApiV1TelephonyCloudonixCdrPostResponses = { 200: unknown; }; +export type SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostData = { + body: TransferSignalRequest; + path: { + workflow_run_id: number; + }; + query?: never; + url: '/api/v1/telephony/transfer-signal/{workflow_run_id}'; +}; + +export type SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostErrors = { + /** + * Not found + */ + 404: unknown; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostError = SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostErrors[keyof SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostErrors]; + +export type SendTransferSignalEndpointApiV1TelephonyTransferSignalWorkflowRunIdPostResponses = { + /** + * Successful Response + */ + 200: unknown; +}; + export type ImpersonateApiV1SuperuserImpersonatePostData = { body: ImpersonateRequest; headers?: { @@ -4354,6 +4423,66 @@ export type OptionsConfigApiV1PublicEmbedConfigTokenOptionsResponses = { 200: unknown; }; +export type GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetData = { + body?: never; + path: { + session_token: string; + }; + query?: never; + url: '/api/v1/public/embed/turn-credentials/{session_token}'; +}; + +export type GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetErrors = { + /** + * Not found + */ + 404: unknown; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetError = GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetErrors[keyof GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetErrors]; + +export type GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetResponses = { + /** + * Successful Response + */ + 200: TurnCredentialsResponse; +}; + +export type GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetResponse = GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetResponses[keyof GetPublicTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenGetResponses]; + +export type OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsData = { + body?: never; + path: { + session_token: string; + }; + query?: never; + url: '/api/v1/public/embed/turn-credentials/{session_token}'; +}; + +export type OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsErrors = { + /** + * Not found + */ + 404: unknown; + /** + * Validation Error + */ + 422: HttpValidationError; +}; + +export type OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsError = OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsErrors[keyof OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsErrors]; + +export type OptionsTurnCredentialsApiV1PublicEmbedTurnCredentialsSessionTokenOptionsResponses = { + /** + * Successful Response + */ + 200: unknown; +}; + export type InitiateCallApiV1PublicAgentUuidPostData = { body: TriggerCallRequest; headers: {