From 97a44f00ffa85a274d7ac0a6268819c5002d6276 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 6 Feb 2026 09:45:34 +0530 Subject: [PATCH] add transfer call tool editor --- ...f5db3dfa1f62_add_transfer_call_category.py | 63 +++++++++++++ api/routes/tool.py | 4 +- .../workflow/pipecat_engine_custom_tools.py | 4 +- .../components/TransferCallToolConfig.tsx | 92 ++++++++++++++++++ .../app/tools/[toolUuid]/components/index.ts | 1 + ui/src/app/tools/[toolUuid]/page.tsx | 94 ++++++++++++++----- 6 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 api/alembic/versions/f5db3dfa1f62_add_transfer_call_category.py create mode 100644 ui/src/app/tools/[toolUuid]/components/TransferCallToolConfig.tsx diff --git a/api/alembic/versions/f5db3dfa1f62_add_transfer_call_category.py b/api/alembic/versions/f5db3dfa1f62_add_transfer_call_category.py new file mode 100644 index 0000000..5900dd8 --- /dev/null +++ b/api/alembic/versions/f5db3dfa1f62_add_transfer_call_category.py @@ -0,0 +1,63 @@ +"""add transfer call category + +Revision ID: f5db3dfa1f62 +Revises: 34c8537dfde5 +Create Date: 2026-02-06 09:24:44.887105 + +""" + +from typing import Sequence, Union + +import sqlalchemy as sa +from alembic import op +from alembic_postgresql_enum import TableReference + +# revision identifiers, used by Alembic. +revision: str = "f5db3dfa1f62" +down_revision: Union[str, None] = "34c8537dfde5" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_index( + "idx_queued_runs_campaign_state_optimized", + "queued_runs", + ["campaign_id", "state"], + unique=False, + postgresql_where=sa.text("state = 'queued'"), + ) + op.sync_enum_values( + enum_schema="public", + enum_name="tool_category", + new_values=["http_api", "end_call", "transfer_call", "native", "integration"], + affected_columns=[ + TableReference( + table_schema="public", table_name="tools", column_name="category" + ) + ], + enum_values_to_rename=[], + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.sync_enum_values( + enum_schema="public", + enum_name="tool_category", + new_values=["http_api", "end_call", "native", "integration"], + affected_columns=[ + TableReference( + table_schema="public", table_name="tools", column_name="category" + ) + ], + enum_values_to_rename=[], + ) + op.drop_index( + "idx_queued_runs_campaign_state_optimized", + table_name="queued_runs", + postgresql_where=sa.text("state = 'queued'"), + ) + # ### end Alembic commands ### diff --git a/api/routes/tool.py b/api/routes/tool.py index b54d83f..829c3ac 100644 --- a/api/routes/tool.py +++ b/api/routes/tool.py @@ -75,8 +75,8 @@ class EndCallToolDefinition(BaseModel): class TransferCallConfig(BaseModel): """Configuration for Transfer Call tools.""" - transfer_number: str = Field(description="Number to transfer the call to") - transfer_message: Optional[str] = Field( + transferNumber: str = Field(description="Number to transfer the call to") + transferMessage: Optional[str] = Field( default=None, description="Message to play before transferring the call" ) diff --git a/api/services/workflow/pipecat_engine_custom_tools.py b/api/services/workflow/pipecat_engine_custom_tools.py index 7481537..3bcd120 100644 --- a/api/services/workflow/pipecat_engine_custom_tools.py +++ b/api/services/workflow/pipecat_engine_custom_tools.py @@ -279,7 +279,9 @@ class CustomToolManager: # Wait for the audio to play or until stopped try: - await asyncio.wait_for(stop_event.wait(), timeout=duration_secs) + await asyncio.wait_for( + stop_event.wait(), timeout=duration_secs + 1.5 + ) break # Stop event was set except asyncio.TimeoutError: pass # Continue looping diff --git a/ui/src/app/tools/[toolUuid]/components/TransferCallToolConfig.tsx b/ui/src/app/tools/[toolUuid]/components/TransferCallToolConfig.tsx new file mode 100644 index 0000000..028c5a5 --- /dev/null +++ b/ui/src/app/tools/[toolUuid]/components/TransferCallToolConfig.tsx @@ -0,0 +1,92 @@ +"use client"; + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; + +export interface TransferCallToolConfigProps { + name: string; + onNameChange: (name: string) => void; + description: string; + onDescriptionChange: (description: string) => void; + transferNumber: string; + onTransferNumberChange: (number: string) => void; + transferMessage: string; + onTransferMessageChange: (message: string) => void; +} + +export function TransferCallToolConfig({ + name, + onNameChange, + description, + onDescriptionChange, + transferNumber, + onTransferNumberChange, + transferMessage, + onTransferMessageChange, +}: TransferCallToolConfigProps) { + return ( + + + Transfer Call Configuration + + Configure call transfer behavior + + + +
+ + + onNameChange(e.target.value)} + placeholder="e.g., Transfer Call" + /> +
+ +
+ + +