@@ -4,7 +4,7 @@ import type {
44 OnDisconnectCallback ,
55 SessionConfig ,
66 FormatConfig ,
7- } from " ./utils/BaseConnection" ;
7+ } from ' ./utils/BaseConnection' ;
88import type {
99 AgentAudioEvent ,
1010 AgentResponseEvent ,
@@ -14,18 +14,19 @@ import type {
1414 InterruptionEvent ,
1515 UserTranscriptionEvent ,
1616 VadScoreEvent ,
17- } from "./utils/events" ;
18- import type { InputConfig } from "./utils/input" ;
17+ } from './utils/events' ;
18+ import type { InputConfig } from './utils/input' ;
19+ import { FeedbackScore } from './utils/events' ;
1920
20- export type Role = " user" | "ai" ;
21+ export type Role = ' user' | 'ai' ;
2122
22- export type Mode = " speaking" | " listening" ;
23+ export type Mode = ' speaking' | ' listening' ;
2324
2425export type Status =
25- | " connecting"
26- | " connected"
27- | " disconnecting"
28- | " disconnected" ;
26+ | ' connecting'
27+ | ' connected'
28+ | ' disconnecting'
29+ | ' disconnected' ;
2930
3031export type Options = SessionConfig &
3132 Callbacks &
@@ -42,7 +43,7 @@ export type ClientToolsConfig = {
4243 clientTools : Record <
4344 string ,
4445 (
45- parameters : any
46+ parameters : any ,
4647 ) => Promise < string | number | void > | string | number | void
4748 > ;
4849} ;
@@ -59,7 +60,7 @@ export type Callbacks = {
5960 onStatusChange ?: ( prop : { status : Status } ) => void ;
6061 onCanSendFeedbackChange ?: ( prop : { canSendFeedback : boolean } ) => void ;
6162 onUnhandledClientToolCall ?: (
62- params : ClientToolCallEvent [ " client_tool_call" ]
63+ params : ClientToolCallEvent [ ' client_tool_call' ] ,
6364 ) => void ;
6465 onVadScore ?: ( props : { vadScore : number } ) => void ;
6566} ;
@@ -68,8 +69,8 @@ const EMPTY_FREQUENCY_DATA = new Uint8Array(0);
6869
6970export class BaseConversation {
7071 protected lastInterruptTimestamp = 0 ;
71- protected mode : Mode = " listening" ;
72- protected status : Status = " connecting" ;
72+ protected mode : Mode = ' listening' ;
73+ protected status : Status = ' connecting' ;
7374 protected volume = 1 ;
7475 protected currentEventId = 1 ;
7576 protected lastFeedbackEventId = 0 ;
@@ -93,26 +94,26 @@ export class BaseConversation {
9394
9495 protected constructor (
9596 protected readonly options : Options ,
96- protected readonly connection : BaseConnection
97+ protected readonly connection : BaseConnection ,
9798 ) {
9899 if ( this . options . onConnect ) {
99100 this . options . onConnect ( { conversationId : connection . conversationId } ) ;
100101 }
101102 this . connection . onMessage ( this . onMessage ) ;
102103 this . connection . onDisconnect ( this . endSessionWithDetails ) ;
103104 this . connection . onModeChange ( mode => this . updateMode ( mode ) ) ;
104- this . updateStatus ( " connected" ) ;
105+ this . updateStatus ( ' connected' ) ;
105106 }
106107
107108 public endSession ( ) {
108- return this . endSessionWithDetails ( { reason : " user" } ) ;
109+ return this . endSessionWithDetails ( { reason : ' user' } ) ;
109110 }
110111
111112 private endSessionWithDetails = async ( details : DisconnectionDetails ) => {
112- if ( this . status !== " connected" && this . status !== " connecting" ) return ;
113- this . updateStatus ( " disconnecting" ) ;
113+ if ( this . status !== ' connected' && this . status !== ' connecting' ) return ;
114+ this . updateStatus ( ' disconnecting' ) ;
114115 await this . handleEndSession ( ) ;
115- this . updateStatus ( " disconnected" ) ;
116+ this . updateStatus ( ' disconnected' ) ;
116117 if ( this . options . onDisconnect ) {
117118 this . options . onDisconnect ( details ) ;
118119 }
@@ -159,7 +160,7 @@ export class BaseConversation {
159160 protected handleAgentResponse ( event : AgentResponseEvent ) {
160161 if ( this . options . onMessage ) {
161162 this . options . onMessage ( {
162- source : "ai" ,
163+ source : 'ai' ,
163164 message : event . agent_response_event . agent_response ,
164165 } ) ;
165166 }
@@ -168,18 +169,18 @@ export class BaseConversation {
168169 protected handleUserTranscript ( event : UserTranscriptionEvent ) {
169170 if ( this . options . onMessage ) {
170171 this . options . onMessage ( {
171- source : " user" ,
172+ source : ' user' ,
172173 message : event . user_transcription_event . user_transcript ,
173174 } ) ;
174175 }
175176 }
176177
177178 protected handleTentativeAgentResponse (
178- event : InternalTentativeAgentResponseEvent
179+ event : InternalTentativeAgentResponseEvent ,
179180 ) {
180181 if ( this . options . onDebug ) {
181182 this . options . onDebug ( {
182- type : " tentative_agent_response" ,
183+ type : ' tentative_agent_response' ,
183184 response :
184185 event . tentative_agent_response_internal_event
185186 . tentative_agent_response ,
@@ -199,21 +200,21 @@ export class BaseConversation {
199200 if (
200201 Object . prototype . hasOwnProperty . call (
201202 this . options . clientTools ,
202- event . client_tool_call . tool_name
203+ event . client_tool_call . tool_name ,
203204 )
204205 ) {
205206 try {
206207 const result =
207208 ( await this . options . clientTools [ event . client_tool_call . tool_name ] (
208- event . client_tool_call . parameters
209- ) ) ?? " Client tool execution successful." ; // default client-tool call response
209+ event . client_tool_call . parameters ,
210+ ) ) ?? ' Client tool execution successful.' ; // default client-tool call response
210211
211212 // The API expects result to be a string, so we need to convert it if it's not already a string
212213 const formattedResult =
213- typeof result === " object" ? JSON . stringify ( result ) : String ( result ) ;
214+ typeof result === ' object' ? JSON . stringify ( result ) : String ( result ) ;
214215
215216 this . connection . sendMessage ( {
216- type : " client_tool_result" ,
217+ type : ' client_tool_result' ,
217218 tool_call_id : event . client_tool_call . tool_call_id ,
218219 result : formattedResult ,
219220 is_error : false ,
@@ -223,10 +224,10 @@ export class BaseConversation {
223224 `Client tool execution failed with following error: ${ ( e as Error ) ?. message } ` ,
224225 {
225226 clientToolName : event . client_tool_call . tool_name ,
226- }
227+ } ,
227228 ) ;
228229 this . connection . sendMessage ( {
229- type : " client_tool_result" ,
230+ type : ' client_tool_result' ,
230231 tool_call_id : event . client_tool_call . tool_call_id ,
231232 result : `Client tool execution failed: ${ ( e as Error ) ?. message } ` ,
232233 is_error : true ,
@@ -243,10 +244,10 @@ export class BaseConversation {
243244 `Client tool with name ${ event . client_tool_call . tool_name } is not defined on client` ,
244245 {
245246 clientToolName : event . client_tool_call . tool_name ,
246- }
247+ } ,
247248 ) ;
248249 this . connection . sendMessage ( {
249- type : " client_tool_result" ,
250+ type : ' client_tool_result' ,
250251 tool_call_id : event . client_tool_call . tool_call_id ,
251252 result : `Client tool with name ${ event . client_tool_call . tool_name } is not defined on client` ,
252253 is_error : true ,
@@ -258,23 +259,23 @@ export class BaseConversation {
258259
259260 private onMessage = async ( parsedEvent : IncomingSocketEvent ) => {
260261 switch ( parsedEvent . type ) {
261- case " interruption" : {
262+ case ' interruption' : {
262263 this . handleInterruption ( parsedEvent ) ;
263264 return ;
264265 }
265- case " agent_response" : {
266+ case ' agent_response' : {
266267 this . handleAgentResponse ( parsedEvent ) ;
267268 return ;
268269 }
269- case " user_transcript" : {
270+ case ' user_transcript' : {
270271 this . handleUserTranscript ( parsedEvent ) ;
271272 return ;
272273 }
273- case " internal_tentative_agent_response" : {
274+ case ' internal_tentative_agent_response' : {
274275 this . handleTentativeAgentResponse ( parsedEvent ) ;
275276 return ;
276277 }
277- case " client_tool_call" : {
278+ case ' client_tool_call' : {
278279 try {
279280 await this . handleClientToolCall ( parsedEvent ) ;
280281 } catch ( error ) {
@@ -283,24 +284,24 @@ export class BaseConversation {
283284 {
284285 clientToolName : parsedEvent . client_tool_call . tool_name ,
285286 toolCallId : parsedEvent . client_tool_call . tool_call_id ,
286- }
287+ } ,
287288 ) ;
288289 }
289290 return ;
290291 }
291- case " audio" : {
292+ case ' audio' : {
292293 this . handleAudio ( parsedEvent ) ;
293294 return ;
294295 }
295296
296- case " vad_score" : {
297+ case ' vad_score' : {
297298 this . handleVadScore ( parsedEvent ) ;
298299 return ;
299300 }
300301
301- case " ping" : {
302+ case ' ping' : {
302303 this . connection . sendMessage ( {
303- type : " pong" ,
304+ type : ' pong' ,
304305 event_id : parsedEvent . ping_event . event_id ,
305306 } ) ;
306307 // parsedEvent.ping_event.ping_ms can be used on client side, for example
@@ -330,7 +331,7 @@ export class BaseConversation {
330331 }
331332
332333 public isOpen ( ) {
333- return this . status === " connected" ;
334+ return this . status === ' connected' ;
334335 }
335336
336337 public setVolume = ( { volume } : { volume : number } ) => {
@@ -360,16 +361,16 @@ export class BaseConversation {
360361 public sendFeedback ( like : boolean ) {
361362 if ( ! this . canSendFeedback ) {
362363 console . warn (
363- this . lastFeedbackEventId === 0
364- ? " Cannot send feedback: the conversation has not started yet."
365- : " Cannot send feedback: feedback has already been sent for the current response."
364+ this . lastFeedbackEventId === this . currentEventId
365+ ? ' Cannot send feedback: feedback has already been sent for the current response.'
366+ : ' Cannot send feedback: no response has been received yet.' ,
366367 ) ;
367368 return ;
368369 }
369370
370371 this . connection . sendMessage ( {
371- type : " feedback" ,
372- score : like ? "like" : "dislike" ,
372+ type : ' feedback' ,
373+ score : like ? FeedbackScore . LIKE : FeedbackScore . DISLIKE ,
373374 event_id : this . currentEventId ,
374375 } ) ;
375376 this . lastFeedbackEventId = this . currentEventId ;
@@ -378,27 +379,27 @@ export class BaseConversation {
378379
379380 public sendContextualUpdate ( text : string ) {
380381 this . connection . sendMessage ( {
381- type : " contextual_update" ,
382+ type : ' contextual_update' ,
382383 text,
383384 } ) ;
384385 }
385386
386387 public sendUserMessage ( text : string ) {
387388 this . connection . sendMessage ( {
388- type : " user_message" ,
389+ type : ' user_message' ,
389390 text,
390391 } ) ;
391392 }
392393
393394 public sendUserActivity ( ) {
394395 this . connection . sendMessage ( {
395- type : " user_activity" ,
396+ type : ' user_activity' ,
396397 } ) ;
397398 }
398399
399400 public sendMCPToolApprovalResult ( toolCallId : string , isApproved : boolean ) {
400401 this . connection . sendMessage ( {
401- type : " mcp_tool_approval_result" ,
402+ type : ' mcp_tool_approval_result' ,
402403 tool_call_id : toolCallId ,
403404 is_approved : isApproved ,
404405 } ) ;
0 commit comments