Handler for containing the EVI WebSocket and associated socket handling behavior.
| 13 | from utils import print_prompt, extract_top_n_emotions, print_emotion_scores |
| 14 | |
| 15 | class WebSocketHandler: |
| 16 | """Handler for containing the EVI WebSocket and associated socket handling behavior.""" |
| 17 | |
| 18 | def __init__(self): |
| 19 | """Construct the WebSocketHandler, initially assigning the socket to None and the byte stream to a new Stream object.""" |
| 20 | self.socket = None |
| 21 | self.byte_strs = Stream.new() |
| 22 | |
| 23 | def set_socket(self, socket: AsyncChatSocketClient): |
| 24 | """Set the socket. |
| 25 | |
| 26 | This method assigns the provided asynchronous WebSocket connection |
| 27 | to the instance variable `self.socket`. It is invoked after successfully |
| 28 | establishing a connection using the client's connect method. |
| 29 | |
| 30 | Args: |
| 31 | socket (AsyncChatSocketClient): EVI asynchronous WebSocket returned by the client's connect method. |
| 32 | """ |
| 33 | self.socket = socket |
| 34 | |
| 35 | async def handle_tool_call(self, message: ToolCallMessage) -> Union[ToolCallMessage, ToolErrorMessage]: |
| 36 | """Functionality which executes when a tool call is invoked. |
| 37 | |
| 38 | Args: |
| 39 | message (ToolCallMessage): The message sent when a tool call is invoked. See it in the API Reference [here](https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat#receive.Tool%20Call%20Message.name). |
| 40 | |
| 41 | Returns: |
| 42 | Union[ToolResponseMessage, ToolErrorMessage]: Returns a [ToolResponseMessage](https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat#send.Tool%20Response%20Message.type) if the tool call is succesful or a [ToolErrorMessage](https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat#send.Tool%20Error%20Message.type) if the tool call fails. |
| 43 | """ |
| 44 | |
| 45 | # Obtain the name, ID, and parameters of the tool call |
| 46 | tool_name = message.name |
| 47 | tool_call_id = message.tool_call_id |
| 48 | |
| 49 | # Parse the stringified JSON parameters into a dictionary |
| 50 | try: |
| 51 | tool_parameters = json.loads(message.parameters) |
| 52 | except json.JSONDecodeError: |
| 53 | resp = ToolErrorMessage( |
| 54 | tool_call_id=tool_call_id, |
| 55 | content="Invalid parameters format.", |
| 56 | error="JSONDecodeError" |
| 57 | ) |
| 58 | await self.socket.send_tool_error(resp) |
| 59 | print(f"(Sent ToolErrorMessage for tool_call_id {tool_call_id} due to JSON decode error.)\n") |
| 60 | return |
| 61 | |
| 62 | if tool_name == "get_current_weather": |
| 63 | obtained_location = tool_parameters.get('location') |
| 64 | obtained_format = tool_parameters.get('format', 'text') |
| 65 | |
| 66 | if not obtained_location: |
| 67 | resp = ToolErrorMessage( |
| 68 | tool_call_id=tool_call_id, |
| 69 | content="Missing 'location' parameter.", |
| 70 | error="MissingParameter" |
| 71 | ) |
| 72 | await self.socket.send_tool_error(resp) |