You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We are trying to use the addTool function in the relay server's instance of RealtimeClient, but it seems the tool handlers are never triggered when the tool is invoked. Instead, the tool logic appears to be bypassed entirely.
Here's a minimal code example demonstrating the issue:
Code Example
import{WebSocketServer,WebSocket}from"ws";import{RealtimeClient}from"@openai/realtime-api-beta";import{personalInstruction}from"../constants/personalInstruction";exporttypeRealtimeEvent={type: string;[key: string]: unknown;// Allow for additional properties in the event object};exportclassRealtimeRelay{privateapiKey: string;privatewss: WebSocketServer|null;constructor(apiKey: string){this.apiKey=apiKey;this.wss=null;}listen(port: number): void{this.wss=newWebSocketServer({ port });this.wss.on("connection",this.connectionHandler.bind(this));this.log(`Listening on ws://localhost:${port}`);}privateasyncconnectionHandler(ws: WebSocket,req: {url?: string;headers: {host?: string}},): Promise<void>{if(!req.url){this.log("No URL provided, closing connection.");ws.close();return;}consturl=newURL(req.url,`http://${req.headers.host}`);const{ pathname }=url;if(pathname!=="/"){this.log(`Invalid pathname: "${pathname}"`);ws.close();return;}// Instantiate new clientthis.log(`Connecting with key "${this.apiKey.slice(0,3)}..."`);constclient=newRealtimeClient({apiKey: this.apiKey});client.addTool({name: "get_weather",description: "Retrieve weather information for a given location.",parameters: {type: "object",properties: {location: {type: "string",description: "Name of the location to retrieve weather for.",},},required: ["location"],},},async({ location }: {location: string})=>{console.log("get_weather tool called with location: ",location);},);client.updateSession({instructions: personalInstruction,input_audio_transcription: {model: "whisper-1"},turn_detection: {type: "server_vad"},tool_choice: "required",});// Relay: OpenAI Realtime API Event -> Browser Eventclient.realtime.on("server.*",(event: RealtimeEvent)=>{this.log(`Relaying "${event.type}" to Client`);ws.send(JSON.stringify(event));});client.realtime.on("close",()=>ws.close());// Relay: Browser Event -> OpenAI Realtime API EventconstmessageQueue: string[]=[];constmessageHandler=(data: string)=>{try{constevent=JSON.parse(data)as{type: string};this.log(`Relaying "${event.type}" to OpenAI`);if(!client.isConnected()){thrownewError("RealtimeClient is not connected");}client.realtime.send(event.type,event);}catch(e){consterror=einstanceofError ? e.message : "Unknown error";console.error(error);this.log(`Error parsing event from client: ${data}`);this.log(`Error processing message from client: ${error}`);}};ws.on("message",(data: string|Buffer)=>{constmessage=typeofdata==="string" ? data : data.toString();if(!client.isConnected()){messageQueue.push(message);}else{messageHandler(message);}});ws.on("close",()=>{this.log("WebSocket closed. Disconnecting client...");messageQueue.length=0;// Clear the message queuereturnclient.disconnect();});// Connect to OpenAI Realtime APItry{this.log(`Connecting to OpenAI...`);awaitclient.connect();}catch(e){consterror=einstanceofError ? e.message : "Unknown error";this.log(`Error connecting to OpenAI: ${error}`);ws.close();return;}this.log(`Connected to OpenAI successfully!`);while(messageQueue.length){constmessage=messageQueue.shift()!;if(client.isConnected()){messageHandler(message);}else{this.log("Client disconnected. Re-queuing message.");messageQueue.unshift(message);// Re-queue the messagebreak;// Exit the loop until reconnection}}}publicasynctestConnectionHandler(ws: WebSocket,req: {url?: string;headers: {host?: string}},): Promise<void>{awaitthis.connectionHandler(ws,req);}// eslint-disable-next-line class-methods-use-thisprivatelog(...args: unknown[]): void{console.log(`[RealtimeRelay]`, ...args);}}
Expected Behavior
When the get_weather tool is invoked, the handler defined in addTool should be triggered, and its logic (e.g., logging "get_weather tool called with location: ") should execute.
Observed Behavior
The tool appears to be registered, but its handler is never triggered when the tool is called.
Questions
Is this behavior expected?
Should addTool be supported in relay server environments, or is there a limitation in how tools are executed server-side?
Is there a specific configuration required to enable addTool in the relay server?
Thank you for looking into this! Let me know if additional details or test cases are needed.
The text was updated successfully, but these errors were encountered:
I previously reported an issue where tools registered using addTool in the server-side context (via the relay server's instance of RealtimeClient) were not triggering their handlers when invoked. I followed up with a patch as per the approach mentioned [here](#14 (comment)).
Steps Taken
Installed patch-package:
Command: npm i patch-package --save-dev.
Added @openai+realtime-api-beta+0.0.0.patch to the patches folder.
Updated package.json with the "postinstall": "patch-package" script.
Applied the patch:
This resolved the issue for tools registered via addTool when invoked from the client side.
Persisting Issue
When addTool is used on the server side, the tool's handler is not triggered.
However, if the tool description (not the function) is added client-side in the updateSession call, the server-side handler for the tool begins to work. Example:
client.updateSession({turn_detection: {type: 'server_vad'},tool_choice: 'auto',tools: [{type: 'function',name: 'get_weather',description: 'Retrieve current weather information for a given location.',parameters: {type: 'object',properties: {lat: {type: 'number',description: 'Latitude of the location.',},lng: {type: 'number',description: 'Longitude of the location.',},location: {type: 'string',description: 'Name of the location.',},},required: ['lat','lng','location'],},},],});
Adding only the description client-side appears to "activate" the tool's functionality server-side.
Next Steps
Could you provide clarification on the expected behavior for server-side tool registration using addTool? Additionally, any insights on resolving this issue without needing redundant client-side updates would be helpful.
Description
We are trying to use the
addTool
function in the relay server's instance ofRealtimeClient
, but it seems the tool handlers are never triggered when the tool is invoked. Instead, the tool logic appears to be bypassed entirely.Here's a minimal code example demonstrating the issue:
Code Example
Expected Behavior
When the
get_weather
tool is invoked, the handler defined inaddTool
should be triggered, and its logic (e.g., logging"get_weather tool called with location: "
) should execute.Observed Behavior
The tool appears to be registered, but its handler is never triggered when the tool is called.
Questions
addTool
be supported in relay server environments, or is there a limitation in how tools are executed server-side?addTool
in the relay server?Thank you for looking into this! Let me know if additional details or test cases are needed.
The text was updated successfully, but these errors were encountered: