Repository: livekit/agents
File: livekit-agents/livekit/agents/beta/tools/end_call.py (Python)

Code before:
from ...llm import Tool, Toolset, function_tool
from ...log import logger
from ...voice.events import CloseEvent, RunContext

END_CALL_INSTRUCTIONS = """
Ends the current call and disconnects immediately.

Call when:
- The user clearly indicates they are done (e.g., “that’s all, bye”).
- The agent determines the conversation is complete and should end.

Do not call when:
- The user asks to pause, hold, or transfer.
- Intent is unclear.

This is the final action the agent can take.
Once called, no further interaction is possible with the user.
Don't generate any other text or response when the tool is called.
"""


class EndCallTool(Toolset):
    def __init__(
        self,
        *,
        extra_instructions: str = "",
        delete_room: bool = True,
        end_instructions: str
        | Callable[[RunContext], Awaitable[None]]
        | None = "say goodbye to the user",
    ):
        """
        This tool allows the agent to end the call and disconnect from the room.

        Args:
            extra_instructions: Additional instructions to add to the end call tool.
            delete_room: Whether to delete the room when the user ends the call.
            end_instructions: If a string is provided, it will be used as the instructions of
                `session.generate_reply` when the user ends the call. If a callback, it will be called
                when the user ends the call.
        """
        super().__init__()
        self._delete_room = delete_room
        self._extra_instructions = extra_instructions
        self._end_instructions = end_instructions

        self._end_call_tool = function_tool(
            self._end_call,
            name="end_call",
            description=f"{END_CALL_INSTRUCTIONS}\n{extra_instructions}",
        )

Review comment (suggestion):
```suggestion
        extra_description: str = "",
```

Code after:
from ...job import get_job_context
from ...llm import RealtimeModel, Tool, Toolset, function_tool
from ...log import logger
from ...voice.events import CloseEvent, RunContext, SpeechCreatedEvent
from ...voice.speech_handle import SpeechHandle

END_CALL_DESCRIPTION = """
Ends the current call and disconnects immediately.

Call when:
- The user clearly indicates they are done (e.g., “that’s all, bye”).
- The agent determines the conversation is complete and should end.

Do not call when:
- The user asks to pause, hold, or transfer.
- Intent is unclear.

This is the final action the agent can take.
Once called, no further interaction is possible with the user.
Don't generate any other text or response when the tool is called.
"""


class EndCallTool(Toolset):
    def __init__(
        self,
        *,
        extra_description: str = "",
        delete_room: bool = True,
        end_instructions: str | None = "say goodbye to the user",
        on_tool_called: Callable[[Toolset.ToolCalledEvent], Awaitable[None]] | None = None,
        on_tool_completed: Callable[[Toolset.ToolCompletedEvent], Awaitable[None]] | None = None,
    ):
        """
        This tool allows the agent to end the call and disconnect from the room.

        Args:
            extra_description: Additional description to add to the end call tool.
            delete_room: Whether to delete the room when the user ends the call. deleting the room disconnects all remote users, including SIP callers.
            end_instructions: Tool output to the LLM for generating the tool response.
            on_tool_called: Callback to call when the tool is called.
            on_tool_completed: Callback to call when the tool is completed.
        """
        super().__init__()
        self._delete_room = delete_room
        self._extra_description = extra_description

        self._end_instructions = end_instructions
        self._on_tool_called = on_tool_called
        self._on_tool_completed = on_tool_completed