@babelbeez/sdk 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/babelbeez-sdk.js +6 -6
- package/dist/babelbeez-sdk.umd.cjs +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@babelbeez/sdk` are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.3.2] - 2026-01-30
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Improved `buttonState` behavior when the user ends a call while the assistant is speaking, so the UI no longer gets stuck in an active/talking state and remains consistent through the configured goodbye message.
|
|
9
|
+
|
|
5
10
|
## [0.3.1] - 2026-01-14
|
|
6
11
|
|
|
7
12
|
### Changed
|
package/dist/babelbeez-sdk.js
CHANGED
|
@@ -12237,7 +12237,7 @@ class wf extends hf {
|
|
|
12237
12237
|
throw new Error("BabelbeezClient: publicChatbotId is required.");
|
|
12238
12238
|
this.publicChatbotId = e.publicChatbotId;
|
|
12239
12239
|
const t = e.proxyInitializeUrl || _f;
|
|
12240
|
-
this.proxyInitializeUrl = t, this.apiBaseUrl = e.apiBaseUrl || new URL(t).origin, this.agent = null, this.session = null, this.currentSystemSettings = null, this.currentChatbotSettings = null, this.currentSessionId = null, this.currentRagSearchUrl = null, this.sessionStartTime = null, this.accumulatedUsage = null, this.hasEndConversationBeenHandled = !1, this.isTerminating = !1, this.isUserSpeaking = !1, this.isAssistantSpeaking = !1, this.isHandoffFormOpen = !1, this.inactivityStage = 0, this.inactivityStage1TimeoutId = null, this.inactivityStage2TimeoutId = null, this.shouldScheduleStage2OnNextAssistantSilence = !1, this.pendingGoodbyeResolve = null, this.handoffPromiseResolve = null, this.currentHandoffSummaryText = null, this.heartbeatIntervalId = null, this.heartbeatFrequencySeconds = null, this._lastInitData = null, this._lastAssistantMessageId = null, this._lastAssistantTranscript = "", this._currentAssistantTranscript = "", this._currentUserTranscript = "";
|
|
12240
|
+
this.proxyInitializeUrl = t, this.apiBaseUrl = e.apiBaseUrl || new URL(t).origin, this.agent = null, this.session = null, this.currentSystemSettings = null, this.currentChatbotSettings = null, this.currentSessionId = null, this.currentRagSearchUrl = null, this.sessionStartTime = null, this.accumulatedUsage = null, this.hasEndConversationBeenHandled = !1, this.isTerminating = !1, this.isGoodbyeInProgress = !1, this.isUserSpeaking = !1, this.isAssistantSpeaking = !1, this.isHandoffFormOpen = !1, this.inactivityStage = 0, this.inactivityStage1TimeoutId = null, this.inactivityStage2TimeoutId = null, this.shouldScheduleStage2OnNextAssistantSilence = !1, this.pendingGoodbyeResolve = null, this.handoffPromiseResolve = null, this.currentHandoffSummaryText = null, this.heartbeatIntervalId = null, this.heartbeatFrequencySeconds = null, this._lastInitData = null, this._lastAssistantMessageId = null, this._lastAssistantTranscript = "", this._currentAssistantTranscript = "", this._currentUserTranscript = "";
|
|
12241
12241
|
}
|
|
12242
12242
|
// --- Public API ---
|
|
12243
12243
|
/**
|
|
@@ -12572,18 +12572,18 @@ class wf extends hf {
|
|
|
12572
12572
|
$("INFO", "No goodbyeInstructions configured or no active session; finalizing immediately."), await this._finalizeSession(e);
|
|
12573
12573
|
return;
|
|
12574
12574
|
}
|
|
12575
|
-
$("INFO", "Playing goodbye message before finalizing session.");
|
|
12575
|
+
this.isGoodbyeInProgress = !0, $("INFO", "Playing goodbye message before finalizing session.");
|
|
12576
12576
|
const s = new Promise((u) => {
|
|
12577
12577
|
this.pendingGoodbyeResolve = u;
|
|
12578
12578
|
});
|
|
12579
12579
|
try {
|
|
12580
12580
|
this._setSessionMuted(!0, "goodbye"), await this.session.sendMessage(t);
|
|
12581
12581
|
} catch (u) {
|
|
12582
|
-
$("WARN", "Failed to send goodbye message; finalizing immediately.", u), this.pendingGoodbyeResolve = null, this._setSessionMuted(!1, "goodbye"), await this._finalizeSession(e);
|
|
12582
|
+
$("WARN", "Failed to send goodbye message; finalizing immediately.", u), this.pendingGoodbyeResolve = null, this._setSessionMuted(!1, "goodbye"), this.isGoodbyeInProgress = !1, await this._finalizeSession(e);
|
|
12583
12583
|
return;
|
|
12584
12584
|
}
|
|
12585
12585
|
const r = 15e3, i = new Promise((u) => setTimeout(u, r));
|
|
12586
|
-
await Promise.race([s, i]), this.pendingGoodbyeResolve = null, this._setSessionMuted(!1, "goodbye"), await this._finalizeSession(e);
|
|
12586
|
+
await Promise.race([s, i]), this.pendingGoodbyeResolve = null, this._setSessionMuted(!1, "goodbye"), this.isGoodbyeInProgress = !1, await this._finalizeSession(e);
|
|
12587
12587
|
}
|
|
12588
12588
|
_createVoiceAgent() {
|
|
12589
12589
|
var u, l, p, d;
|
|
@@ -12756,7 +12756,7 @@ ${((l = this.currentChatbotSettings) == null ? void 0 : l.instructions) || ""}`.
|
|
|
12756
12756
|
return;
|
|
12757
12757
|
}
|
|
12758
12758
|
if (e.type === "output_audio_buffer.started") {
|
|
12759
|
-
this.isAssistantSpeaking = !0, this._clearInactivityTimers(), this._currentAssistantTranscript = "", this.emit("buttonState", "speaking");
|
|
12759
|
+
this.isAssistantSpeaking = !0, this._clearInactivityTimers(), this._currentAssistantTranscript = "", this.isTerminating || this.emit("buttonState", "speaking");
|
|
12760
12760
|
return;
|
|
12761
12761
|
}
|
|
12762
12762
|
if (e.type === "output_audio_buffer.stopped" || e.type === "output_audio_buffer.cleared") {
|
|
@@ -12766,7 +12766,7 @@ ${((l = this.currentChatbotSettings) == null ? void 0 : l.instructions) || ""}`.
|
|
|
12766
12766
|
role: "agent",
|
|
12767
12767
|
text: r,
|
|
12768
12768
|
isFinal: !0
|
|
12769
|
-
}), this._lastAssistantTranscript = "", this._currentAssistantTranscript = "", this.emit("buttonState", "active"), this.pendingGoodbyeResolve && (this.pendingGoodbyeResolve(), this.pendingGoodbyeResolve = null), !this.isTerminating && this.currentChatbotSettings && !this.isHandoffFormOpen) {
|
|
12769
|
+
}), this._lastAssistantTranscript = "", this._currentAssistantTranscript = "", !this.isGoodbyeInProgress && !this.isTerminating && this.emit("buttonState", "active"), this.pendingGoodbyeResolve && (this.pendingGoodbyeResolve(), this.pendingGoodbyeResolve = null), !this.isTerminating && this.currentChatbotSettings && !this.isHandoffFormOpen) {
|
|
12770
12770
|
const i = ((s = this.currentChatbotSettings) == null ? void 0 : s.inactivityTimeoutMs) || 0;
|
|
12771
12771
|
if (this.inactivityStage === 0 && i > 0) {
|
|
12772
12772
|
this._clearInactivityTimers();
|
|
@@ -9,7 +9,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
9
9
|
Failed Guardrail Reason: ${n.guardrail.policyHint}.
|
|
10
10
|
Failure Details: ${JSON.stringify(n.output.outputInfo??{})}.
|
|
11
11
|
Please respond again following policy. Apologize for not being able to answer the question (while avoiding the specific reason) and divert discussion back to an approved topic immediately and not invite more discussion.
|
|
12
|
-
`.trim()}function Et(n,e){return n in e&&typeof e[n]<"u"}function ep(n){return Et("modalities",n)||Et("inputAudioFormat",n)||Et("outputAudioFormat",n)||Et("inputAudioTranscription",n)||Et("turnDetection",n)||Et("inputAudioNoiseReduction",n)||Et("speed",n)}function tp(n){var e,t,s,r,i,o,a,u;if(!ep(n)){const l=(e=n.audio)!=null&&e.input?{format:Ds(n.audio.input.format),noiseReduction:n.audio.input.noiseReduction??null,transcription:n.audio.input.transcription,turnDetection:n.audio.input.turnDetection}:void 0,p=((s=(t=n.audio)==null?void 0:t.output)==null?void 0:s.voice)??n.voice,d=(r=n.audio)!=null&&r.output||typeof p<"u"?{format:Ds((o=(i=n.audio)==null?void 0:i.output)==null?void 0:o.format),voice:p,speed:(u=(a=n.audio)==null?void 0:a.output)==null?void 0:u.speed}:void 0;return{model:n.model,instructions:n.instructions,toolChoice:n.toolChoice,tools:n.tools,tracing:n.tracing,providerData:n.providerData,prompt:n.prompt,outputModalities:n.outputModalities,audio:l||d?{input:l,output:d}:void 0}}return{model:n.model,instructions:n.instructions,toolChoice:n.toolChoice,tools:n.tools,tracing:n.tracing,providerData:n.providerData,prompt:n.prompt,outputModalities:n.modalities,audio:{input:{format:Ds(n.inputAudioFormat),noiseReduction:n.inputAudioNoiseReduction??null,transcription:n.inputAudioTranscription,turnDetection:n.turnDetection},output:{format:Ds(n.outputAudioFormat),voice:n.voice,speed:n.speed}}}}function Ds(n){if(!n)return;if(typeof n=="object")return n;const e=String(n);return e==="pcm16"?{type:"audio/pcm",rate:24e3}:e==="g711_ulaw"?{type:"audio/pcmu"}:e==="g711_alaw"?{type:"audio/pcma"}:{type:"audio/pcm",rate:24e3}}w({itemId:f()});const so=ve("role",[w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("system"),content:J(w({type:I("input_text"),text:f()}))}),w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("user"),status:pe(["in_progress","completed"]),content:J(w({type:I("input_text"),text:f()}).or(w({type:I("input_audio"),audio:f().nullable().optional(),transcript:f().nullable()})))}),w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("assistant"),status:pe(["in_progress","completed","incomplete"]),content:J(w({type:I("output_text"),text:f()}).or(w({type:I("output_audio"),audio:f().nullable().optional(),transcript:f().nullable().optional()})))})]),ro=w({itemId:f(),previousItemId:f().nullable().optional(),type:I("function_call"),status:pe(["in_progress","completed","incomplete"]),arguments:f(),name:f(),output:f().nullable()}),io=w({itemId:f(),previousItemId:f().nullable().optional(),type:pe(["mcp_call","mcp_tool_call"]),status:pe(["in_progress","completed","incomplete"]),arguments:f(),name:f(),output:f().nullable()}),np=w({itemId:f(),type:I("mcp_approval_request"),serverLabel:f(),name:f(),arguments:se(f(),H()),approved:St().optional().nullable()}),Ne=Fi("openai-agents:realtime"),ao=w({id:f().optional().nullable(),conversation_id:f().optional().nullable(),max_output_tokens:E().or(I("inf")).optional().nullable(),metadata:se(f(),H()).optional().nullable(),output_modalities:J(f()).optional().nullable(),object:I("realtime.response").optional().nullable(),output:J(H()).optional().nullable(),audio:w({output:w({format:H().optional().nullable(),voice:f().optional().nullable()}).optional().nullable()}).optional().nullable(),status:pe(["completed","incomplete","failed","cancelled","in_progress"]).optional().nullable(),status_details:se(f(),H()).optional().nullable(),usage:w({input_tokens:E().optional(),input_token_details:se(f(),H()).optional().nullable(),output_tokens:E().optional(),output_token_details:se(f(),H()).optional().nullable()}).optional().nullable()}),sp=w({id:f().optional(),audio:f().nullable().optional(),text:f().nullable().optional(),transcript:f().nullable().optional(),type:Ye([I("input_text"),I("input_audio"),I("item_reference"),I("output_text"),I("output_audio")])}),Qt=w({id:f().optional(),arguments:f().optional(),call_id:f().optional(),content:J(sp).optional(),name:f().optional(),output:f().nullable().optional(),role:pe(["user","assistant","system"]).optional(),status:pe(["completed","incomplete","in_progress"]).optional(),type:pe(["message","function_call","function_call_output","mcp_list_tools","mcp_tool_call","mcp_call","mcp_approval_request","mcp_approval_response"]).optional(),approval_request_id:f().nullable().optional(),approve:St().nullable().optional(),reason:f().nullable().optional(),server_label:f().optional(),error:H().nullable().optional(),tools:J(w({name:f(),description:f(),input_schema:se(H()).optional()}).passthrough()).optional()}).passthrough(),rp=w({type:I("conversation.created"),event_id:f(),conversation:w({id:f().optional(),object:I("realtime.conversation").optional()})}),ip=w({type:I("conversation.item.added"),event_id:f(),item:Qt,previous_item_id:f().nullable().optional()}),ap=w({type:I("conversation.item.done"),event_id:f(),item:Qt,previous_item_id:f().nullable().optional()}),op=w({type:I("conversation.item.deleted"),event_id:f(),item_id:f()}),up=w({type:I("conversation.item.input_audio_transcription.completed"),event_id:f(),item_id:f(),content_index:E(),transcript:f(),logprobs:J(H()).nullable().optional(),usage:w({type:I("tokens"),total_tokens:E(),input_tokens:E(),input_token_details:w({text_tokens:E(),audio_tokens:E()}),output_tokens:E()}).optional()}),cp=w({type:I("conversation.item.input_audio_transcription.delta"),event_id:f(),item_id:f(),content_index:E().optional(),delta:f().optional(),logprobs:J(H()).nullable().optional()}),lp=w({type:I("conversation.item.input_audio_transcription.failed"),event_id:f(),item_id:f(),content_index:E(),error:w({code:f().optional(),message:f().optional(),param:f().optional(),type:f().optional()})}),dp=w({type:I("conversation.item.retrieved"),event_id:f(),item:Qt}),pp=w({type:I("conversation.item.truncated"),event_id:f(),item_id:f(),audio_end_ms:E(),content_index:E()}),fp=w({type:I("conversation.item.create"),item:Qt,event_id:f().optional(),previous_item_id:f().nullable().optional()}),hp=w({type:I("conversation.item.delete"),item_id:f(),event_id:f().optional()}),mp=w({type:I("conversation.item.retrieve"),item_id:f(),event_id:f().optional()}),gp=w({type:I("conversation.item.truncate"),item_id:f(),audio_end_ms:E(),content_index:E(),event_id:f().optional()}),yp=w({type:I("error"),event_id:f().optional(),error:H().optional()}),_p=w({type:I("input_audio_buffer.cleared"),event_id:f()}),vp=w({type:I("input_audio_buffer.append"),audio:f(),event_id:f().optional()}),bp=w({type:I("input_audio_buffer.clear"),event_id:f().optional()}),wp=w({type:I("input_audio_buffer.commit"),event_id:f().optional()}),Ip=w({type:I("input_audio_buffer.committed"),event_id:f(),item_id:f(),previous_item_id:f().nullable().optional()}),Sp=w({type:I("input_audio_buffer.speech_started"),event_id:f(),item_id:f(),audio_start_ms:E()}),Tp=w({type:I("input_audio_buffer.speech_stopped"),event_id:f(),item_id:f(),audio_end_ms:E()}),xp=w({type:I("output_audio_buffer.started"),event_id:f()}).passthrough(),kp=w({type:I("output_audio_buffer.stopped"),event_id:f()}).passthrough(),Ap=w({type:I("output_audio_buffer.cleared"),event_id:f()}),Cp=w({type:I("rate_limits.updated"),event_id:f(),rate_limits:J(w({limit:E().optional(),name:pe(["requests","tokens"]).optional(),remaining:E().optional(),reset_seconds:E().optional()}))}),Op=w({type:I("response.output_audio.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),Ep=w({type:I("response.output_audio.done"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f()}),Rp=w({type:I("response.output_audio_transcript.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),Np=w({type:I("response.output_audio_transcript.done"),event_id:f(),item_id:f(),content_index:E(),transcript:f(),output_index:E(),response_id:f()}),Pp=w({type:I("response.content_part.added"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f(),part:w({audio:f().optional(),text:f().optional(),transcript:f().optional(),type:pe(["text","audio"]).optional()})}),Dp=w({type:I("response.content_part.done"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f(),part:w({audio:f().optional(),text:f().optional(),transcript:f().optional(),type:pe(["text","audio"]).optional()})}),Mp=w({type:I("response.created"),event_id:f(),response:ao}),oo=w({type:I("response.done"),event_id:f(),response:ao}),Fp=w({type:I("response.function_call_arguments.delta"),event_id:f(),item_id:f(),call_id:f(),delta:f(),output_index:E(),response_id:f()}),$p=w({type:I("response.function_call_arguments.done"),event_id:f(),item_id:f(),call_id:f(),arguments:f(),output_index:E(),response_id:f()}),jp=w({type:I("response.output_item.added"),event_id:f(),item:Qt,output_index:E(),response_id:f()}),Up=w({type:I("response.output_item.done"),event_id:f(),item:Qt,output_index:E(),response_id:f()}),Lp=w({type:I("response.output_text.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),zp=w({type:I("response.output_text.done"),event_id:f(),item_id:f(),content_index:E(),text:f(),output_index:E(),response_id:f()}),Bp=w({type:I("session.created"),event_id:f(),session:H()}),Zp=w({type:I("session.updated"),event_id:f(),session:H()}),qp=w({type:I("response.cancel"),event_id:f().optional(),response_id:f().optional()}),Jp=w({type:I("response.create"),event_id:f().optional(),response:H().optional()}),Gp=w({type:I("session.update"),event_id:f().optional(),session:H()}),Vp=w({type:I("mcp_list_tools.in_progress"),event_id:f().optional(),item_id:f().optional()}),Hp=w({type:I("mcp_list_tools.completed"),event_id:f().optional(),item_id:f().optional()}),Wp=w({type:I("response.mcp_call_arguments.delta"),event_id:f(),response_id:f(),item_id:f(),output_index:E(),delta:f(),obfuscation:f()}),Kp=w({type:I("response.mcp_call_arguments.done"),event_id:f(),response_id:f(),item_id:f(),output_index:E(),arguments:f()}),Yp=w({type:I("response.mcp_call.in_progress"),event_id:f(),output_index:E(),item_id:f()}),Xp=w({type:I("response.mcp_call.completed"),event_id:f(),output_index:E(),item_id:f()}),Qp=w({type:I("mcp_list_tools.failed"),event_id:f().optional(),item_id:f().optional()}),ef=w({type:f(),event_id:f().optional().nullable()}).passthrough(),tf=ve("type",[rp,ip,ap,op,up,cp,lp,dp,pp,yp,_p,Ip,Sp,Tp,xp,kp,Ap,Cp,Op,Ep,Rp,Np,Pp,Dp,Mp,oo,Fp,$p,jp,Up,Lp,zp,Bp,Zp,Vp,Hp,Qp,Wp,Kp,Yp,Xp]);ve("type",[fp,hp,mp,gp,vp,bp,wp,qp,Jp,Gp]);function Er(n){const e=JSON.parse(n.data.toString()),t=tf.safeParse(e);if(!t.success){const s=ef.safeParse(e);return s.success?{data:s.data,isGeneric:!0}:{data:null,isGeneric:!0}}return{data:t.data,isGeneric:!1}}const nf="gpt-realtime",Je={outputModalities:["audio"],audio:{input:{format:{type:"audio/pcm",rate:24e3},transcription:{model:"gpt-4o-mini-transcribe"},turnDetection:{type:"semantic_vad"},noiseReduction:null},output:{format:{type:"audio/pcm",rate:24e3},speed:1}}},Dr=class Dr extends or{constructor(t={}){super();R(this,$t);R(this,Bn);R(this,xe,null);R(this,Zn,null);S(this,"eventEmitter",new ws);k(this,$t,t.model??nf),k(this,Bn,t.apiKey)}get currentModel(){return c(this,$t)}set currentModel(t){k(this,$t,t)}_afterAudioDoneEvent(){}get _rawSessionConfig(){return c(this,Zn)??null}async _getApiKey(t){const s=t.apiKey??c(this,Bn);return typeof s=="function"?await s():s}_onMessage(t){var i,o,a,u,l,p;const{data:s,isGeneric:r}=Er(t);if(s!==null&&(this.emit("*",s),!r)){if(s.type==="error"?this.emit("error",{type:"error",error:s}):this.emit(s.type,s),s.type==="response.created"){this.emit("turn_started",{type:"response_started",providerData:{...s}});return}if(s.type==="session.updated"&&k(this,Zn,s.session),s.type==="response.done"){const d=oo.safeParse(s);if(!d.success){Ne.error("Error parsing response done event",d.error);return}const m=((i=d.data.response.usage)==null?void 0:i.input_tokens)??0,g=((o=d.data.response.usage)==null?void 0:o.output_tokens)??0,_=m+g,T=new kn({inputTokens:m,inputTokensDetails:((a=d.data.response.usage)==null?void 0:a.input_token_details)??{},outputTokens:g,outputTokensDetails:((u=d.data.response.usage)==null?void 0:u.output_token_details)??{},totalTokens:_});this.emit("usage_update",T),this.emit("turn_done",{type:"response_done",response:{id:d.data.response.id??"",output:d.data.response.output??[],usage:{inputTokens:m,inputTokensDetails:((l=d.data.response.usage)==null?void 0:l.input_token_details)??{},outputTokens:g,outputTokensDetails:((p=d.data.response.usage)==null?void 0:p.output_token_details)??{},totalTokens:_}}});return}if(s.type==="response.output_audio.done"){this.emit("audio_done"),this._afterAudioDoneEvent();return}if(s.type==="conversation.item.deleted"){this.emit("item_deleted",{itemId:s.item_id});return}if(s.type==="conversation.item.input_audio_transcription.completed"||s.type==="conversation.item.truncated"){this.sendEvent({type:"conversation.item.retrieve",item_id:s.item_id});return}if(s.type==="conversation.item.input_audio_transcription.delta"||s.type==="response.output_text.delta"||s.type==="response.output_audio_transcript.delta"||s.type==="response.function_call_arguments.delta"){s.type==="response.output_audio_transcript.delta"&&this.emit("audio_transcript_delta",{type:"transcript_delta",delta:s.delta,itemId:s.item_id,responseId:s.response_id});return}if(s.type==="conversation.item.added"||s.type==="conversation.item.done"||s.type==="conversation.item.retrieved"){if(s.item.type==="mcp_list_tools"&&s.type==="conversation.item.done"){const d=s.item.server_label??"",m=s.item.tools??[];try{this.emit("mcp_tools_listed",{serverLabel:d,tools:m})}catch(g){Ne.error("Error emitting mcp_tools_listed",g,s.item)}return}if(s.item.type==="message"){const d=s.type==="conversation.item.added"||s.type==="conversation.item.done"?s.previous_item_id:null,m=so.parse({itemId:s.item.id,previousItemId:d,type:s.item.type,role:s.item.role,content:s.item.content,status:s.item.status});this.emit("item_update",m);return}if(s.item.type==="mcp_approval_request"&&s.type==="conversation.item.done"){const d=s.item,m=np.parse({itemId:d.id,type:d.type,serverLabel:d.server_label,name:d.name,arguments:JSON.parse(d.arguments||"{}"),approved:d.approved});this.emit("item_update",m),this.emit("mcp_approval_request",m);return}if(s.item.type==="mcp_tool_call"||s.item.type==="mcp_call"){const d=s.type==="conversation.item.done"?"completed":"in_progress",m=io.parse({itemId:s.item.id,type:s.item.type,status:d,arguments:s.item.arguments,name:s.item.name,output:s.item.output});this.emit("item_update",m),s.type==="conversation.item.done"&&this.emit("mcp_tool_call_completed",m);return}}if(s.type==="response.mcp_call.in_progress"){const d=s;this.sendEvent({type:"conversation.item.retrieve",item_id:d.item_id});return}if(s.type==="mcp_list_tools.in_progress"){const d=s;d.item_id&&this.sendEvent({type:"conversation.item.retrieve",item_id:d.item_id});return}if(s.type==="response.output_item.done"||s.type==="response.output_item.added"){const d=s.item;if(d.type==="function_call"&&d.status==="completed"){const m=ro.parse({itemId:d.id,type:d.type,status:"in_progress",arguments:d.arguments,name:d.name,output:null});this.emit("item_update",m),this.emit("function_call",{id:d.id,type:"function_call",callId:d.call_id??"",arguments:d.arguments??"",name:d.name??""});return}if(d.type==="mcp_tool_call"||d.type==="mcp_call"){const m=io.parse({itemId:d.id,type:d.type,status:s.type==="response.output_item.done"?"completed":"in_progress",arguments:d.arguments,name:d.name,output:d.output});this.emit("item_update",m);return}if(d.type==="message"){const m=so.parse({itemId:s.item.id,type:s.item.type,role:s.item.role,content:s.item.content,status:s.type==="response.output_item.done"?d.status??"completed":d.status??"in_progress"});this.emit("item_update",m);return}}}}_onError(t){this.emit("error",{type:"error",error:t})}_onOpen(){this.emit("connected")}_onClose(){this.emit("disconnected")}sendMessage(t,s,{triggerResponse:r=!0}={}){const i=typeof t=="string"?[{type:"input_text",text:t}]:t.content.map(o=>o.type==="input_image"?{type:"input_image",image_url:o.image,...o.providerData??{}}:o);this.sendEvent({type:"conversation.item.create",item:{type:"message",role:"user",content:i},...s}),r&&this.sendEvent({type:"response.create"})}addImage(t,{triggerResponse:s=!0}={}){this.sendMessage({type:"message",role:"user",content:[{type:"input_image",image:t}]},{},{triggerResponse:s})}_getMergedSessionConfig(t){var i,o,a,u,l,p,d,m,g,_,T,y,h,v,b,N,x,A,D,U,G,L,fe,Y,ce,Me,Ve,Qn;const s=tp(t),r={type:"realtime",instructions:s.instructions,model:s.model??c(this,$t),output_modalities:s.outputModalities??Je.outputModalities,audio:{input:{format:((o=(i=s.audio)==null?void 0:i.input)==null?void 0:o.format)??((u=(a=Je.audio)==null?void 0:a.input)==null?void 0:u.format),noise_reduction:((p=(l=s.audio)==null?void 0:l.input)==null?void 0:p.noiseReduction)??((m=(d=Je.audio)==null?void 0:d.input)==null?void 0:m.noiseReduction),transcription:((_=(g=s.audio)==null?void 0:g.input)==null?void 0:_.transcription)??((y=(T=Je.audio)==null?void 0:T.input)==null?void 0:y.transcription),turn_detection:Dr.buildTurnDetectionConfig((v=(h=s.audio)==null?void 0:h.input)==null?void 0:v.turnDetection)??((N=(b=Je.audio)==null?void 0:b.input)==null?void 0:N.turnDetection)},output:{format:((A=(x=s.audio)==null?void 0:x.output)==null?void 0:A.format)??((U=(D=Je.audio)==null?void 0:D.output)==null?void 0:U.format),voice:((L=(G=s.audio)==null?void 0:G.output)==null?void 0:L.voice)??((Y=(fe=Je.audio)==null?void 0:fe.output)==null?void 0:Y.voice),speed:((Me=(ce=s.audio)==null?void 0:ce.output)==null?void 0:Me.speed)??((Qn=(Ve=Je.audio)==null?void 0:Ve.output)==null?void 0:Qn.speed)}},tool_choice:s.toolChoice??Je.toolChoice,...s.providerData??{}};return s.prompt&&(r.prompt={id:s.prompt.promptId,version:s.prompt.version,variables:s.prompt.variables}),s.tools&&s.tools.length>0&&(r.tools=s.tools.map($s=>({...$s,strict:void 0}))),r}buildSessionPayload(t){return this._getMergedSessionConfig(t)}static buildTurnDetectionConfig(t){if(typeof t>"u")return;const{type:s,createResponse:r,create_response:i,eagerness:o,interruptResponse:a,interrupt_response:u,prefixPaddingMs:l,prefix_padding_ms:p,silenceDurationMs:d,silence_duration_ms:m,threshold:g,idleTimeoutMs:_,idle_timeout_ms:T,...y}=t,h={type:s,create_response:r||i,eagerness:o,interrupt_response:a||u,prefix_padding_ms:l||p,silence_duration_ms:d||m,idle_timeout_ms:_||T,threshold:g,...y};return Object.keys(h).forEach(v=>{h[v]===void 0&&delete h[v]}),Object.keys(h).length>0?h:void 0}set _tracingConfig(t){k(this,xe,t)}_updateTracingConfig(t){var s,r,i;if(typeof c(this,xe)>"u"&&k(this,xe,null),t==="auto"){this.sendEvent({type:"session.update",session:{type:"realtime",tracing:"auto"}});return}if(c(this,xe)!==null&&typeof c(this,xe)!="string"&&typeof t!="string"){Ne.warn("Tracing config is already set, skipping setting it again. This likely happens when you already set a tracing config on session creation.");return}if(t===null){Ne.debug("Disabling tracing for this session. It cannot be turned on for this session from this point on."),this.sendEvent({type:"session.update",session:{type:"realtime",tracing:null}});return}if(c(this,xe)===null||typeof c(this,xe)=="string"){this.sendEvent({type:"session.update",session:{type:"realtime",tracing:t}});return}if((t==null?void 0:t.group_id)!==((s=c(this,xe))==null?void 0:s.group_id)||(t==null?void 0:t.metadata)!==((r=c(this,xe))==null?void 0:r.metadata)||(t==null?void 0:t.workflow_name)!==((i=c(this,xe))==null?void 0:i.workflow_name)){Ne.warn("Mismatch in tracing config. Ignoring the new tracing config. This likely happens when you already set a tracing config on session creation. Current tracing config: %s, new tracing config: %s",JSON.stringify(c(this,xe)),JSON.stringify(t));return}this.sendEvent({type:"session.update",session:{type:"realtime",tracing:t}})}updateSessionConfig(t){const s=this.buildSessionPayload(t);this.sendEvent({type:"session.update",session:s})}sendFunctionCallOutput(t,s,r=!0){this.sendEvent({type:"conversation.item.create",item:{type:"function_call_output",output:s,call_id:t.callId}});try{const i=ro.parse({itemId:t.id,previousItemId:t.previousItemId,type:"function_call",status:"completed",arguments:t.arguments,name:t.name,output:s});this.emit("item_update",i)}catch(i){Ne.error("Error parsing tool call item",i,t)}r&&this.sendEvent({type:"response.create"})}sendAudio(t,{commit:s=!1}={}){this.sendEvent({type:"input_audio_buffer.append",audio:Zd(t)}),s&&this.sendEvent({type:"input_audio_buffer.commit"})}resetHistory(t,s){const{removals:r,additions:i,updates:o}=Jd(t,s),a=new Set(r.map(l=>l.itemId));for(const l of o)a.add(l.itemId);if(a.size>0)for(const l of a)this.sendEvent({type:"conversation.item.delete",item_id:l});const u=[...i,...o];for(const l of u)if(l.type==="message"){const p={type:"message",role:l.role,content:l.content,id:l.itemId};l.role!=="system"&&l.status&&(p.status=l.status),this.sendEvent({type:"conversation.item.create",item:p})}else l.type==="function_call"&&Ne.warn("Function calls cannot be manually added or updated at the moment. Ignoring.")}sendMcpResponse(t,s){this.sendEvent({type:"conversation.item.create",previous_item_id:t.itemId,item:{type:"mcp_approval_response",approval_request_id:t.itemId,approve:s}})}};$t=new WeakMap,Bn=new WeakMap,xe=new WeakMap,Zn=new WeakMap;let Ms=Dr;class sf extends Ms{constructor(t={}){if(typeof RTCPeerConnection>"u")throw new Error("WebRTC is not supported in this environment");super(t);S(this,"options");R(this,qn);R(this,ie,{status:"disconnected",peerConnection:void 0,dataChannel:void 0,callId:void 0});R(this,Jn);R(this,yt,!1);R(this,Gn,!1);this.options=t,k(this,qn,t.baseUrl??"https://api.openai.com/v1/realtime/calls"),k(this,Jn,t.useInsecureApiKey??!1)}get callId(){return c(this,ie).callId}get status(){return c(this,ie).status}get connectionState(){return c(this,ie)}get muted(){return c(this,Gn)}async connect(t){if(c(this,ie).status==="connected")return;c(this,ie).status==="connecting"&&Ne.warn("Realtime connection already in progress. Please await original promise");const s=t.model??this.currentModel;this.currentModel=s;const r=t.url??c(this,qn),i=await this._getApiKey(t),o=typeof i=="string"&&i.startsWith("ek_");if(!c(this,Jn)&&!o)throw new re("Using the WebRTC connection in a browser environment requires an ephemeral client key. If you need to use a regular API key, use the WebSocket transport or set the `useInsecureApiKey` option to true.");return new Promise(async(a,u)=>{var l,p;try{const d={...t.initialSessionConfig||{},model:this.currentModel},m=new URL(r);let g=new RTCPeerConnection;const _=g.createDataChannel("oai-events");let T;const y=A=>{A.onconnectionstatechange=()=>{switch(A.connectionState){case"disconnected":case"failed":case"closed":this.close();break}}};y(g),k(this,ie,{status:"connecting",peerConnection:g,dataChannel:_,callId:T}),this.emit("connection_change",c(this,ie).status),_.addEventListener("open",()=>{k(this,ie,{status:"connected",peerConnection:g,dataChannel:_,callId:T}),this.updateSessionConfig(d),this.emit("connection_change",c(this,ie).status),this._onOpen(),a()}),_.addEventListener("error",A=>{this.close(),this._onError(A),u(A)}),_.addEventListener("message",A=>{this._onMessage(A);const{data:D,isGeneric:U}=Er(A);if(!(!D||U)&&(D.type==="response.created"?k(this,yt,!0):D.type==="response.done"&&k(this,yt,!1),D.type==="session.created")){this._tracingConfig=D.session.tracing;const G=typeof d.tracing>"u"?"auto":d.tracing;this._updateTracingConfig(G)}});const h=this.options.audioElement??document.createElement("audio");h.autoplay=!0,g.ontrack=A=>{h.srcObject=A.streams[0]};const v=this.options.mediaStream??await navigator.mediaDevices.getUserMedia({audio:!0});if(g.addTrack(v.getAudioTracks()[0]),this.options.changePeerConnection){const A=g;g=await this.options.changePeerConnection(g),A!==g&&(A.onconnectionstatechange=null),y(g),k(this,ie,{...c(this,ie),peerConnection:g})}const b=await g.createOffer();if(await g.setLocalDescription(b),!b.sdp)throw new Error("Failed to create offer");const N=await fetch(m,{method:"POST",body:b.sdp,headers:{"Content-Type":"application/sdp",Authorization:`Bearer ${i}`,"X-OpenAI-Agents-SDK":to["X-OpenAI-Agents-SDK"]}});T=(p=(l=N.headers)==null?void 0:l.get("Location"))==null?void 0:p.split("/").pop(),k(this,ie,{...c(this,ie),callId:T});const x={type:"answer",sdp:await N.text()};await g.setRemoteDescription(x)}catch(d){this.close(),this._onError(d),u(d)}})}sendEvent(t){if(!c(this,ie).dataChannel||c(this,ie).dataChannel.readyState!=="open")throw new Error("WebRTC data channel is not connected. Make sure you call `connect()` before sending events.");c(this,ie).dataChannel.send(JSON.stringify(t))}mute(t){k(this,Gn,t),c(this,ie).peerConnection&&c(this,ie).peerConnection.getSenders().forEach(r=>{r.track&&(r.track.enabled=!t)})}_afterAudioDoneEvent(){k(this,yt,!1)}close(){if(c(this,ie).dataChannel&&c(this,ie).dataChannel.close(),c(this,ie).peerConnection){const t=c(this,ie).peerConnection;t.onconnectionstatechange=null,t.getSenders().forEach(s=>{var r;(r=s.track)==null||r.stop()}),t.close()}c(this,ie).status!=="disconnected"&&(k(this,ie,{status:"disconnected",peerConnection:void 0,dataChannel:void 0,callId:void 0}),this.emit("connection_change",c(this,ie).status),this._onClose())}interrupt(){c(this,yt)&&(this.sendEvent({type:"response.cancel"}),k(this,yt,!1)),this.sendEvent({type:"output_audio_buffer.clear"})}}qn=new WeakMap,ie=new WeakMap,Jn=new WeakMap,yt=new WeakMap,Gn=new WeakMap;const rf=globalThis.WebSocket;class af extends Ms{constructor(t={}){super(t);R(this,Bt);R(this,_t);R(this,jt);R(this,Ut);R(this,ye,{status:"disconnected",websocket:void 0});R(this,Vn);R(this,at);R(this,Lt);S(this,"_firstAudioTimestamp");S(this,"_audioLengthMs",0);R(this,zt,!1);R(this,ln);R(this,Hn);k(this,jt,t.url),k(this,Ut,t.url),k(this,Vn,t.useInsecureApiKey??!1),k(this,ln,t.createWebSocket),k(this,Hn,t.skipOpenEventListeners??!1)}getCommonRequestHeaders(){return to}get status(){return c(this,ye).status}get connectionState(){return c(this,ye)}get muted(){return null}get currentItemId(){return c(this,at)}_onAudio(t){this.emit("audio",t)}_afterAudioDoneEvent(){z(this,Bt,Zr).call(this)}async connect(t){const s=t.model??this.currentModel;this.currentModel=s,k(this,_t,await this._getApiKey(t));const r=t.callId;let i;t.url?(i=t.url,k(this,Ut,t.url)):r?i=`wss://api.openai.com/v1/realtime?call_id=${r}`:c(this,Ut)?i=c(this,Ut):i=`wss://api.openai.com/v1/realtime?model=${this.currentModel}`,k(this,jt,i);const o={...t.initialSessionConfig||{},model:this.currentModel};await new Promise((a,u)=>{z(this,Bt,bo).call(this,a,u,o).catch(u)}),await this.updateSessionConfig(o)}sendEvent(t){if(!c(this,ye).websocket)throw new Error("WebSocket is not connected. Make sure you call `connect()` before sending events.");c(this,ye).websocket.send(JSON.stringify(t))}close(){var t;(t=c(this,ye).websocket)==null||t.close(),k(this,at,void 0),this._firstAudioTimestamp=void 0,this._audioLengthMs=0,k(this,Lt,void 0)}mute(t){throw new Error("Mute is not supported for the WebSocket transport. You have to mute the audio input yourself.")}sendAudio(t,s={}){c(this,ye).status==="connected"&&super.sendAudio(t,s)}_cancelResponse(){c(this,zt)&&(this.sendEvent({type:"response.cancel"}),k(this,zt,!1))}_interrupt(t,s=!0){if(t<0)return;s&&this._cancelResponse();const r=this._audioLengthMs??Number.POSITIVE_INFINITY,i=Math.max(0,Math.floor(Math.min(t,r)));this.emit("audio_interrupted"),this.sendEvent({type:"conversation.item.truncate",item_id:c(this,at),content_index:c(this,Lt),audio_end_ms:i})}interrupt(t=!0){if(!c(this,at)||typeof this._firstAudioTimestamp!="number")return;const s=Date.now()-this._firstAudioTimestamp;s>=0&&this._interrupt(s,t),z(this,Bt,Zr).call(this)}}_t=new WeakMap,jt=new WeakMap,Ut=new WeakMap,ye=new WeakMap,Vn=new WeakMap,at=new WeakMap,Lt=new WeakMap,zt=new WeakMap,ln=new WeakMap,Hn=new WeakMap,Bt=new WeakSet,Zr=function(){k(this,at,void 0),this._firstAudioTimestamp=void 0,this._audioLengthMs=0,k(this,Lt,void 0)},bo=async function(t,s,r){if(c(this,ye).websocket){t();return}if(!c(this,_t))throw new re("API key is not set. Please call `connect()` with an API key first.");if(!c(this,_t).startsWith("ek_")&&!c(this,Vn))throw new re("Using the WebSocket connection in a browser environment requires an ephemeral client key. If you have to use a regular API key, set the `useInsecureApiKey` option to true.");let i=null;if(c(this,ln))i=await c(this,ln).call(this,{url:c(this,jt),apiKey:c(this,_t)});else{const a=["realtime","openai-insecure-api-key."+c(this,_t),Hd];i=new rf(c(this,jt),a)}k(this,ye,{status:"connecting",websocket:i}),this.emit("connection_change",c(this,ye).status);const o=()=>{k(this,ye,{status:"connected",websocket:i}),this.emit("connection_change",c(this,ye).status),this._onOpen(),t()};c(this,Hn)===!0?o():i.addEventListener("open",o),i.addEventListener("error",a=>{this._onError(a),k(this,ye,{status:"disconnected",websocket:void 0}),this.emit("connection_change",c(this,ye).status),s(a)}),i.addEventListener("message",a=>{var p,d,m,g,_,T,y;this._onMessage(a);const{data:u,isGeneric:l}=Er(a);if(!(!u||l)){if(u.type==="response.output_audio.delta"){k(this,Lt,u.content_index),k(this,at,u.item_id),this._firstAudioTimestamp===void 0&&(this._firstAudioTimestamp=Date.now(),this._audioLengthMs=0);const h=Bd(u.delta),v=(m=(d=(p=this._rawSessionConfig)==null?void 0:p.audio)==null?void 0:d.output)==null?void 0:m.format;if(v&&typeof v=="object"){const N=v.type;if(N==="audio/pcmu"||N==="audio/pcma")this._audioLengthMs+=h.byteLength/8;else if(N==="audio/pcm"){const x=v.rate??24e3;this._audioLengthMs+=h.byteLength/2/x*1e3}else this._audioLengthMs+=h.byteLength/24/2}else typeof v=="string"?v.startsWith("g711_")?this._audioLengthMs+=h.byteLength/8:this._audioLengthMs+=h.byteLength/24/2:this._audioLengthMs+=h.byteLength/24/2;const b={type:"audio",data:h,responseId:u.response_id};this._onAudio(b)}else if(u.type==="input_audio_buffer.speech_started"){const h=((y=(T=(_=(g=this._rawSessionConfig)==null?void 0:g.audio)==null?void 0:_.input)==null?void 0:T.turn_detection)==null?void 0:y.interrupt_response)??!1;this.interrupt(!h)}else if(u.type==="response.created")k(this,zt,!0);else if(u.type==="response.done")k(this,zt,!1);else if(u.type==="session.created"){this._tracingConfig=u.session.tracing;const h=typeof r.tracing>"u"?"auto":r.tracing;this._updateTracingConfig(h)}}}),i.addEventListener("close",()=>{k(this,ye,{status:"disconnected",websocket:void 0}),this.emit("connection_change",c(this,ye).status),this._onClose()})};const of=Symbol("backgroundResult");function uf(n){return typeof n=="object"&&n!==null&&of in n}function cf(n){return n.type==="function"||n.type==="hosted_tool"&&n.name==="hosted_mcp"}function lf(n){if(n.type==="function")return n;if(n.type==="hosted_tool"&&n.name==="hosted_mcp"){const e=n.providerData.server_url&&n.providerData.server_url.length>0?n.providerData.server_url:void 0;return{type:"mcp",server_label:n.providerData.server_label,server_url:e,headers:n.providerData.headers,allowed_tools:n.providerData.allowed_tools,require_approval:n.providerData.require_approval}}throw new re(`Invalid tool type: ${n}`)}function df(){return JSON.parse(JSON.stringify(Je))}const Mr=class Mr extends ws{constructor(t,s={}){super();R(this,ae);S(this,"initialAgent");S(this,"options");R(this,W);R(this,Z);R(this,dn);R(this,q);R(this,pn,[]);R(this,fn);R(this,Wn,{});R(this,ue,[]);R(this,hn);R(this,mn,{});R(this,Ge,!1);R(this,Kn,new Map);R(this,Zt,[]);R(this,Yn,df());R(this,Xn,!0);this.initialAgent=t,this.options=s,typeof s.transport>"u"&&Gd()||s.transport==="webrtc"?k(this,W,new sf):s.transport==="websocket"||typeof s.transport>"u"?k(this,W,new af):k(this,W,s.transport),k(this,Z,t),k(this,q,new Wt({...s.context??{},history:c(this,ue)})),k(this,pn,(s.outputGuardrails??[]).map(Xd)),k(this,fn,Yd(s.outputGuardrailSettings??{})),k(this,hn,s.historyStoreAudio??!1),k(this,Xn,s.automaticallyTriggerResponseForMcpToolCalls??!0)}get transport(){return c(this,W)}get currentAgent(){return c(this,Z)}get usage(){return c(this,q).usage}get context(){return c(this,q)}get muted(){return c(this,W).muted}get history(){return c(this,ue)}get availableMcpTools(){return c(this,Zt)}async getInitialSessionConfig(t={}){return await z(this,ae,ts).call(this,this.initialAgent),z(this,ae,ns).call(this,{...this.options.config??{},...t??{}})}static async computeInitialSessionConfig(t,s={},r={}){const i=new Mr(t,s);try{return await i.getInitialSessionConfig(r)}finally{i.close()}}async updateAgent(t){return c(this,Z).emit("agent_handoff",c(this,q),t),this.emit("agent_handoff",c(this,q),c(this,Z),t),await z(this,ae,ts).call(this,t),await c(this,W).updateSessionConfig(await z(this,ae,ns).call(this)),t}async connect(t){await z(this,ae,ts).call(this,this.initialAgent),z(this,ae,So).call(this),await c(this,W).connect({apiKey:t.apiKey??this.options.apiKey,model:this.options.model,url:t.url,callId:t.callId,initialSessionConfig:await z(this,ae,ns).call(this,this.options.config)}),k(this,ue,[]),this.emit("history_updated",c(this,ue))}updateHistory(t){let s;typeof t=="function"?s=t(c(this,ue)):s=t,c(this,W).resetHistory(c(this,ue),s)}sendMessage(t,s={}){c(this,W).sendMessage(t,s)}addImage(t,{triggerResponse:s=!0}={}){c(this,W).addImage(t,{triggerResponse:s})}mute(t){c(this,W).mute(t)}close(){k(this,mn,{}),c(this,W).close()}sendAudio(t,s={}){c(this,W).sendAudio(t,s)}interrupt(){c(this,W).interrupt()}async approve(t,s={alwaysApprove:!1}){c(this,q).approveTool(t,s);const r=t.toolName??t.rawItem.name,i=c(this,Z).tools.find(o=>o.name===r);if(i&&i.type==="function"&&t.rawItem.type==="function_call")await z(this,ae,js).call(this,t.rawItem,i);else if(t.rawItem.type==="hosted_tool_call"){s.alwaysApprove&&Ne.warn("Always approving MCP tools is not supported. Use the allowed tools configuration instead.");const o=no(t);c(this,W).sendMcpResponse(o,!0)}else throw new Se(`Tool ${r??"unknown"} not found`)}async reject(t,s={alwaysReject:!1}){c(this,q).rejectTool(t,s);const r=t.toolName??t.rawItem.name,i=c(this,Z).tools.find(o=>o.name===r);if(i&&i.type==="function"&&t.rawItem.type==="function_call")await z(this,ae,js).call(this,t.rawItem,i);else if(t.rawItem.type==="hosted_tool_call"){s.alwaysReject&&Ne.warn("Always rejecting MCP tools is not supported. Use the allowed tools configuration instead.");const o=no(t);c(this,W).sendMcpResponse(o,!1)}else throw new Se(`Tool ${r??"unknown"} not found`)}};W=new WeakMap,Z=new WeakMap,dn=new WeakMap,q=new WeakMap,pn=new WeakMap,fn=new WeakMap,Wn=new WeakMap,ue=new WeakMap,hn=new WeakMap,mn=new WeakMap,Ge=new WeakMap,Kn=new WeakMap,Zt=new WeakMap,Yn=new WeakMap,Xn=new WeakMap,ae=new WeakSet,ts=async function(t){k(this,Z,t);const s=await c(this,Z).getEnabledHandoffs(c(this,q)),r=s.map(u=>u.getHandoffAsFunctionTool()),i=(await c(this,Z).getAllTools(c(this,q))).filter(cf).map(lf),o=typeof c(this,Z).tools<"u"||typeof c(this,Z).mcpServers<"u",a=s.length>0;k(this,dn,o||a?[...i,...r]:void 0),z(this,ae,Jr).call(this)},ns=async function(t={}){const s=t??{},r=this.options.config??{},i=await c(this,Z).getSystemPrompt(c(this,q)),o=g=>{var T;const _=g.audio;return(T=_==null?void 0:_.output)==null?void 0:T.voice},a=this.options.tracingDisabled?null:this.options.workflowName?{workflow_name:this.options.workflowName}:"auto";a!==null&&a!=="auto"?(this.options.groupId&&(a.group_id=this.options.groupId),this.options.traceMetadata&&(a.metadata=this.options.traceMetadata)):(this.options.groupId||this.options.traceMetadata)&&Ne.warn("In order to set traceMetadata or a groupId you need to specify a workflowName.");const u=o(s)??o(r),l=s.voice??r.voice,p=typeof u<"u"?u:typeof l<"u"?l:c(this,Z).voice,m={...{...c(this,Yn)??{},...r,...s},instructions:i,voice:p,model:this.options.model,tools:c(this,dn),tracing:a,prompt:typeof c(this,Z).prompt=="function"?await c(this,Z).prompt(c(this,q),c(this,Z)):c(this,Z).prompt};return k(this,Yn,m),m},wo=async function(t,s){const r=await s.onInvokeHandoff(c(this,q),t.arguments);c(this,Z).emit("agent_handoff",c(this,q),r),this.emit("agent_handoff",c(this,q),c(this,Z),r),await z(this,ae,ts).call(this,r),await c(this,W).updateSessionConfig(await z(this,ae,ns).call(this));const i=Vi(r);return c(this,W).sendFunctionCallOutput(t,i,!0),r},js=async function(t,s){c(this,q).context.history=JSON.parse(JSON.stringify(c(this,ue)));let r=t.arguments;if(s.parameters&&(kt(s.parameters)?r=s.parameters.parse(r):r=JSON.parse(r)),await s.needsApproval(c(this,q),r,t.callId)){const u=this.context.isToolApproved({toolName:s.name,callId:t.callId});if(u===!1){this.emit("agent_tool_start",c(this,q),c(this,Z),s,{toolCall:t}),c(this,Z).emit("agent_tool_start",c(this,q),s,{toolCall:t});const l="Tool execution was not approved.";c(this,W).sendFunctionCallOutput(t,l,!0),this.emit("agent_tool_end",c(this,q),c(this,Z),s,l,{toolCall:t}),c(this,Z).emit("agent_tool_end",c(this,q),s,l,{toolCall:t});return}else if(typeof u>"u"){this.emit("tool_approval_requested",c(this,q),c(this,Z),{type:"function_approval",tool:s,approvalItem:new Ie(t,c(this,Z))});return}}this.emit("agent_tool_start",c(this,q),c(this,Z),s,{toolCall:t}),c(this,Z).emit("agent_tool_start",c(this,q),s,{toolCall:t}),c(this,q).context.history=JSON.parse(JSON.stringify(c(this,ue)));const o=await s.invoke(c(this,q),t.arguments,{toolCall:t});let a;uf(o)?(a=lt(o.content),c(this,W).sendFunctionCallOutput(t,a,!1)):(a=lt(o),c(this,W).sendFunctionCallOutput(t,a,!0)),this.emit("agent_tool_end",c(this,q),c(this,Z),s,a,{toolCall:t}),c(this,Z).emit("agent_tool_end",c(this,q),s,a,{toolCall:t})},Io=async function(t){const s=await c(this,Z).getEnabledHandoffs(c(this,q)),r=new Map(s.map(u=>[u.toolName,u])),i=await c(this,Z).getAllTools(c(this,q)),o=new Map(i.map(u=>[u.name,u])),a=r.get(t.name);if(a)await z(this,ae,wo).call(this,t,a);else{const u=o.get(t.name);if(u&&u.type==="function")await z(this,ae,js).call(this,t,u);else throw new Se(`Tool ${t.name} not found`)}},qr=async function(t,s,r){if(c(this,pn).length===0)return;const i={agent:c(this,Z),agentOutput:t,context:c(this,q)},a=(await Promise.all(c(this,pn).map(u=>u.run(i)))).find(u=>u.output.tripwireTriggered);if(a){if(c(this,mn)[s])return;c(this,mn)[s]=!0;const u=new Ys(`Output guardrail triggered: ${JSON.stringify(a.output.outputInfo)}`,a);this.emit("guardrail_tripped",c(this,q),c(this,Z),u,{itemId:r}),this.interrupt();const l=Qd(a);this.sendMessage(l);return}},So=function(){c(this,W).on("*",r=>{if(this.emit("transport_event",r),r.type==="conversation.item.input_audio_transcription.completed")try{const i=r;k(this,ue,eo(c(this,ue),i,c(this,hn))),c(this,q).context.history=c(this,ue),this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("mcp_tools_listed",({serverLabel:r,tools:i})=>{try{c(this,Kn).set(r,i??[]),z(this,ae,Jr).call(this)}catch(o){this.emit("error",{type:"error",error:o})}}),c(this,W).on("audio",r=>{c(this,Ge)||(k(this,Ge,!0),this.emit("audio_start",c(this,q),c(this,Z))),this.emit("audio",r)}),c(this,W).on("turn_started",()=>{k(this,Ge,!1),this.emit("agent_start",c(this,q),c(this,Z)),c(this,Z).emit("agent_start",c(this,q),c(this,Z))}),c(this,W).on("turn_done",r=>{const i=r.response.output[r.response.output.length-1],o=qd(i)??"",a=(i==null?void 0:i.id)??"";this.emit("agent_end",c(this,q),c(this,Z),o),c(this,Z).emit("agent_end",c(this,q),o),z(this,ae,qr).call(this,o,r.response.id,a)}),c(this,W).on("audio_done",()=>{c(this,Ge)&&k(this,Ge,!1),this.emit("audio_stopped",c(this,q),c(this,Z))});let t=0,s;c(this,W).on("audio_transcript_delta",r=>{try{const i=r.delta,o=r.itemId,a=r.responseId;s!==o&&(s=o,t=0);const l=(c(this,Wn)[o]??"")+i;if(c(this,Wn)[o]=l,c(this,fn).debounceTextLength<0)return;const p=Math.floor(l.length/c(this,fn).debounceTextLength);p>t&&(t=p,z(this,ae,qr).call(this,l,a,o))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("item_update",r=>{try{const i=!c(this,ue).some(o=>o.itemId===r.itemId);if(k(this,ue,eo(c(this,ue),r,c(this,hn))),c(this,q).context.history=c(this,ue),i){const o=c(this,ue).find(a=>a.itemId===r.itemId);o&&this.emit("history_added",o)}this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("item_deleted",r=>{try{k(this,ue,c(this,ue).filter(i=>i.itemId!==r.itemId)),c(this,q).context.history=c(this,ue),this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("function_call",async r=>{try{await z(this,ae,Io).call(this,r)}catch(i){Ne.error("Error handling function call",i),this.emit("error",{type:"error",error:i})}}),c(this,W).on("usage_update",r=>{c(this,q).usage.add(r)}),c(this,W).on("audio_interrupted",()=>{c(this,Ge)&&k(this,Ge,!1),this.emit("audio_interrupted",c(this,q),c(this,Z))}),c(this,W).on("error",r=>{this.emit("error",r)}),c(this,W).on("mcp_tool_call_completed",r=>{this.emit("mcp_tool_call_completed",c(this,q),c(this,Z),r),c(this,Xn)&&c(this,W).sendEvent({type:"response.create"})}),c(this,W).on("mcp_approval_request",r=>{this.emit("tool_approval_requested",c(this,q),c(this,Z),{type:"mcp_approval_request",approvalItem:Wd(c(this,Z),r)})})},Jr=function(){var u;const t=(u=c(this,dn))==null?void 0:u.filter(l=>l.type==="mcp"),s=l=>{const p=l.allowed_tools;if(p){if(Array.isArray(p))return p;if(p&&Array.isArray(p.tool_names))return p.tool_names}},r=new Map;for(const l of t){const p=c(this,Kn).get(l.server_label)??[],d=s(l);for(const m of p)d&&!d.includes(m.name)||r.has(m.name)||r.set(m.name,m)}const i=Array.from(r.values()),o=c(this,Zt);(o.length!==i.length||JSON.stringify(o.map(l=>l.name).sort())!==JSON.stringify(i.map(l=>l.name).sort()))&&(k(this,Zt,i),this.emit("mcp_tools_changed",c(this,Zt)))};let Rr=Mr;class pf{constructor(){this._listeners={}}on(e,t){return this._listeners[e]||(this._listeners[e]=new Set),this._listeners[e].add(t),this}off(e,t){const s=this._listeners[e];return s&&(s.delete(t),s.size===0&&delete this._listeners[e]),this}emit(e,...t){const s=this._listeners[e];if(!s||s.size===0)return!1;for(const r of Array.from(s))try{r(...t)}catch(i){console.error(`BabelbeezClient listener for event "${e}" threw:`,i)}return!0}}const Rt={DEBUG:0,INFO:1,WARN:2,ERROR:3},uo=!0,ff=Rt.INFO;function $(n,e,...t){const s=Rt[n]??Rt.INFO;if(!(s<ff))switch(s){case Rt.DEBUG:console.debug(`[${n}] ${e}`,...t);break;case Rt.INFO:console.info(`[${n}] ${e}`,...t);break;case Rt.WARN:console.warn(`[${n}] ${e}`,...t);break;case Rt.ERROR:{const r=t.find(o=>o instanceof Error),i=e+(r&&r.message?`: ${r.message}`:"");console.error(`[${n}] ${i}`)}break;default:console.log(`[${n}] ${e}`,...t)}}function co(n,e){if(!e)return n;n||(n={});for(const t in e){if(!Object.prototype.hasOwnProperty.call(e,t))continue;const s=e[t],r=n[t];typeof s=="number"?n[t]=(typeof r=="number"?r:0)+s:typeof s=="object"&&s!==null&&!Array.isArray(s)&&((typeof r!="object"||r===null||Array.isArray(r))&&(n[t]={}),co(n[t],s))}return n}const hf=15e3,mf=2e3,gf="https://www.babelbeez.com/initialize-chat";class yf extends pf{constructor(e){if(super(),!e||!e.publicChatbotId)throw new Error("BabelbeezClient: publicChatbotId is required.");this.publicChatbotId=e.publicChatbotId;const t=e.proxyInitializeUrl||gf;this.proxyInitializeUrl=t,this.apiBaseUrl=e.apiBaseUrl||new URL(t).origin,this.agent=null,this.session=null,this.currentSystemSettings=null,this.currentChatbotSettings=null,this.currentSessionId=null,this.currentRagSearchUrl=null,this.sessionStartTime=null,this.accumulatedUsage=null,this.hasEndConversationBeenHandled=!1,this.isTerminating=!1,this.isUserSpeaking=!1,this.isAssistantSpeaking=!1,this.isHandoffFormOpen=!1,this.inactivityStage=0,this.inactivityStage1TimeoutId=null,this.inactivityStage2TimeoutId=null,this.shouldScheduleStage2OnNextAssistantSilence=!1,this.pendingGoodbyeResolve=null,this.handoffPromiseResolve=null,this.currentHandoffSummaryText=null,this.heartbeatIntervalId=null,this.heartbeatFrequencySeconds=null,this._lastInitData=null,this._lastAssistantMessageId=null,this._lastAssistantTranscript="",this._currentAssistantTranscript="",this._currentUserTranscript=""}async connect(){if(this.session){$("WARN","BabelbeezClient.connect() called while session already active; ignoring.");return}$("INFO","BabelbeezClient.connect: initializing via proxy and connecting RealtimeSession.");const e=await this._initializeSessionViaProxy();this._lastInitData=e;const{openai_token:t,system_settings:s,chatbot_config:r,session_id:i,heartbeat_frequency_seconds:o}=e;this.currentSystemSettings=s,this.currentChatbotSettings=r,this.currentSessionId=i,this.heartbeatFrequencySeconds=o,this.currentRagSearchUrl=`${this.apiBaseUrl}/api/perform-rag-search`,$("DEBUG","BabelbeezClient: using RAG search URL",this.currentRagSearchUrl),this._resetAccumulatedUsage(),this._resetInactivityState(),this.isUserSpeaking=!1,this.isAssistantSpeaking=!1,this.isTerminating=!1,this.hasEndConversationBeenHandled=!1;try{this.emit("buttonState","loading"),this.agent=this._createVoiceAgent(),this.session=this._createVoiceSession(s,r),await this.session.connect({apiKey:t}),this._attachTransportListeners(),this.sessionStartTime=Date.now(),this.emit("buttonState","active"),this.emit("session:start",{chatbotId:this.publicChatbotId,config:this.currentChatbotSettings}),this._startHeartbeat(),this._resetInactivityState(),$("INFO","BabelbeezClient: Realtime session connected."),setTimeout(()=>{var u;const a=(u=this.currentChatbotSettings)==null?void 0:u.greetingInstructions;if(a)try{this.session&&this.session.transport&&this.session.transport.sendEvent({type:"response.create",response:{conversation:"none",output_modalities:["audio"],instructions:a,tools:[],input:[{type:"message",role:"user",content:[{type:"input_text",text:"The caller has just connected. Greet them now."}]}],metadata:{source:"greeting"}}})}catch(l){$("WARN","BabelbeezClient: failed to trigger greeting response (post-connect).",l)}},0)}catch(a){let u=`Connect Session failed: ${(a==null?void 0:a.message)||"Unknown error"}`,l="connection_error",p="CONNECTION_FAILED";throw a&&(a.name==="NotAllowedError"||a.name==="PermissionDeniedError")?(u="Microphone access denied. Please allow microphone access in your browser settings.",l="microphone_permission_denied",p="MIC_DENIED"):a&&a.name==="NotFoundError"&&(u="No microphone found. Please ensure a microphone is connected and enabled.",l="microphone_not_found",p="MIC_NOT_FOUND"),$("ERROR",u,a),this.emit("buttonState","error"),this.emit("error",{code:p,message:u,severity:"error",fatal:!0}),await this._finalizeSession(l),a}}async disconnect(e="client_disconnect"){if($("INFO",`BabelbeezClient.disconnect called. Reason: ${e}`),e==="user_button_click"){try{this.session&&(await this.session.interrupt(),$("INFO","Session interrupted by user_button_click before goodbye."))}catch(t){$("WARN","Error interrupting session during user_button_click; proceeding with goodbye anyway.",t)}await this._playGoodbyeThenFinalize(e);return}await this._finalizeSession(e)}initializeAudio(){try{const e=window.AudioContext||window.webkitAudioContext;if(!e)return;const t=this._audioCtx||new e;this._audioCtx=t,t.state==="suspended"&&t.resume().catch(()=>{});try{const s=t.currentTime,r=t.createGain();r.gain.setValueAtTime(1e-4,s),r.connect(t.destination);const i=t.createOscillator();i.type="sine",i.frequency.setValueAtTime(440,s),i.connect(r),i.start(s),i.stop(s+.02),i.onended=()=>{try{i.disconnect(),r.disconnect()}catch{}}}catch{}}catch(e){$("WARN","BabelbeezClient.initializeAudio failed",e)}}async sendUserText(e){if(!this.session||this.isTerminating){$("WARN","Cannot send text message; session is not active or is terminating.");return}const t=(e??"").trim();if(!t){$("DEBUG","sendUserText called with empty/whitespace text; ignoring.");return}if(this.isAssistantSpeaking)try{await this.session.interrupt()}catch(s){$("WARN","Failed to interrupt assistant before sending user text.",s)}this._resetInactivityState();try{await this.session.sendMessage(t),this.emit("transcript",{role:"user",text:t,isFinal:!0})}catch(s){$("ERROR","Failed to send user text message",s)}}async handleHandoffSubmit(e){if(!this.isHandoffFormOpen){$("WARN","handleHandoffSubmit called but no handoff form is open.");return}const{email:t,consent:s}=e||{},r=this.currentHandoffSummaryText||"Summary not available.";try{const i=`${this.apiBaseUrl}/handoff/request`,o=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:this.currentSessionId,email:t,consent:s,summary:r})});if(o.ok)$("INFO","Handoff request submitted successfully.");else{let a=`HTTP ${o.status}`;try{const u=await o.json();u&&u.detail&&(a=u.detail)}catch{}$("ERROR",`Failed to submit handoff request: ${a}`),this.emit("error",{code:"HANDOFF_FAILED",message:"Failed to submit handoff request. Please try again later.",severity:"error",fatal:!1})}}catch(i){$("ERROR","Network or unexpected error submitting handoff request.",i),this.emit("error",{code:"HANDOFF_FAILED",message:"Network error submitting handoff request. Please try again later.",severity:"error",fatal:!1})}finally{this.isHandoffFormOpen=!1,this._resetInactivityState(),this.isTerminating||this._setSessionMuted(!1,"handoff_form"),this.emit("handoff:hide",{outcome:"email_submitted"}),this.handoffPromiseResolve&&(this.handoffPromiseResolve("email_submitted"),this.handoffPromiseResolve=null)}try{this.session&&await this.session.sendMessage("The user has submitted their contact details. Confirm that their request was received and that a team member will follow up. See if there's anything else you can help them with in the meantime.")}catch(i){$("WARN","Failed to send post-handoff confirmation message.",i)}}async handleHandoffCancel(e={}){const{viaWhatsapp:t}=e;if(!this.isHandoffFormOpen){$("WARN","handleHandoffCancel called but no handoff form is open.");return}this.isHandoffFormOpen=!1,this._resetInactivityState(),this.isTerminating||this._setSessionMuted(!1,"handoff_form");const s=t?"whatsapp_submitted":"cancelled";if(this.emit("handoff:hide",{outcome:s}),this.handoffPromiseResolve&&(this.handoffPromiseResolve(s),this.handoffPromiseResolve=null),t){await this._playGoodbyeThenFinalize("handoff_whatsapp");return}try{this.session&&await this.session.sendMessage("The user changed their mind and no longer wishes to fill out the form right now. See if there's anything else you can help them with.")}catch(r){$("WARN","Failed to send handoff cancellation message.",r)}}async _initializeSessionViaProxy(){$("INFO","BabelbeezClient: Initializing session via proxy /initialize-chat...");const e=typeof navigator<"u"&&(navigator.language||navigator.userLanguage)||null,t=await fetch(this.proxyInitializeUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({public_chatbot_id:this.publicChatbotId,browser_language:e})});if(!t.ok){let r=`HTTP error ${t.status}: ${t.statusText}`;try{const i=await t.json();i&&i.detail&&(r=i.detail)}catch{}throw $("ERROR","BabelbeezClient: /initialize-chat failed",r),new Error(r)}const s=await t.json();if(!s.session_id||!s.openai_token||!s.system_settings||!s.chatbot_config||s.heartbeat_frequency_seconds===void 0)throw $("ERROR","BabelbeezClient: Invalid response structure from /initialize-chat.",s?{...s,openai_token:"***"}:null),new Error("Incomplete session details received from server.");return $("INFO","BabelbeezClient: Session initialized via proxy.",{session_id:s.session_id,heartbeat_frequency_seconds:s.heartbeat_frequency_seconds}),s}_resetAccumulatedUsage(){this.accumulatedUsage={total_tokens:0,input_tokens:0,output_tokens:0,input_token_details:{cached_tokens:0,text_tokens:0,audio_tokens:0,cached_tokens_details:{text_tokens:0,audio_tokens:0}},output_token_details:{text_tokens:0,audio_tokens:0}},$("DEBUG","BabelbeezClient: accumulated token usage reset.")}_setSessionMuted(e,t=""){try{this.session&&this.session.transport&&typeof this.session.transport.mute=="function"&&(this.session.transport.mute(e),$("DEBUG",`Session ${e?"muted":"unmuted"}${t?` (${t})`:""}.`))}catch{}}_clearInactivityTimers(){this.inactivityStage1TimeoutId&&(clearTimeout(this.inactivityStage1TimeoutId),this.inactivityStage1TimeoutId=null),this.inactivityStage2TimeoutId&&(clearTimeout(this.inactivityStage2TimeoutId),this.inactivityStage2TimeoutId=null)}_resetInactivityState(){this.inactivityStage=0,this.shouldScheduleStage2OnNextAssistantSilence=!1,this._clearInactivityTimers()}async _sendInactivityEnquiry(){var t,s;const e=(((t=this.currentChatbotSettings)==null?void 0:t.inactivityTimeoutMs)||0)/1e3;$("INFO",`User inactive for ${e}s. Sending enquiry.`),this.shouldScheduleStage2OnNextAssistantSilence=!0;try{(s=this.currentSystemSettings)!=null&&s.inactivityInstructions&&this.session&&await this.session.sendMessage(this.currentSystemSettings.inactivityInstructions)}catch(r){$("ERROR","Failed to send inactivity enquiry; ending session.",r),await this._finalizeSession("inactivity_enquiry_failed")}}async _playGoodbyeThenFinalize(e){var o,a;if(this.isTerminating){await this._finalizeSession(e);return}this._clearInactivityTimers();const t=(a=(o=this.currentSystemSettings)==null?void 0:o.goodbyeInstructions)==null?void 0:a.trim();if(!this.session||!t){$("INFO","No goodbyeInstructions configured or no active session; finalizing immediately."),await this._finalizeSession(e);return}$("INFO","Playing goodbye message before finalizing session.");const s=new Promise(u=>{this.pendingGoodbyeResolve=u});try{this._setSessionMuted(!0,"goodbye"),await this.session.sendMessage(t)}catch(u){$("WARN","Failed to send goodbye message; finalizing immediately.",u),this.pendingGoodbyeResolve=null,this._setSessionMuted(!1,"goodbye"),await this._finalizeSession(e);return}const r=15e3,i=new Promise(u=>setTimeout(u,r));await Promise.race([s,i]),this.pendingGoodbyeResolve=null,this._setSessionMuted(!1,"goodbye"),await this._finalizeSession(e)}_createVoiceAgent(){var u,l,p,d;const e=(u=this.currentSystemSettings)!=null&&u.system_prompt?`${this.currentSystemSettings.system_prompt}
|
|
12
|
+
`.trim()}function Et(n,e){return n in e&&typeof e[n]<"u"}function ep(n){return Et("modalities",n)||Et("inputAudioFormat",n)||Et("outputAudioFormat",n)||Et("inputAudioTranscription",n)||Et("turnDetection",n)||Et("inputAudioNoiseReduction",n)||Et("speed",n)}function tp(n){var e,t,s,r,i,o,a,u;if(!ep(n)){const l=(e=n.audio)!=null&&e.input?{format:Ds(n.audio.input.format),noiseReduction:n.audio.input.noiseReduction??null,transcription:n.audio.input.transcription,turnDetection:n.audio.input.turnDetection}:void 0,p=((s=(t=n.audio)==null?void 0:t.output)==null?void 0:s.voice)??n.voice,d=(r=n.audio)!=null&&r.output||typeof p<"u"?{format:Ds((o=(i=n.audio)==null?void 0:i.output)==null?void 0:o.format),voice:p,speed:(u=(a=n.audio)==null?void 0:a.output)==null?void 0:u.speed}:void 0;return{model:n.model,instructions:n.instructions,toolChoice:n.toolChoice,tools:n.tools,tracing:n.tracing,providerData:n.providerData,prompt:n.prompt,outputModalities:n.outputModalities,audio:l||d?{input:l,output:d}:void 0}}return{model:n.model,instructions:n.instructions,toolChoice:n.toolChoice,tools:n.tools,tracing:n.tracing,providerData:n.providerData,prompt:n.prompt,outputModalities:n.modalities,audio:{input:{format:Ds(n.inputAudioFormat),noiseReduction:n.inputAudioNoiseReduction??null,transcription:n.inputAudioTranscription,turnDetection:n.turnDetection},output:{format:Ds(n.outputAudioFormat),voice:n.voice,speed:n.speed}}}}function Ds(n){if(!n)return;if(typeof n=="object")return n;const e=String(n);return e==="pcm16"?{type:"audio/pcm",rate:24e3}:e==="g711_ulaw"?{type:"audio/pcmu"}:e==="g711_alaw"?{type:"audio/pcma"}:{type:"audio/pcm",rate:24e3}}w({itemId:f()});const so=ve("role",[w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("system"),content:J(w({type:I("input_text"),text:f()}))}),w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("user"),status:pe(["in_progress","completed"]),content:J(w({type:I("input_text"),text:f()}).or(w({type:I("input_audio"),audio:f().nullable().optional(),transcript:f().nullable()})))}),w({itemId:f(),previousItemId:f().nullable().optional(),type:I("message"),role:I("assistant"),status:pe(["in_progress","completed","incomplete"]),content:J(w({type:I("output_text"),text:f()}).or(w({type:I("output_audio"),audio:f().nullable().optional(),transcript:f().nullable().optional()})))})]),ro=w({itemId:f(),previousItemId:f().nullable().optional(),type:I("function_call"),status:pe(["in_progress","completed","incomplete"]),arguments:f(),name:f(),output:f().nullable()}),io=w({itemId:f(),previousItemId:f().nullable().optional(),type:pe(["mcp_call","mcp_tool_call"]),status:pe(["in_progress","completed","incomplete"]),arguments:f(),name:f(),output:f().nullable()}),np=w({itemId:f(),type:I("mcp_approval_request"),serverLabel:f(),name:f(),arguments:se(f(),H()),approved:St().optional().nullable()}),Ne=Fi("openai-agents:realtime"),ao=w({id:f().optional().nullable(),conversation_id:f().optional().nullable(),max_output_tokens:E().or(I("inf")).optional().nullable(),metadata:se(f(),H()).optional().nullable(),output_modalities:J(f()).optional().nullable(),object:I("realtime.response").optional().nullable(),output:J(H()).optional().nullable(),audio:w({output:w({format:H().optional().nullable(),voice:f().optional().nullable()}).optional().nullable()}).optional().nullable(),status:pe(["completed","incomplete","failed","cancelled","in_progress"]).optional().nullable(),status_details:se(f(),H()).optional().nullable(),usage:w({input_tokens:E().optional(),input_token_details:se(f(),H()).optional().nullable(),output_tokens:E().optional(),output_token_details:se(f(),H()).optional().nullable()}).optional().nullable()}),sp=w({id:f().optional(),audio:f().nullable().optional(),text:f().nullable().optional(),transcript:f().nullable().optional(),type:Ye([I("input_text"),I("input_audio"),I("item_reference"),I("output_text"),I("output_audio")])}),Qt=w({id:f().optional(),arguments:f().optional(),call_id:f().optional(),content:J(sp).optional(),name:f().optional(),output:f().nullable().optional(),role:pe(["user","assistant","system"]).optional(),status:pe(["completed","incomplete","in_progress"]).optional(),type:pe(["message","function_call","function_call_output","mcp_list_tools","mcp_tool_call","mcp_call","mcp_approval_request","mcp_approval_response"]).optional(),approval_request_id:f().nullable().optional(),approve:St().nullable().optional(),reason:f().nullable().optional(),server_label:f().optional(),error:H().nullable().optional(),tools:J(w({name:f(),description:f(),input_schema:se(H()).optional()}).passthrough()).optional()}).passthrough(),rp=w({type:I("conversation.created"),event_id:f(),conversation:w({id:f().optional(),object:I("realtime.conversation").optional()})}),ip=w({type:I("conversation.item.added"),event_id:f(),item:Qt,previous_item_id:f().nullable().optional()}),ap=w({type:I("conversation.item.done"),event_id:f(),item:Qt,previous_item_id:f().nullable().optional()}),op=w({type:I("conversation.item.deleted"),event_id:f(),item_id:f()}),up=w({type:I("conversation.item.input_audio_transcription.completed"),event_id:f(),item_id:f(),content_index:E(),transcript:f(),logprobs:J(H()).nullable().optional(),usage:w({type:I("tokens"),total_tokens:E(),input_tokens:E(),input_token_details:w({text_tokens:E(),audio_tokens:E()}),output_tokens:E()}).optional()}),cp=w({type:I("conversation.item.input_audio_transcription.delta"),event_id:f(),item_id:f(),content_index:E().optional(),delta:f().optional(),logprobs:J(H()).nullable().optional()}),lp=w({type:I("conversation.item.input_audio_transcription.failed"),event_id:f(),item_id:f(),content_index:E(),error:w({code:f().optional(),message:f().optional(),param:f().optional(),type:f().optional()})}),dp=w({type:I("conversation.item.retrieved"),event_id:f(),item:Qt}),pp=w({type:I("conversation.item.truncated"),event_id:f(),item_id:f(),audio_end_ms:E(),content_index:E()}),fp=w({type:I("conversation.item.create"),item:Qt,event_id:f().optional(),previous_item_id:f().nullable().optional()}),hp=w({type:I("conversation.item.delete"),item_id:f(),event_id:f().optional()}),mp=w({type:I("conversation.item.retrieve"),item_id:f(),event_id:f().optional()}),gp=w({type:I("conversation.item.truncate"),item_id:f(),audio_end_ms:E(),content_index:E(),event_id:f().optional()}),yp=w({type:I("error"),event_id:f().optional(),error:H().optional()}),_p=w({type:I("input_audio_buffer.cleared"),event_id:f()}),vp=w({type:I("input_audio_buffer.append"),audio:f(),event_id:f().optional()}),bp=w({type:I("input_audio_buffer.clear"),event_id:f().optional()}),wp=w({type:I("input_audio_buffer.commit"),event_id:f().optional()}),Ip=w({type:I("input_audio_buffer.committed"),event_id:f(),item_id:f(),previous_item_id:f().nullable().optional()}),Sp=w({type:I("input_audio_buffer.speech_started"),event_id:f(),item_id:f(),audio_start_ms:E()}),Tp=w({type:I("input_audio_buffer.speech_stopped"),event_id:f(),item_id:f(),audio_end_ms:E()}),xp=w({type:I("output_audio_buffer.started"),event_id:f()}).passthrough(),kp=w({type:I("output_audio_buffer.stopped"),event_id:f()}).passthrough(),Ap=w({type:I("output_audio_buffer.cleared"),event_id:f()}),Cp=w({type:I("rate_limits.updated"),event_id:f(),rate_limits:J(w({limit:E().optional(),name:pe(["requests","tokens"]).optional(),remaining:E().optional(),reset_seconds:E().optional()}))}),Op=w({type:I("response.output_audio.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),Ep=w({type:I("response.output_audio.done"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f()}),Rp=w({type:I("response.output_audio_transcript.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),Np=w({type:I("response.output_audio_transcript.done"),event_id:f(),item_id:f(),content_index:E(),transcript:f(),output_index:E(),response_id:f()}),Pp=w({type:I("response.content_part.added"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f(),part:w({audio:f().optional(),text:f().optional(),transcript:f().optional(),type:pe(["text","audio"]).optional()})}),Dp=w({type:I("response.content_part.done"),event_id:f(),item_id:f(),content_index:E(),output_index:E(),response_id:f(),part:w({audio:f().optional(),text:f().optional(),transcript:f().optional(),type:pe(["text","audio"]).optional()})}),Mp=w({type:I("response.created"),event_id:f(),response:ao}),oo=w({type:I("response.done"),event_id:f(),response:ao}),Fp=w({type:I("response.function_call_arguments.delta"),event_id:f(),item_id:f(),call_id:f(),delta:f(),output_index:E(),response_id:f()}),$p=w({type:I("response.function_call_arguments.done"),event_id:f(),item_id:f(),call_id:f(),arguments:f(),output_index:E(),response_id:f()}),jp=w({type:I("response.output_item.added"),event_id:f(),item:Qt,output_index:E(),response_id:f()}),Up=w({type:I("response.output_item.done"),event_id:f(),item:Qt,output_index:E(),response_id:f()}),Lp=w({type:I("response.output_text.delta"),event_id:f(),item_id:f(),content_index:E(),delta:f(),output_index:E(),response_id:f()}),zp=w({type:I("response.output_text.done"),event_id:f(),item_id:f(),content_index:E(),text:f(),output_index:E(),response_id:f()}),Bp=w({type:I("session.created"),event_id:f(),session:H()}),Zp=w({type:I("session.updated"),event_id:f(),session:H()}),qp=w({type:I("response.cancel"),event_id:f().optional(),response_id:f().optional()}),Jp=w({type:I("response.create"),event_id:f().optional(),response:H().optional()}),Gp=w({type:I("session.update"),event_id:f().optional(),session:H()}),Vp=w({type:I("mcp_list_tools.in_progress"),event_id:f().optional(),item_id:f().optional()}),Hp=w({type:I("mcp_list_tools.completed"),event_id:f().optional(),item_id:f().optional()}),Wp=w({type:I("response.mcp_call_arguments.delta"),event_id:f(),response_id:f(),item_id:f(),output_index:E(),delta:f(),obfuscation:f()}),Kp=w({type:I("response.mcp_call_arguments.done"),event_id:f(),response_id:f(),item_id:f(),output_index:E(),arguments:f()}),Yp=w({type:I("response.mcp_call.in_progress"),event_id:f(),output_index:E(),item_id:f()}),Xp=w({type:I("response.mcp_call.completed"),event_id:f(),output_index:E(),item_id:f()}),Qp=w({type:I("mcp_list_tools.failed"),event_id:f().optional(),item_id:f().optional()}),ef=w({type:f(),event_id:f().optional().nullable()}).passthrough(),tf=ve("type",[rp,ip,ap,op,up,cp,lp,dp,pp,yp,_p,Ip,Sp,Tp,xp,kp,Ap,Cp,Op,Ep,Rp,Np,Pp,Dp,Mp,oo,Fp,$p,jp,Up,Lp,zp,Bp,Zp,Vp,Hp,Qp,Wp,Kp,Yp,Xp]);ve("type",[fp,hp,mp,gp,vp,bp,wp,qp,Jp,Gp]);function Er(n){const e=JSON.parse(n.data.toString()),t=tf.safeParse(e);if(!t.success){const s=ef.safeParse(e);return s.success?{data:s.data,isGeneric:!0}:{data:null,isGeneric:!0}}return{data:t.data,isGeneric:!1}}const nf="gpt-realtime",Je={outputModalities:["audio"],audio:{input:{format:{type:"audio/pcm",rate:24e3},transcription:{model:"gpt-4o-mini-transcribe"},turnDetection:{type:"semantic_vad"},noiseReduction:null},output:{format:{type:"audio/pcm",rate:24e3},speed:1}}},Dr=class Dr extends or{constructor(t={}){super();R(this,$t);R(this,Bn);R(this,xe,null);R(this,Zn,null);S(this,"eventEmitter",new ws);k(this,$t,t.model??nf),k(this,Bn,t.apiKey)}get currentModel(){return c(this,$t)}set currentModel(t){k(this,$t,t)}_afterAudioDoneEvent(){}get _rawSessionConfig(){return c(this,Zn)??null}async _getApiKey(t){const s=t.apiKey??c(this,Bn);return typeof s=="function"?await s():s}_onMessage(t){var i,o,a,u,l,p;const{data:s,isGeneric:r}=Er(t);if(s!==null&&(this.emit("*",s),!r)){if(s.type==="error"?this.emit("error",{type:"error",error:s}):this.emit(s.type,s),s.type==="response.created"){this.emit("turn_started",{type:"response_started",providerData:{...s}});return}if(s.type==="session.updated"&&k(this,Zn,s.session),s.type==="response.done"){const d=oo.safeParse(s);if(!d.success){Ne.error("Error parsing response done event",d.error);return}const m=((i=d.data.response.usage)==null?void 0:i.input_tokens)??0,g=((o=d.data.response.usage)==null?void 0:o.output_tokens)??0,_=m+g,T=new kn({inputTokens:m,inputTokensDetails:((a=d.data.response.usage)==null?void 0:a.input_token_details)??{},outputTokens:g,outputTokensDetails:((u=d.data.response.usage)==null?void 0:u.output_token_details)??{},totalTokens:_});this.emit("usage_update",T),this.emit("turn_done",{type:"response_done",response:{id:d.data.response.id??"",output:d.data.response.output??[],usage:{inputTokens:m,inputTokensDetails:((l=d.data.response.usage)==null?void 0:l.input_token_details)??{},outputTokens:g,outputTokensDetails:((p=d.data.response.usage)==null?void 0:p.output_token_details)??{},totalTokens:_}}});return}if(s.type==="response.output_audio.done"){this.emit("audio_done"),this._afterAudioDoneEvent();return}if(s.type==="conversation.item.deleted"){this.emit("item_deleted",{itemId:s.item_id});return}if(s.type==="conversation.item.input_audio_transcription.completed"||s.type==="conversation.item.truncated"){this.sendEvent({type:"conversation.item.retrieve",item_id:s.item_id});return}if(s.type==="conversation.item.input_audio_transcription.delta"||s.type==="response.output_text.delta"||s.type==="response.output_audio_transcript.delta"||s.type==="response.function_call_arguments.delta"){s.type==="response.output_audio_transcript.delta"&&this.emit("audio_transcript_delta",{type:"transcript_delta",delta:s.delta,itemId:s.item_id,responseId:s.response_id});return}if(s.type==="conversation.item.added"||s.type==="conversation.item.done"||s.type==="conversation.item.retrieved"){if(s.item.type==="mcp_list_tools"&&s.type==="conversation.item.done"){const d=s.item.server_label??"",m=s.item.tools??[];try{this.emit("mcp_tools_listed",{serverLabel:d,tools:m})}catch(g){Ne.error("Error emitting mcp_tools_listed",g,s.item)}return}if(s.item.type==="message"){const d=s.type==="conversation.item.added"||s.type==="conversation.item.done"?s.previous_item_id:null,m=so.parse({itemId:s.item.id,previousItemId:d,type:s.item.type,role:s.item.role,content:s.item.content,status:s.item.status});this.emit("item_update",m);return}if(s.item.type==="mcp_approval_request"&&s.type==="conversation.item.done"){const d=s.item,m=np.parse({itemId:d.id,type:d.type,serverLabel:d.server_label,name:d.name,arguments:JSON.parse(d.arguments||"{}"),approved:d.approved});this.emit("item_update",m),this.emit("mcp_approval_request",m);return}if(s.item.type==="mcp_tool_call"||s.item.type==="mcp_call"){const d=s.type==="conversation.item.done"?"completed":"in_progress",m=io.parse({itemId:s.item.id,type:s.item.type,status:d,arguments:s.item.arguments,name:s.item.name,output:s.item.output});this.emit("item_update",m),s.type==="conversation.item.done"&&this.emit("mcp_tool_call_completed",m);return}}if(s.type==="response.mcp_call.in_progress"){const d=s;this.sendEvent({type:"conversation.item.retrieve",item_id:d.item_id});return}if(s.type==="mcp_list_tools.in_progress"){const d=s;d.item_id&&this.sendEvent({type:"conversation.item.retrieve",item_id:d.item_id});return}if(s.type==="response.output_item.done"||s.type==="response.output_item.added"){const d=s.item;if(d.type==="function_call"&&d.status==="completed"){const m=ro.parse({itemId:d.id,type:d.type,status:"in_progress",arguments:d.arguments,name:d.name,output:null});this.emit("item_update",m),this.emit("function_call",{id:d.id,type:"function_call",callId:d.call_id??"",arguments:d.arguments??"",name:d.name??""});return}if(d.type==="mcp_tool_call"||d.type==="mcp_call"){const m=io.parse({itemId:d.id,type:d.type,status:s.type==="response.output_item.done"?"completed":"in_progress",arguments:d.arguments,name:d.name,output:d.output});this.emit("item_update",m);return}if(d.type==="message"){const m=so.parse({itemId:s.item.id,type:s.item.type,role:s.item.role,content:s.item.content,status:s.type==="response.output_item.done"?d.status??"completed":d.status??"in_progress"});this.emit("item_update",m);return}}}}_onError(t){this.emit("error",{type:"error",error:t})}_onOpen(){this.emit("connected")}_onClose(){this.emit("disconnected")}sendMessage(t,s,{triggerResponse:r=!0}={}){const i=typeof t=="string"?[{type:"input_text",text:t}]:t.content.map(o=>o.type==="input_image"?{type:"input_image",image_url:o.image,...o.providerData??{}}:o);this.sendEvent({type:"conversation.item.create",item:{type:"message",role:"user",content:i},...s}),r&&this.sendEvent({type:"response.create"})}addImage(t,{triggerResponse:s=!0}={}){this.sendMessage({type:"message",role:"user",content:[{type:"input_image",image:t}]},{},{triggerResponse:s})}_getMergedSessionConfig(t){var i,o,a,u,l,p,d,m,g,_,T,y,h,v,b,N,x,A,D,U,G,L,fe,Y,ce,Me,Ve,Qn;const s=tp(t),r={type:"realtime",instructions:s.instructions,model:s.model??c(this,$t),output_modalities:s.outputModalities??Je.outputModalities,audio:{input:{format:((o=(i=s.audio)==null?void 0:i.input)==null?void 0:o.format)??((u=(a=Je.audio)==null?void 0:a.input)==null?void 0:u.format),noise_reduction:((p=(l=s.audio)==null?void 0:l.input)==null?void 0:p.noiseReduction)??((m=(d=Je.audio)==null?void 0:d.input)==null?void 0:m.noiseReduction),transcription:((_=(g=s.audio)==null?void 0:g.input)==null?void 0:_.transcription)??((y=(T=Je.audio)==null?void 0:T.input)==null?void 0:y.transcription),turn_detection:Dr.buildTurnDetectionConfig((v=(h=s.audio)==null?void 0:h.input)==null?void 0:v.turnDetection)??((N=(b=Je.audio)==null?void 0:b.input)==null?void 0:N.turnDetection)},output:{format:((A=(x=s.audio)==null?void 0:x.output)==null?void 0:A.format)??((U=(D=Je.audio)==null?void 0:D.output)==null?void 0:U.format),voice:((L=(G=s.audio)==null?void 0:G.output)==null?void 0:L.voice)??((Y=(fe=Je.audio)==null?void 0:fe.output)==null?void 0:Y.voice),speed:((Me=(ce=s.audio)==null?void 0:ce.output)==null?void 0:Me.speed)??((Qn=(Ve=Je.audio)==null?void 0:Ve.output)==null?void 0:Qn.speed)}},tool_choice:s.toolChoice??Je.toolChoice,...s.providerData??{}};return s.prompt&&(r.prompt={id:s.prompt.promptId,version:s.prompt.version,variables:s.prompt.variables}),s.tools&&s.tools.length>0&&(r.tools=s.tools.map($s=>({...$s,strict:void 0}))),r}buildSessionPayload(t){return this._getMergedSessionConfig(t)}static buildTurnDetectionConfig(t){if(typeof t>"u")return;const{type:s,createResponse:r,create_response:i,eagerness:o,interruptResponse:a,interrupt_response:u,prefixPaddingMs:l,prefix_padding_ms:p,silenceDurationMs:d,silence_duration_ms:m,threshold:g,idleTimeoutMs:_,idle_timeout_ms:T,...y}=t,h={type:s,create_response:r||i,eagerness:o,interrupt_response:a||u,prefix_padding_ms:l||p,silence_duration_ms:d||m,idle_timeout_ms:_||T,threshold:g,...y};return Object.keys(h).forEach(v=>{h[v]===void 0&&delete h[v]}),Object.keys(h).length>0?h:void 0}set _tracingConfig(t){k(this,xe,t)}_updateTracingConfig(t){var s,r,i;if(typeof c(this,xe)>"u"&&k(this,xe,null),t==="auto"){this.sendEvent({type:"session.update",session:{type:"realtime",tracing:"auto"}});return}if(c(this,xe)!==null&&typeof c(this,xe)!="string"&&typeof t!="string"){Ne.warn("Tracing config is already set, skipping setting it again. This likely happens when you already set a tracing config on session creation.");return}if(t===null){Ne.debug("Disabling tracing for this session. It cannot be turned on for this session from this point on."),this.sendEvent({type:"session.update",session:{type:"realtime",tracing:null}});return}if(c(this,xe)===null||typeof c(this,xe)=="string"){this.sendEvent({type:"session.update",session:{type:"realtime",tracing:t}});return}if((t==null?void 0:t.group_id)!==((s=c(this,xe))==null?void 0:s.group_id)||(t==null?void 0:t.metadata)!==((r=c(this,xe))==null?void 0:r.metadata)||(t==null?void 0:t.workflow_name)!==((i=c(this,xe))==null?void 0:i.workflow_name)){Ne.warn("Mismatch in tracing config. Ignoring the new tracing config. This likely happens when you already set a tracing config on session creation. Current tracing config: %s, new tracing config: %s",JSON.stringify(c(this,xe)),JSON.stringify(t));return}this.sendEvent({type:"session.update",session:{type:"realtime",tracing:t}})}updateSessionConfig(t){const s=this.buildSessionPayload(t);this.sendEvent({type:"session.update",session:s})}sendFunctionCallOutput(t,s,r=!0){this.sendEvent({type:"conversation.item.create",item:{type:"function_call_output",output:s,call_id:t.callId}});try{const i=ro.parse({itemId:t.id,previousItemId:t.previousItemId,type:"function_call",status:"completed",arguments:t.arguments,name:t.name,output:s});this.emit("item_update",i)}catch(i){Ne.error("Error parsing tool call item",i,t)}r&&this.sendEvent({type:"response.create"})}sendAudio(t,{commit:s=!1}={}){this.sendEvent({type:"input_audio_buffer.append",audio:Zd(t)}),s&&this.sendEvent({type:"input_audio_buffer.commit"})}resetHistory(t,s){const{removals:r,additions:i,updates:o}=Jd(t,s),a=new Set(r.map(l=>l.itemId));for(const l of o)a.add(l.itemId);if(a.size>0)for(const l of a)this.sendEvent({type:"conversation.item.delete",item_id:l});const u=[...i,...o];for(const l of u)if(l.type==="message"){const p={type:"message",role:l.role,content:l.content,id:l.itemId};l.role!=="system"&&l.status&&(p.status=l.status),this.sendEvent({type:"conversation.item.create",item:p})}else l.type==="function_call"&&Ne.warn("Function calls cannot be manually added or updated at the moment. Ignoring.")}sendMcpResponse(t,s){this.sendEvent({type:"conversation.item.create",previous_item_id:t.itemId,item:{type:"mcp_approval_response",approval_request_id:t.itemId,approve:s}})}};$t=new WeakMap,Bn=new WeakMap,xe=new WeakMap,Zn=new WeakMap;let Ms=Dr;class sf extends Ms{constructor(t={}){if(typeof RTCPeerConnection>"u")throw new Error("WebRTC is not supported in this environment");super(t);S(this,"options");R(this,qn);R(this,ie,{status:"disconnected",peerConnection:void 0,dataChannel:void 0,callId:void 0});R(this,Jn);R(this,yt,!1);R(this,Gn,!1);this.options=t,k(this,qn,t.baseUrl??"https://api.openai.com/v1/realtime/calls"),k(this,Jn,t.useInsecureApiKey??!1)}get callId(){return c(this,ie).callId}get status(){return c(this,ie).status}get connectionState(){return c(this,ie)}get muted(){return c(this,Gn)}async connect(t){if(c(this,ie).status==="connected")return;c(this,ie).status==="connecting"&&Ne.warn("Realtime connection already in progress. Please await original promise");const s=t.model??this.currentModel;this.currentModel=s;const r=t.url??c(this,qn),i=await this._getApiKey(t),o=typeof i=="string"&&i.startsWith("ek_");if(!c(this,Jn)&&!o)throw new re("Using the WebRTC connection in a browser environment requires an ephemeral client key. If you need to use a regular API key, use the WebSocket transport or set the `useInsecureApiKey` option to true.");return new Promise(async(a,u)=>{var l,p;try{const d={...t.initialSessionConfig||{},model:this.currentModel},m=new URL(r);let g=new RTCPeerConnection;const _=g.createDataChannel("oai-events");let T;const y=A=>{A.onconnectionstatechange=()=>{switch(A.connectionState){case"disconnected":case"failed":case"closed":this.close();break}}};y(g),k(this,ie,{status:"connecting",peerConnection:g,dataChannel:_,callId:T}),this.emit("connection_change",c(this,ie).status),_.addEventListener("open",()=>{k(this,ie,{status:"connected",peerConnection:g,dataChannel:_,callId:T}),this.updateSessionConfig(d),this.emit("connection_change",c(this,ie).status),this._onOpen(),a()}),_.addEventListener("error",A=>{this.close(),this._onError(A),u(A)}),_.addEventListener("message",A=>{this._onMessage(A);const{data:D,isGeneric:U}=Er(A);if(!(!D||U)&&(D.type==="response.created"?k(this,yt,!0):D.type==="response.done"&&k(this,yt,!1),D.type==="session.created")){this._tracingConfig=D.session.tracing;const G=typeof d.tracing>"u"?"auto":d.tracing;this._updateTracingConfig(G)}});const h=this.options.audioElement??document.createElement("audio");h.autoplay=!0,g.ontrack=A=>{h.srcObject=A.streams[0]};const v=this.options.mediaStream??await navigator.mediaDevices.getUserMedia({audio:!0});if(g.addTrack(v.getAudioTracks()[0]),this.options.changePeerConnection){const A=g;g=await this.options.changePeerConnection(g),A!==g&&(A.onconnectionstatechange=null),y(g),k(this,ie,{...c(this,ie),peerConnection:g})}const b=await g.createOffer();if(await g.setLocalDescription(b),!b.sdp)throw new Error("Failed to create offer");const N=await fetch(m,{method:"POST",body:b.sdp,headers:{"Content-Type":"application/sdp",Authorization:`Bearer ${i}`,"X-OpenAI-Agents-SDK":to["X-OpenAI-Agents-SDK"]}});T=(p=(l=N.headers)==null?void 0:l.get("Location"))==null?void 0:p.split("/").pop(),k(this,ie,{...c(this,ie),callId:T});const x={type:"answer",sdp:await N.text()};await g.setRemoteDescription(x)}catch(d){this.close(),this._onError(d),u(d)}})}sendEvent(t){if(!c(this,ie).dataChannel||c(this,ie).dataChannel.readyState!=="open")throw new Error("WebRTC data channel is not connected. Make sure you call `connect()` before sending events.");c(this,ie).dataChannel.send(JSON.stringify(t))}mute(t){k(this,Gn,t),c(this,ie).peerConnection&&c(this,ie).peerConnection.getSenders().forEach(r=>{r.track&&(r.track.enabled=!t)})}_afterAudioDoneEvent(){k(this,yt,!1)}close(){if(c(this,ie).dataChannel&&c(this,ie).dataChannel.close(),c(this,ie).peerConnection){const t=c(this,ie).peerConnection;t.onconnectionstatechange=null,t.getSenders().forEach(s=>{var r;(r=s.track)==null||r.stop()}),t.close()}c(this,ie).status!=="disconnected"&&(k(this,ie,{status:"disconnected",peerConnection:void 0,dataChannel:void 0,callId:void 0}),this.emit("connection_change",c(this,ie).status),this._onClose())}interrupt(){c(this,yt)&&(this.sendEvent({type:"response.cancel"}),k(this,yt,!1)),this.sendEvent({type:"output_audio_buffer.clear"})}}qn=new WeakMap,ie=new WeakMap,Jn=new WeakMap,yt=new WeakMap,Gn=new WeakMap;const rf=globalThis.WebSocket;class af extends Ms{constructor(t={}){super(t);R(this,Bt);R(this,_t);R(this,jt);R(this,Ut);R(this,ye,{status:"disconnected",websocket:void 0});R(this,Vn);R(this,at);R(this,Lt);S(this,"_firstAudioTimestamp");S(this,"_audioLengthMs",0);R(this,zt,!1);R(this,ln);R(this,Hn);k(this,jt,t.url),k(this,Ut,t.url),k(this,Vn,t.useInsecureApiKey??!1),k(this,ln,t.createWebSocket),k(this,Hn,t.skipOpenEventListeners??!1)}getCommonRequestHeaders(){return to}get status(){return c(this,ye).status}get connectionState(){return c(this,ye)}get muted(){return null}get currentItemId(){return c(this,at)}_onAudio(t){this.emit("audio",t)}_afterAudioDoneEvent(){z(this,Bt,Zr).call(this)}async connect(t){const s=t.model??this.currentModel;this.currentModel=s,k(this,_t,await this._getApiKey(t));const r=t.callId;let i;t.url?(i=t.url,k(this,Ut,t.url)):r?i=`wss://api.openai.com/v1/realtime?call_id=${r}`:c(this,Ut)?i=c(this,Ut):i=`wss://api.openai.com/v1/realtime?model=${this.currentModel}`,k(this,jt,i);const o={...t.initialSessionConfig||{},model:this.currentModel};await new Promise((a,u)=>{z(this,Bt,bo).call(this,a,u,o).catch(u)}),await this.updateSessionConfig(o)}sendEvent(t){if(!c(this,ye).websocket)throw new Error("WebSocket is not connected. Make sure you call `connect()` before sending events.");c(this,ye).websocket.send(JSON.stringify(t))}close(){var t;(t=c(this,ye).websocket)==null||t.close(),k(this,at,void 0),this._firstAudioTimestamp=void 0,this._audioLengthMs=0,k(this,Lt,void 0)}mute(t){throw new Error("Mute is not supported for the WebSocket transport. You have to mute the audio input yourself.")}sendAudio(t,s={}){c(this,ye).status==="connected"&&super.sendAudio(t,s)}_cancelResponse(){c(this,zt)&&(this.sendEvent({type:"response.cancel"}),k(this,zt,!1))}_interrupt(t,s=!0){if(t<0)return;s&&this._cancelResponse();const r=this._audioLengthMs??Number.POSITIVE_INFINITY,i=Math.max(0,Math.floor(Math.min(t,r)));this.emit("audio_interrupted"),this.sendEvent({type:"conversation.item.truncate",item_id:c(this,at),content_index:c(this,Lt),audio_end_ms:i})}interrupt(t=!0){if(!c(this,at)||typeof this._firstAudioTimestamp!="number")return;const s=Date.now()-this._firstAudioTimestamp;s>=0&&this._interrupt(s,t),z(this,Bt,Zr).call(this)}}_t=new WeakMap,jt=new WeakMap,Ut=new WeakMap,ye=new WeakMap,Vn=new WeakMap,at=new WeakMap,Lt=new WeakMap,zt=new WeakMap,ln=new WeakMap,Hn=new WeakMap,Bt=new WeakSet,Zr=function(){k(this,at,void 0),this._firstAudioTimestamp=void 0,this._audioLengthMs=0,k(this,Lt,void 0)},bo=async function(t,s,r){if(c(this,ye).websocket){t();return}if(!c(this,_t))throw new re("API key is not set. Please call `connect()` with an API key first.");if(!c(this,_t).startsWith("ek_")&&!c(this,Vn))throw new re("Using the WebSocket connection in a browser environment requires an ephemeral client key. If you have to use a regular API key, set the `useInsecureApiKey` option to true.");let i=null;if(c(this,ln))i=await c(this,ln).call(this,{url:c(this,jt),apiKey:c(this,_t)});else{const a=["realtime","openai-insecure-api-key."+c(this,_t),Hd];i=new rf(c(this,jt),a)}k(this,ye,{status:"connecting",websocket:i}),this.emit("connection_change",c(this,ye).status);const o=()=>{k(this,ye,{status:"connected",websocket:i}),this.emit("connection_change",c(this,ye).status),this._onOpen(),t()};c(this,Hn)===!0?o():i.addEventListener("open",o),i.addEventListener("error",a=>{this._onError(a),k(this,ye,{status:"disconnected",websocket:void 0}),this.emit("connection_change",c(this,ye).status),s(a)}),i.addEventListener("message",a=>{var p,d,m,g,_,T,y;this._onMessage(a);const{data:u,isGeneric:l}=Er(a);if(!(!u||l)){if(u.type==="response.output_audio.delta"){k(this,Lt,u.content_index),k(this,at,u.item_id),this._firstAudioTimestamp===void 0&&(this._firstAudioTimestamp=Date.now(),this._audioLengthMs=0);const h=Bd(u.delta),v=(m=(d=(p=this._rawSessionConfig)==null?void 0:p.audio)==null?void 0:d.output)==null?void 0:m.format;if(v&&typeof v=="object"){const N=v.type;if(N==="audio/pcmu"||N==="audio/pcma")this._audioLengthMs+=h.byteLength/8;else if(N==="audio/pcm"){const x=v.rate??24e3;this._audioLengthMs+=h.byteLength/2/x*1e3}else this._audioLengthMs+=h.byteLength/24/2}else typeof v=="string"?v.startsWith("g711_")?this._audioLengthMs+=h.byteLength/8:this._audioLengthMs+=h.byteLength/24/2:this._audioLengthMs+=h.byteLength/24/2;const b={type:"audio",data:h,responseId:u.response_id};this._onAudio(b)}else if(u.type==="input_audio_buffer.speech_started"){const h=((y=(T=(_=(g=this._rawSessionConfig)==null?void 0:g.audio)==null?void 0:_.input)==null?void 0:T.turn_detection)==null?void 0:y.interrupt_response)??!1;this.interrupt(!h)}else if(u.type==="response.created")k(this,zt,!0);else if(u.type==="response.done")k(this,zt,!1);else if(u.type==="session.created"){this._tracingConfig=u.session.tracing;const h=typeof r.tracing>"u"?"auto":r.tracing;this._updateTracingConfig(h)}}}),i.addEventListener("close",()=>{k(this,ye,{status:"disconnected",websocket:void 0}),this.emit("connection_change",c(this,ye).status),this._onClose()})};const of=Symbol("backgroundResult");function uf(n){return typeof n=="object"&&n!==null&&of in n}function cf(n){return n.type==="function"||n.type==="hosted_tool"&&n.name==="hosted_mcp"}function lf(n){if(n.type==="function")return n;if(n.type==="hosted_tool"&&n.name==="hosted_mcp"){const e=n.providerData.server_url&&n.providerData.server_url.length>0?n.providerData.server_url:void 0;return{type:"mcp",server_label:n.providerData.server_label,server_url:e,headers:n.providerData.headers,allowed_tools:n.providerData.allowed_tools,require_approval:n.providerData.require_approval}}throw new re(`Invalid tool type: ${n}`)}function df(){return JSON.parse(JSON.stringify(Je))}const Mr=class Mr extends ws{constructor(t,s={}){super();R(this,ae);S(this,"initialAgent");S(this,"options");R(this,W);R(this,Z);R(this,dn);R(this,q);R(this,pn,[]);R(this,fn);R(this,Wn,{});R(this,ue,[]);R(this,hn);R(this,mn,{});R(this,Ge,!1);R(this,Kn,new Map);R(this,Zt,[]);R(this,Yn,df());R(this,Xn,!0);this.initialAgent=t,this.options=s,typeof s.transport>"u"&&Gd()||s.transport==="webrtc"?k(this,W,new sf):s.transport==="websocket"||typeof s.transport>"u"?k(this,W,new af):k(this,W,s.transport),k(this,Z,t),k(this,q,new Wt({...s.context??{},history:c(this,ue)})),k(this,pn,(s.outputGuardrails??[]).map(Xd)),k(this,fn,Yd(s.outputGuardrailSettings??{})),k(this,hn,s.historyStoreAudio??!1),k(this,Xn,s.automaticallyTriggerResponseForMcpToolCalls??!0)}get transport(){return c(this,W)}get currentAgent(){return c(this,Z)}get usage(){return c(this,q).usage}get context(){return c(this,q)}get muted(){return c(this,W).muted}get history(){return c(this,ue)}get availableMcpTools(){return c(this,Zt)}async getInitialSessionConfig(t={}){return await z(this,ae,ts).call(this,this.initialAgent),z(this,ae,ns).call(this,{...this.options.config??{},...t??{}})}static async computeInitialSessionConfig(t,s={},r={}){const i=new Mr(t,s);try{return await i.getInitialSessionConfig(r)}finally{i.close()}}async updateAgent(t){return c(this,Z).emit("agent_handoff",c(this,q),t),this.emit("agent_handoff",c(this,q),c(this,Z),t),await z(this,ae,ts).call(this,t),await c(this,W).updateSessionConfig(await z(this,ae,ns).call(this)),t}async connect(t){await z(this,ae,ts).call(this,this.initialAgent),z(this,ae,So).call(this),await c(this,W).connect({apiKey:t.apiKey??this.options.apiKey,model:this.options.model,url:t.url,callId:t.callId,initialSessionConfig:await z(this,ae,ns).call(this,this.options.config)}),k(this,ue,[]),this.emit("history_updated",c(this,ue))}updateHistory(t){let s;typeof t=="function"?s=t(c(this,ue)):s=t,c(this,W).resetHistory(c(this,ue),s)}sendMessage(t,s={}){c(this,W).sendMessage(t,s)}addImage(t,{triggerResponse:s=!0}={}){c(this,W).addImage(t,{triggerResponse:s})}mute(t){c(this,W).mute(t)}close(){k(this,mn,{}),c(this,W).close()}sendAudio(t,s={}){c(this,W).sendAudio(t,s)}interrupt(){c(this,W).interrupt()}async approve(t,s={alwaysApprove:!1}){c(this,q).approveTool(t,s);const r=t.toolName??t.rawItem.name,i=c(this,Z).tools.find(o=>o.name===r);if(i&&i.type==="function"&&t.rawItem.type==="function_call")await z(this,ae,js).call(this,t.rawItem,i);else if(t.rawItem.type==="hosted_tool_call"){s.alwaysApprove&&Ne.warn("Always approving MCP tools is not supported. Use the allowed tools configuration instead.");const o=no(t);c(this,W).sendMcpResponse(o,!0)}else throw new Se(`Tool ${r??"unknown"} not found`)}async reject(t,s={alwaysReject:!1}){c(this,q).rejectTool(t,s);const r=t.toolName??t.rawItem.name,i=c(this,Z).tools.find(o=>o.name===r);if(i&&i.type==="function"&&t.rawItem.type==="function_call")await z(this,ae,js).call(this,t.rawItem,i);else if(t.rawItem.type==="hosted_tool_call"){s.alwaysReject&&Ne.warn("Always rejecting MCP tools is not supported. Use the allowed tools configuration instead.");const o=no(t);c(this,W).sendMcpResponse(o,!1)}else throw new Se(`Tool ${r??"unknown"} not found`)}};W=new WeakMap,Z=new WeakMap,dn=new WeakMap,q=new WeakMap,pn=new WeakMap,fn=new WeakMap,Wn=new WeakMap,ue=new WeakMap,hn=new WeakMap,mn=new WeakMap,Ge=new WeakMap,Kn=new WeakMap,Zt=new WeakMap,Yn=new WeakMap,Xn=new WeakMap,ae=new WeakSet,ts=async function(t){k(this,Z,t);const s=await c(this,Z).getEnabledHandoffs(c(this,q)),r=s.map(u=>u.getHandoffAsFunctionTool()),i=(await c(this,Z).getAllTools(c(this,q))).filter(cf).map(lf),o=typeof c(this,Z).tools<"u"||typeof c(this,Z).mcpServers<"u",a=s.length>0;k(this,dn,o||a?[...i,...r]:void 0),z(this,ae,Jr).call(this)},ns=async function(t={}){const s=t??{},r=this.options.config??{},i=await c(this,Z).getSystemPrompt(c(this,q)),o=g=>{var T;const _=g.audio;return(T=_==null?void 0:_.output)==null?void 0:T.voice},a=this.options.tracingDisabled?null:this.options.workflowName?{workflow_name:this.options.workflowName}:"auto";a!==null&&a!=="auto"?(this.options.groupId&&(a.group_id=this.options.groupId),this.options.traceMetadata&&(a.metadata=this.options.traceMetadata)):(this.options.groupId||this.options.traceMetadata)&&Ne.warn("In order to set traceMetadata or a groupId you need to specify a workflowName.");const u=o(s)??o(r),l=s.voice??r.voice,p=typeof u<"u"?u:typeof l<"u"?l:c(this,Z).voice,m={...{...c(this,Yn)??{},...r,...s},instructions:i,voice:p,model:this.options.model,tools:c(this,dn),tracing:a,prompt:typeof c(this,Z).prompt=="function"?await c(this,Z).prompt(c(this,q),c(this,Z)):c(this,Z).prompt};return k(this,Yn,m),m},wo=async function(t,s){const r=await s.onInvokeHandoff(c(this,q),t.arguments);c(this,Z).emit("agent_handoff",c(this,q),r),this.emit("agent_handoff",c(this,q),c(this,Z),r),await z(this,ae,ts).call(this,r),await c(this,W).updateSessionConfig(await z(this,ae,ns).call(this));const i=Vi(r);return c(this,W).sendFunctionCallOutput(t,i,!0),r},js=async function(t,s){c(this,q).context.history=JSON.parse(JSON.stringify(c(this,ue)));let r=t.arguments;if(s.parameters&&(kt(s.parameters)?r=s.parameters.parse(r):r=JSON.parse(r)),await s.needsApproval(c(this,q),r,t.callId)){const u=this.context.isToolApproved({toolName:s.name,callId:t.callId});if(u===!1){this.emit("agent_tool_start",c(this,q),c(this,Z),s,{toolCall:t}),c(this,Z).emit("agent_tool_start",c(this,q),s,{toolCall:t});const l="Tool execution was not approved.";c(this,W).sendFunctionCallOutput(t,l,!0),this.emit("agent_tool_end",c(this,q),c(this,Z),s,l,{toolCall:t}),c(this,Z).emit("agent_tool_end",c(this,q),s,l,{toolCall:t});return}else if(typeof u>"u"){this.emit("tool_approval_requested",c(this,q),c(this,Z),{type:"function_approval",tool:s,approvalItem:new Ie(t,c(this,Z))});return}}this.emit("agent_tool_start",c(this,q),c(this,Z),s,{toolCall:t}),c(this,Z).emit("agent_tool_start",c(this,q),s,{toolCall:t}),c(this,q).context.history=JSON.parse(JSON.stringify(c(this,ue)));const o=await s.invoke(c(this,q),t.arguments,{toolCall:t});let a;uf(o)?(a=lt(o.content),c(this,W).sendFunctionCallOutput(t,a,!1)):(a=lt(o),c(this,W).sendFunctionCallOutput(t,a,!0)),this.emit("agent_tool_end",c(this,q),c(this,Z),s,a,{toolCall:t}),c(this,Z).emit("agent_tool_end",c(this,q),s,a,{toolCall:t})},Io=async function(t){const s=await c(this,Z).getEnabledHandoffs(c(this,q)),r=new Map(s.map(u=>[u.toolName,u])),i=await c(this,Z).getAllTools(c(this,q)),o=new Map(i.map(u=>[u.name,u])),a=r.get(t.name);if(a)await z(this,ae,wo).call(this,t,a);else{const u=o.get(t.name);if(u&&u.type==="function")await z(this,ae,js).call(this,t,u);else throw new Se(`Tool ${t.name} not found`)}},qr=async function(t,s,r){if(c(this,pn).length===0)return;const i={agent:c(this,Z),agentOutput:t,context:c(this,q)},a=(await Promise.all(c(this,pn).map(u=>u.run(i)))).find(u=>u.output.tripwireTriggered);if(a){if(c(this,mn)[s])return;c(this,mn)[s]=!0;const u=new Ys(`Output guardrail triggered: ${JSON.stringify(a.output.outputInfo)}`,a);this.emit("guardrail_tripped",c(this,q),c(this,Z),u,{itemId:r}),this.interrupt();const l=Qd(a);this.sendMessage(l);return}},So=function(){c(this,W).on("*",r=>{if(this.emit("transport_event",r),r.type==="conversation.item.input_audio_transcription.completed")try{const i=r;k(this,ue,eo(c(this,ue),i,c(this,hn))),c(this,q).context.history=c(this,ue),this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("mcp_tools_listed",({serverLabel:r,tools:i})=>{try{c(this,Kn).set(r,i??[]),z(this,ae,Jr).call(this)}catch(o){this.emit("error",{type:"error",error:o})}}),c(this,W).on("audio",r=>{c(this,Ge)||(k(this,Ge,!0),this.emit("audio_start",c(this,q),c(this,Z))),this.emit("audio",r)}),c(this,W).on("turn_started",()=>{k(this,Ge,!1),this.emit("agent_start",c(this,q),c(this,Z)),c(this,Z).emit("agent_start",c(this,q),c(this,Z))}),c(this,W).on("turn_done",r=>{const i=r.response.output[r.response.output.length-1],o=qd(i)??"",a=(i==null?void 0:i.id)??"";this.emit("agent_end",c(this,q),c(this,Z),o),c(this,Z).emit("agent_end",c(this,q),o),z(this,ae,qr).call(this,o,r.response.id,a)}),c(this,W).on("audio_done",()=>{c(this,Ge)&&k(this,Ge,!1),this.emit("audio_stopped",c(this,q),c(this,Z))});let t=0,s;c(this,W).on("audio_transcript_delta",r=>{try{const i=r.delta,o=r.itemId,a=r.responseId;s!==o&&(s=o,t=0);const l=(c(this,Wn)[o]??"")+i;if(c(this,Wn)[o]=l,c(this,fn).debounceTextLength<0)return;const p=Math.floor(l.length/c(this,fn).debounceTextLength);p>t&&(t=p,z(this,ae,qr).call(this,l,a,o))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("item_update",r=>{try{const i=!c(this,ue).some(o=>o.itemId===r.itemId);if(k(this,ue,eo(c(this,ue),r,c(this,hn))),c(this,q).context.history=c(this,ue),i){const o=c(this,ue).find(a=>a.itemId===r.itemId);o&&this.emit("history_added",o)}this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("item_deleted",r=>{try{k(this,ue,c(this,ue).filter(i=>i.itemId!==r.itemId)),c(this,q).context.history=c(this,ue),this.emit("history_updated",c(this,ue))}catch(i){this.emit("error",{type:"error",error:i})}}),c(this,W).on("function_call",async r=>{try{await z(this,ae,Io).call(this,r)}catch(i){Ne.error("Error handling function call",i),this.emit("error",{type:"error",error:i})}}),c(this,W).on("usage_update",r=>{c(this,q).usage.add(r)}),c(this,W).on("audio_interrupted",()=>{c(this,Ge)&&k(this,Ge,!1),this.emit("audio_interrupted",c(this,q),c(this,Z))}),c(this,W).on("error",r=>{this.emit("error",r)}),c(this,W).on("mcp_tool_call_completed",r=>{this.emit("mcp_tool_call_completed",c(this,q),c(this,Z),r),c(this,Xn)&&c(this,W).sendEvent({type:"response.create"})}),c(this,W).on("mcp_approval_request",r=>{this.emit("tool_approval_requested",c(this,q),c(this,Z),{type:"mcp_approval_request",approvalItem:Wd(c(this,Z),r)})})},Jr=function(){var u;const t=(u=c(this,dn))==null?void 0:u.filter(l=>l.type==="mcp"),s=l=>{const p=l.allowed_tools;if(p){if(Array.isArray(p))return p;if(p&&Array.isArray(p.tool_names))return p.tool_names}},r=new Map;for(const l of t){const p=c(this,Kn).get(l.server_label)??[],d=s(l);for(const m of p)d&&!d.includes(m.name)||r.has(m.name)||r.set(m.name,m)}const i=Array.from(r.values()),o=c(this,Zt);(o.length!==i.length||JSON.stringify(o.map(l=>l.name).sort())!==JSON.stringify(i.map(l=>l.name).sort()))&&(k(this,Zt,i),this.emit("mcp_tools_changed",c(this,Zt)))};let Rr=Mr;class pf{constructor(){this._listeners={}}on(e,t){return this._listeners[e]||(this._listeners[e]=new Set),this._listeners[e].add(t),this}off(e,t){const s=this._listeners[e];return s&&(s.delete(t),s.size===0&&delete this._listeners[e]),this}emit(e,...t){const s=this._listeners[e];if(!s||s.size===0)return!1;for(const r of Array.from(s))try{r(...t)}catch(i){console.error(`BabelbeezClient listener for event "${e}" threw:`,i)}return!0}}const Rt={DEBUG:0,INFO:1,WARN:2,ERROR:3},uo=!0,ff=Rt.INFO;function $(n,e,...t){const s=Rt[n]??Rt.INFO;if(!(s<ff))switch(s){case Rt.DEBUG:console.debug(`[${n}] ${e}`,...t);break;case Rt.INFO:console.info(`[${n}] ${e}`,...t);break;case Rt.WARN:console.warn(`[${n}] ${e}`,...t);break;case Rt.ERROR:{const r=t.find(o=>o instanceof Error),i=e+(r&&r.message?`: ${r.message}`:"");console.error(`[${n}] ${i}`)}break;default:console.log(`[${n}] ${e}`,...t)}}function co(n,e){if(!e)return n;n||(n={});for(const t in e){if(!Object.prototype.hasOwnProperty.call(e,t))continue;const s=e[t],r=n[t];typeof s=="number"?n[t]=(typeof r=="number"?r:0)+s:typeof s=="object"&&s!==null&&!Array.isArray(s)&&((typeof r!="object"||r===null||Array.isArray(r))&&(n[t]={}),co(n[t],s))}return n}const hf=15e3,mf=2e3,gf="https://www.babelbeez.com/initialize-chat";class yf extends pf{constructor(e){if(super(),!e||!e.publicChatbotId)throw new Error("BabelbeezClient: publicChatbotId is required.");this.publicChatbotId=e.publicChatbotId;const t=e.proxyInitializeUrl||gf;this.proxyInitializeUrl=t,this.apiBaseUrl=e.apiBaseUrl||new URL(t).origin,this.agent=null,this.session=null,this.currentSystemSettings=null,this.currentChatbotSettings=null,this.currentSessionId=null,this.currentRagSearchUrl=null,this.sessionStartTime=null,this.accumulatedUsage=null,this.hasEndConversationBeenHandled=!1,this.isTerminating=!1,this.isGoodbyeInProgress=!1,this.isUserSpeaking=!1,this.isAssistantSpeaking=!1,this.isHandoffFormOpen=!1,this.inactivityStage=0,this.inactivityStage1TimeoutId=null,this.inactivityStage2TimeoutId=null,this.shouldScheduleStage2OnNextAssistantSilence=!1,this.pendingGoodbyeResolve=null,this.handoffPromiseResolve=null,this.currentHandoffSummaryText=null,this.heartbeatIntervalId=null,this.heartbeatFrequencySeconds=null,this._lastInitData=null,this._lastAssistantMessageId=null,this._lastAssistantTranscript="",this._currentAssistantTranscript="",this._currentUserTranscript=""}async connect(){if(this.session){$("WARN","BabelbeezClient.connect() called while session already active; ignoring.");return}$("INFO","BabelbeezClient.connect: initializing via proxy and connecting RealtimeSession.");const e=await this._initializeSessionViaProxy();this._lastInitData=e;const{openai_token:t,system_settings:s,chatbot_config:r,session_id:i,heartbeat_frequency_seconds:o}=e;this.currentSystemSettings=s,this.currentChatbotSettings=r,this.currentSessionId=i,this.heartbeatFrequencySeconds=o,this.currentRagSearchUrl=`${this.apiBaseUrl}/api/perform-rag-search`,$("DEBUG","BabelbeezClient: using RAG search URL",this.currentRagSearchUrl),this._resetAccumulatedUsage(),this._resetInactivityState(),this.isUserSpeaking=!1,this.isAssistantSpeaking=!1,this.isTerminating=!1,this.hasEndConversationBeenHandled=!1;try{this.emit("buttonState","loading"),this.agent=this._createVoiceAgent(),this.session=this._createVoiceSession(s,r),await this.session.connect({apiKey:t}),this._attachTransportListeners(),this.sessionStartTime=Date.now(),this.emit("buttonState","active"),this.emit("session:start",{chatbotId:this.publicChatbotId,config:this.currentChatbotSettings}),this._startHeartbeat(),this._resetInactivityState(),$("INFO","BabelbeezClient: Realtime session connected."),setTimeout(()=>{var u;const a=(u=this.currentChatbotSettings)==null?void 0:u.greetingInstructions;if(a)try{this.session&&this.session.transport&&this.session.transport.sendEvent({type:"response.create",response:{conversation:"none",output_modalities:["audio"],instructions:a,tools:[],input:[{type:"message",role:"user",content:[{type:"input_text",text:"The caller has just connected. Greet them now."}]}],metadata:{source:"greeting"}}})}catch(l){$("WARN","BabelbeezClient: failed to trigger greeting response (post-connect).",l)}},0)}catch(a){let u=`Connect Session failed: ${(a==null?void 0:a.message)||"Unknown error"}`,l="connection_error",p="CONNECTION_FAILED";throw a&&(a.name==="NotAllowedError"||a.name==="PermissionDeniedError")?(u="Microphone access denied. Please allow microphone access in your browser settings.",l="microphone_permission_denied",p="MIC_DENIED"):a&&a.name==="NotFoundError"&&(u="No microphone found. Please ensure a microphone is connected and enabled.",l="microphone_not_found",p="MIC_NOT_FOUND"),$("ERROR",u,a),this.emit("buttonState","error"),this.emit("error",{code:p,message:u,severity:"error",fatal:!0}),await this._finalizeSession(l),a}}async disconnect(e="client_disconnect"){if($("INFO",`BabelbeezClient.disconnect called. Reason: ${e}`),e==="user_button_click"){try{this.session&&(await this.session.interrupt(),$("INFO","Session interrupted by user_button_click before goodbye."))}catch(t){$("WARN","Error interrupting session during user_button_click; proceeding with goodbye anyway.",t)}await this._playGoodbyeThenFinalize(e);return}await this._finalizeSession(e)}initializeAudio(){try{const e=window.AudioContext||window.webkitAudioContext;if(!e)return;const t=this._audioCtx||new e;this._audioCtx=t,t.state==="suspended"&&t.resume().catch(()=>{});try{const s=t.currentTime,r=t.createGain();r.gain.setValueAtTime(1e-4,s),r.connect(t.destination);const i=t.createOscillator();i.type="sine",i.frequency.setValueAtTime(440,s),i.connect(r),i.start(s),i.stop(s+.02),i.onended=()=>{try{i.disconnect(),r.disconnect()}catch{}}}catch{}}catch(e){$("WARN","BabelbeezClient.initializeAudio failed",e)}}async sendUserText(e){if(!this.session||this.isTerminating){$("WARN","Cannot send text message; session is not active or is terminating.");return}const t=(e??"").trim();if(!t){$("DEBUG","sendUserText called with empty/whitespace text; ignoring.");return}if(this.isAssistantSpeaking)try{await this.session.interrupt()}catch(s){$("WARN","Failed to interrupt assistant before sending user text.",s)}this._resetInactivityState();try{await this.session.sendMessage(t),this.emit("transcript",{role:"user",text:t,isFinal:!0})}catch(s){$("ERROR","Failed to send user text message",s)}}async handleHandoffSubmit(e){if(!this.isHandoffFormOpen){$("WARN","handleHandoffSubmit called but no handoff form is open.");return}const{email:t,consent:s}=e||{},r=this.currentHandoffSummaryText||"Summary not available.";try{const i=`${this.apiBaseUrl}/handoff/request`,o=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({session_id:this.currentSessionId,email:t,consent:s,summary:r})});if(o.ok)$("INFO","Handoff request submitted successfully.");else{let a=`HTTP ${o.status}`;try{const u=await o.json();u&&u.detail&&(a=u.detail)}catch{}$("ERROR",`Failed to submit handoff request: ${a}`),this.emit("error",{code:"HANDOFF_FAILED",message:"Failed to submit handoff request. Please try again later.",severity:"error",fatal:!1})}}catch(i){$("ERROR","Network or unexpected error submitting handoff request.",i),this.emit("error",{code:"HANDOFF_FAILED",message:"Network error submitting handoff request. Please try again later.",severity:"error",fatal:!1})}finally{this.isHandoffFormOpen=!1,this._resetInactivityState(),this.isTerminating||this._setSessionMuted(!1,"handoff_form"),this.emit("handoff:hide",{outcome:"email_submitted"}),this.handoffPromiseResolve&&(this.handoffPromiseResolve("email_submitted"),this.handoffPromiseResolve=null)}try{this.session&&await this.session.sendMessage("The user has submitted their contact details. Confirm that their request was received and that a team member will follow up. See if there's anything else you can help them with in the meantime.")}catch(i){$("WARN","Failed to send post-handoff confirmation message.",i)}}async handleHandoffCancel(e={}){const{viaWhatsapp:t}=e;if(!this.isHandoffFormOpen){$("WARN","handleHandoffCancel called but no handoff form is open.");return}this.isHandoffFormOpen=!1,this._resetInactivityState(),this.isTerminating||this._setSessionMuted(!1,"handoff_form");const s=t?"whatsapp_submitted":"cancelled";if(this.emit("handoff:hide",{outcome:s}),this.handoffPromiseResolve&&(this.handoffPromiseResolve(s),this.handoffPromiseResolve=null),t){await this._playGoodbyeThenFinalize("handoff_whatsapp");return}try{this.session&&await this.session.sendMessage("The user changed their mind and no longer wishes to fill out the form right now. See if there's anything else you can help them with.")}catch(r){$("WARN","Failed to send handoff cancellation message.",r)}}async _initializeSessionViaProxy(){$("INFO","BabelbeezClient: Initializing session via proxy /initialize-chat...");const e=typeof navigator<"u"&&(navigator.language||navigator.userLanguage)||null,t=await fetch(this.proxyInitializeUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({public_chatbot_id:this.publicChatbotId,browser_language:e})});if(!t.ok){let r=`HTTP error ${t.status}: ${t.statusText}`;try{const i=await t.json();i&&i.detail&&(r=i.detail)}catch{}throw $("ERROR","BabelbeezClient: /initialize-chat failed",r),new Error(r)}const s=await t.json();if(!s.session_id||!s.openai_token||!s.system_settings||!s.chatbot_config||s.heartbeat_frequency_seconds===void 0)throw $("ERROR","BabelbeezClient: Invalid response structure from /initialize-chat.",s?{...s,openai_token:"***"}:null),new Error("Incomplete session details received from server.");return $("INFO","BabelbeezClient: Session initialized via proxy.",{session_id:s.session_id,heartbeat_frequency_seconds:s.heartbeat_frequency_seconds}),s}_resetAccumulatedUsage(){this.accumulatedUsage={total_tokens:0,input_tokens:0,output_tokens:0,input_token_details:{cached_tokens:0,text_tokens:0,audio_tokens:0,cached_tokens_details:{text_tokens:0,audio_tokens:0}},output_token_details:{text_tokens:0,audio_tokens:0}},$("DEBUG","BabelbeezClient: accumulated token usage reset.")}_setSessionMuted(e,t=""){try{this.session&&this.session.transport&&typeof this.session.transport.mute=="function"&&(this.session.transport.mute(e),$("DEBUG",`Session ${e?"muted":"unmuted"}${t?` (${t})`:""}.`))}catch{}}_clearInactivityTimers(){this.inactivityStage1TimeoutId&&(clearTimeout(this.inactivityStage1TimeoutId),this.inactivityStage1TimeoutId=null),this.inactivityStage2TimeoutId&&(clearTimeout(this.inactivityStage2TimeoutId),this.inactivityStage2TimeoutId=null)}_resetInactivityState(){this.inactivityStage=0,this.shouldScheduleStage2OnNextAssistantSilence=!1,this._clearInactivityTimers()}async _sendInactivityEnquiry(){var t,s;const e=(((t=this.currentChatbotSettings)==null?void 0:t.inactivityTimeoutMs)||0)/1e3;$("INFO",`User inactive for ${e}s. Sending enquiry.`),this.shouldScheduleStage2OnNextAssistantSilence=!0;try{(s=this.currentSystemSettings)!=null&&s.inactivityInstructions&&this.session&&await this.session.sendMessage(this.currentSystemSettings.inactivityInstructions)}catch(r){$("ERROR","Failed to send inactivity enquiry; ending session.",r),await this._finalizeSession("inactivity_enquiry_failed")}}async _playGoodbyeThenFinalize(e){var o,a;if(this.isTerminating){await this._finalizeSession(e);return}this._clearInactivityTimers();const t=(a=(o=this.currentSystemSettings)==null?void 0:o.goodbyeInstructions)==null?void 0:a.trim();if(!this.session||!t){$("INFO","No goodbyeInstructions configured or no active session; finalizing immediately."),await this._finalizeSession(e);return}this.isGoodbyeInProgress=!0,$("INFO","Playing goodbye message before finalizing session.");const s=new Promise(u=>{this.pendingGoodbyeResolve=u});try{this._setSessionMuted(!0,"goodbye"),await this.session.sendMessage(t)}catch(u){$("WARN","Failed to send goodbye message; finalizing immediately.",u),this.pendingGoodbyeResolve=null,this._setSessionMuted(!1,"goodbye"),this.isGoodbyeInProgress=!1,await this._finalizeSession(e);return}const r=15e3,i=new Promise(u=>setTimeout(u,r));await Promise.race([s,i]),this.pendingGoodbyeResolve=null,this._setSessionMuted(!1,"goodbye"),this.isGoodbyeInProgress=!1,await this._finalizeSession(e)}_createVoiceAgent(){var u,l,p,d;const e=(u=this.currentSystemSettings)!=null&&u.system_prompt?`${this.currentSystemSettings.system_prompt}
|
|
13
13
|
|
|
14
|
-
${((l=this.currentChatbotSettings)==null?void 0:l.instructions)||""}`.trim():((p=this.currentChatbotSettings)==null?void 0:p.instructions)||"",t=this,s=Ht({name:"perform_rag_search",description:((d=this.currentSystemSettings)==null?void 0:d.rag_search_description)||"Searches the knowledge base for relevant context.",parameters:w({query:f()}),async execute({query:m}){if($("INFO",`Tool perform_rag_search called with query: "${m}"`),t._resetInactivityState(),!t.currentRagSearchUrl||!t.publicChatbotId)return $("ERROR","RAG search URL or publicChatbotId not configured; returning fallback context."),"Knowledge search is temporarily unavailable.";const g=t.isAssistantSpeaking;t.isAssistantSpeaking=!0,t.emit("buttonState","rag-retrieval");try{const _=await fetch(t.currentRagSearchUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:m,public_chatbot_id:t.publicChatbotId})});if(!_.ok){let h=`RAG search failed: ${_.status} ${_.statusText}`;try{const v=await _.json();v&&v.detail&&(h=v.detail)}catch{}return $("ERROR",h),"Knowledge search failed; please answer based on your existing knowledge."}const y=(await _.json()).context||"";return $("INFO",`RAG search succeeded. Context length: ${y.length}`),y||"No additional knowledge was found."}catch(_){return $("ERROR","Network or unexpected error during RAG search.",_),"Knowledge search failed due to a network error."}finally{t.isAssistantSpeaking=g,t.emit("buttonState","active")}}}),r=Ht({name:"request_human_handoff",description:"Escalate to a human staff member via contact form. Provide a concise summary_text.",parameters:w({summary_text:f(),announcement:f()}),async execute({summary_text:m,announcement:g}){var h;$("INFO","Tool request_human_handoff called."),t._resetInactivityState();const _=g||"Please fill out the form so that I can connect you to a staff member to follow up";try{t.session&&await t.session.sendMessage(_)}catch(v){$("WARN","Failed to send handoff announcement message.",v)}t.isHandoffFormOpen=!0,t._setSessionMuted(!0,"handoff_form");let T=null;const y=(h=t.currentChatbotSettings)==null?void 0:h.handoff_whatsapp_number;if(y){const v=String(y).replace(/\D+/g,"");v&&(T=`https://wa.me/${v}?text=${encodeURIComponent(m||"Summary not available.")}`)}return t.currentHandoffSummaryText=m||"Summary not available.",t.emit("handoff:show",{summaryText:t.currentHandoffSummaryText,waLink:T}),await new Promise(v=>{t.handoffPromiseResolve=v}).then(v=>v==="whatsapp_submitted"?"User chose WhatsApp handoff.":v==="email_submitted"?"Handoff request submitted successfully.":"Handoff flow completed or cancelled by the user.")}}),i=Ht({name:"end_conversation",description:"End the conversation when the user clearly wants to stop. The model should call this tool instead of saying goodbye itself.",parameters:w({}),async execute(){return $("INFO","Tool end_conversation called by AI."),t._resetInactivityState(),t.hasEndConversationBeenHandled?($("DEBUG","end_conversation already handled; ignoring subsequent call."),"Conversation is already ending."):(t.hasEndConversationBeenHandled=!0,(async()=>{try{t.session&&(await t.session.interrupt(),$("INFO","Session interrupted by AI end_conversation before goodbye."))}catch(m){$("WARN","Error interrupting session during AI end_conversation; proceeding anyway.",m)}await t._playGoodbyeThenFinalize("ai_end_conversation_tool")})(),"Conversation ended.")}}),o=[s,r,i];return new Kd({name:"Assistant",instructions:e,tools:o})}_createVoiceSession(e,t){const s=e==null?void 0:e.model;if(!s)throw new Error("Missing systemSettings.model for RealtimeSession.");const r={type:t!=null&&t.semanticVadEnabled?"semantic_vad":"server_vad",eagerness:(t==null?void 0:t.eagerness)||"medium",createResponse:!0,interruptResponse:!0};return new Rr(this.agent,{model:s,config:{inputAudioFormat:"pcm16",outputAudioFormat:"pcm16",inputAudioTranscription:{model:"gpt-4o-mini-transcribe"},turnDetection:r}})}_attachTransportListeners(){this.session&&(this.session.on("history_updated",e=>{try{const t=Array.isArray(e)?e:this.session.history||[],s=t[t.length-1];if(!s||s.type!=="message"||s.role!=="assistant")return;const r=s.id||null;r&&r!==this._lastAssistantMessageId&&(this._lastAssistantMessageId=r,this._lastAssistantTranscript="");const i=s.content||[],o=[];for(const p of i)if(p&&p.type==="output_audio"&&typeof p.transcript=="string"){const d=p.transcript.trim();d&&o.push(d)}const a=o.join(" ").trim();if(!a)return;const u=this._lastAssistantTranscript||"";let l=a;if(u&&a.startsWith(u)&&(l=a.slice(u.length)),!l)return;this._lastAssistantTranscript=a,this.emit("transcript",{role:"agent",text:l,isFinal:!1})}catch{}}),this.session.transport&&(this.session.transport.on("*",e=>{var t,s;if(e){if(e.type&&typeof e.type=="string"&&e.type.startsWith("response."),e.type==="response.done"&&((t=e.response)!=null&&t.usage)&&(this.accumulatedUsage=co(this.accumulatedUsage,e.response.usage),$("DEBUG","Accumulated token usage from response.done.",this.accumulatedUsage)),e.type==="input_audio_buffer.speech_started"){this.isUserSpeaking=!0,this._currentUserTranscript="",this._resetInactivityState();return}if(e.type==="conversation.item.input_audio_transcription.delta"){if(this.isUserSpeaking=!0,this._resetInactivityState(),typeof e.delta=="string"&&e.delta){this._currentUserTranscript+=e.delta;const r=this._currentUserTranscript;this.emit("transcript",{role:"user",text:r,isFinal:!1})}return}if(e.type==="input_audio_buffer.speech_stopped"||e.type==="conversation.item.input_audio_transcription.completed"||e.type==="conversation.item.input_audio_transcription.failed"){this.isUserSpeaking=!1,e.type==="conversation.item.input_audio_transcription.completed"&&this._currentUserTranscript&&this.emit("transcript",{role:"user",text:this._currentUserTranscript,isFinal:!0}),this._currentUserTranscript="";return}if(e.type==="output_audio_buffer.started"){this.isAssistantSpeaking=!0,this._clearInactivityTimers(),this._currentAssistantTranscript="",this.emit("buttonState","speaking");return}if(e.type==="output_audio_buffer.stopped"||e.type==="output_audio_buffer.cleared"){this.isAssistantSpeaking=!1;const r=this._lastAssistantTranscript||this._currentAssistantTranscript||"";if(r&&this.emit("transcript",{role:"agent",text:r,isFinal:!0}),this._lastAssistantTranscript="",this._currentAssistantTranscript=""
|
|
14
|
+
${((l=this.currentChatbotSettings)==null?void 0:l.instructions)||""}`.trim():((p=this.currentChatbotSettings)==null?void 0:p.instructions)||"",t=this,s=Ht({name:"perform_rag_search",description:((d=this.currentSystemSettings)==null?void 0:d.rag_search_description)||"Searches the knowledge base for relevant context.",parameters:w({query:f()}),async execute({query:m}){if($("INFO",`Tool perform_rag_search called with query: "${m}"`),t._resetInactivityState(),!t.currentRagSearchUrl||!t.publicChatbotId)return $("ERROR","RAG search URL or publicChatbotId not configured; returning fallback context."),"Knowledge search is temporarily unavailable.";const g=t.isAssistantSpeaking;t.isAssistantSpeaking=!0,t.emit("buttonState","rag-retrieval");try{const _=await fetch(t.currentRagSearchUrl,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({query:m,public_chatbot_id:t.publicChatbotId})});if(!_.ok){let h=`RAG search failed: ${_.status} ${_.statusText}`;try{const v=await _.json();v&&v.detail&&(h=v.detail)}catch{}return $("ERROR",h),"Knowledge search failed; please answer based on your existing knowledge."}const y=(await _.json()).context||"";return $("INFO",`RAG search succeeded. Context length: ${y.length}`),y||"No additional knowledge was found."}catch(_){return $("ERROR","Network or unexpected error during RAG search.",_),"Knowledge search failed due to a network error."}finally{t.isAssistantSpeaking=g,t.emit("buttonState","active")}}}),r=Ht({name:"request_human_handoff",description:"Escalate to a human staff member via contact form. Provide a concise summary_text.",parameters:w({summary_text:f(),announcement:f()}),async execute({summary_text:m,announcement:g}){var h;$("INFO","Tool request_human_handoff called."),t._resetInactivityState();const _=g||"Please fill out the form so that I can connect you to a staff member to follow up";try{t.session&&await t.session.sendMessage(_)}catch(v){$("WARN","Failed to send handoff announcement message.",v)}t.isHandoffFormOpen=!0,t._setSessionMuted(!0,"handoff_form");let T=null;const y=(h=t.currentChatbotSettings)==null?void 0:h.handoff_whatsapp_number;if(y){const v=String(y).replace(/\D+/g,"");v&&(T=`https://wa.me/${v}?text=${encodeURIComponent(m||"Summary not available.")}`)}return t.currentHandoffSummaryText=m||"Summary not available.",t.emit("handoff:show",{summaryText:t.currentHandoffSummaryText,waLink:T}),await new Promise(v=>{t.handoffPromiseResolve=v}).then(v=>v==="whatsapp_submitted"?"User chose WhatsApp handoff.":v==="email_submitted"?"Handoff request submitted successfully.":"Handoff flow completed or cancelled by the user.")}}),i=Ht({name:"end_conversation",description:"End the conversation when the user clearly wants to stop. The model should call this tool instead of saying goodbye itself.",parameters:w({}),async execute(){return $("INFO","Tool end_conversation called by AI."),t._resetInactivityState(),t.hasEndConversationBeenHandled?($("DEBUG","end_conversation already handled; ignoring subsequent call."),"Conversation is already ending."):(t.hasEndConversationBeenHandled=!0,(async()=>{try{t.session&&(await t.session.interrupt(),$("INFO","Session interrupted by AI end_conversation before goodbye."))}catch(m){$("WARN","Error interrupting session during AI end_conversation; proceeding anyway.",m)}await t._playGoodbyeThenFinalize("ai_end_conversation_tool")})(),"Conversation ended.")}}),o=[s,r,i];return new Kd({name:"Assistant",instructions:e,tools:o})}_createVoiceSession(e,t){const s=e==null?void 0:e.model;if(!s)throw new Error("Missing systemSettings.model for RealtimeSession.");const r={type:t!=null&&t.semanticVadEnabled?"semantic_vad":"server_vad",eagerness:(t==null?void 0:t.eagerness)||"medium",createResponse:!0,interruptResponse:!0};return new Rr(this.agent,{model:s,config:{inputAudioFormat:"pcm16",outputAudioFormat:"pcm16",inputAudioTranscription:{model:"gpt-4o-mini-transcribe"},turnDetection:r}})}_attachTransportListeners(){this.session&&(this.session.on("history_updated",e=>{try{const t=Array.isArray(e)?e:this.session.history||[],s=t[t.length-1];if(!s||s.type!=="message"||s.role!=="assistant")return;const r=s.id||null;r&&r!==this._lastAssistantMessageId&&(this._lastAssistantMessageId=r,this._lastAssistantTranscript="");const i=s.content||[],o=[];for(const p of i)if(p&&p.type==="output_audio"&&typeof p.transcript=="string"){const d=p.transcript.trim();d&&o.push(d)}const a=o.join(" ").trim();if(!a)return;const u=this._lastAssistantTranscript||"";let l=a;if(u&&a.startsWith(u)&&(l=a.slice(u.length)),!l)return;this._lastAssistantTranscript=a,this.emit("transcript",{role:"agent",text:l,isFinal:!1})}catch{}}),this.session.transport&&(this.session.transport.on("*",e=>{var t,s;if(e){if(e.type&&typeof e.type=="string"&&e.type.startsWith("response."),e.type==="response.done"&&((t=e.response)!=null&&t.usage)&&(this.accumulatedUsage=co(this.accumulatedUsage,e.response.usage),$("DEBUG","Accumulated token usage from response.done.",this.accumulatedUsage)),e.type==="input_audio_buffer.speech_started"){this.isUserSpeaking=!0,this._currentUserTranscript="",this._resetInactivityState();return}if(e.type==="conversation.item.input_audio_transcription.delta"){if(this.isUserSpeaking=!0,this._resetInactivityState(),typeof e.delta=="string"&&e.delta){this._currentUserTranscript+=e.delta;const r=this._currentUserTranscript;this.emit("transcript",{role:"user",text:r,isFinal:!1})}return}if(e.type==="input_audio_buffer.speech_stopped"||e.type==="conversation.item.input_audio_transcription.completed"||e.type==="conversation.item.input_audio_transcription.failed"){this.isUserSpeaking=!1,e.type==="conversation.item.input_audio_transcription.completed"&&this._currentUserTranscript&&this.emit("transcript",{role:"user",text:this._currentUserTranscript,isFinal:!0}),this._currentUserTranscript="";return}if(e.type==="output_audio_buffer.started"){this.isAssistantSpeaking=!0,this._clearInactivityTimers(),this._currentAssistantTranscript="",this.isTerminating||this.emit("buttonState","speaking");return}if(e.type==="output_audio_buffer.stopped"||e.type==="output_audio_buffer.cleared"){this.isAssistantSpeaking=!1;const r=this._lastAssistantTranscript||this._currentAssistantTranscript||"";if(r&&this.emit("transcript",{role:"agent",text:r,isFinal:!0}),this._lastAssistantTranscript="",this._currentAssistantTranscript="",!this.isGoodbyeInProgress&&!this.isTerminating&&this.emit("buttonState","active"),this.pendingGoodbyeResolve&&(this.pendingGoodbyeResolve(),this.pendingGoodbyeResolve=null),!this.isTerminating&&this.currentChatbotSettings&&!this.isHandoffFormOpen){const i=((s=this.currentChatbotSettings)==null?void 0:s.inactivityTimeoutMs)||0;if(this.inactivityStage===0&&i>0){this._clearInactivityTimers();const o=i+mf;this.inactivityStage1TimeoutId=setTimeout(()=>{this.inactivityStage=1,$("INFO","[INACTIVITY] Stage 1 threshold reached; sending enquiry."),this._sendInactivityEnquiry()},o)}else this.inactivityStage===1&&this.shouldScheduleStage2OnNextAssistantSilence&&(this._clearInactivityTimers(),this.inactivityStage2TimeoutId=setTimeout(()=>{$("INFO","[INACTIVITY] Stage 2 threshold reached; auto-ending session with goodbye."),this._playGoodbyeThenFinalize("inactivity_timeout")},hf),this.shouldScheduleStage2OnNextAssistantSilence=!1)}return}}}),this.session.transport.on("audio_transcript_delta",e=>{const t=e==null?void 0:e.delta,s=(t==null?void 0:t.delta)||(t==null?void 0:t.transcript);typeof s=="string"&&s&&($("INFO","Transcript event",{source:"agent_audio_delta",role:"agent",len:s.length}),this._currentAssistantTranscript+=s,this.emit("transcript",{role:"agent",text:s,isFinal:!1}))})))}_buildRawHistoryFromSession(){var e;try{const t=((e=this.session)==null?void 0:e.history)||[],s=[];for(const r of t){if(!r||r.type!=="message"||r.role!=="user"&&r.role!=="assistant")continue;const i=r.role==="user"?"User":"Assistant",o=[],a=r.content||[];for(const l of a)if((l.type==="input_audio"||l.type==="output_audio")&&typeof l.transcript=="string"){const p=l.transcript.trim();p&&o.push(p)}const u=o.join(" ").trim();u&&s.push(`${i}: ${u}`)}return s.join(`
|
|
15
15
|
`)}catch(t){return $("ERROR","Failed to build raw_history from session history.",t),""}}_startHeartbeat(){if(this.heartbeatIntervalId){$("WARN","BabelbeezClient: Heartbeat already running.");return}!this.heartbeatFrequencySeconds&&this._lastInitData&&this._lastInitData.heartbeat_frequency_seconds!=null&&(this.heartbeatFrequencySeconds=this._lastInitData.heartbeat_frequency_seconds);const e=this.heartbeatFrequencySeconds;if(!e||e<=0){$("WARN","BabelbeezClient: Cannot start heartbeat, invalid or missing frequency.",e);return}$("INFO",`BabelbeezClient: Starting heartbeat every ${e} seconds.`);const t=()=>this._sendHeartbeat();this.heartbeatIntervalId=setInterval(t,e*1e3)}_stopHeartbeat(){this.heartbeatIntervalId&&(clearInterval(this.heartbeatIntervalId),this.heartbeatIntervalId=null,$("INFO","BabelbeezClient: Heartbeat stopped."))}async _sendHeartbeat(){if(!this.currentSessionId){$("WARN","BabelbeezClient: Cannot send heartbeat, no active session ID."),this._stopHeartbeat();return}try{const e=this.proxyInitializeUrl.replace("/initialize-chat","/heartbeat");$("DEBUG","BabelbeezClient: Sending heartbeat",{session_id:this.currentSessionId,heartbeatUrl:e});const t={session_id:this.currentSessionId};(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok}catch(e){$("ERROR","BabelbeezClient: Error sending heartbeat.",e)}}async _finalizeSession(e){if(this.isTerminating){$("DEBUG",`BabelbeezClient._finalizeSession called while already terminating (reason: ${e}).`);return}this.isTerminating=!0,this._clearInactivityTimers(),this._stopHeartbeat();const t=this._buildRawHistoryFromSession();if(this.accumulatedUsage){const r=this.accumulatedUsage.input_tokens||0,i=this.accumulatedUsage.output_tokens||0,o=r+i;(!this.accumulatedUsage.total_tokens||this.accumulatedUsage.total_tokens<o)&&(this.accumulatedUsage.total_tokens=o)}$("INFO",`Finalizing session (reason: ${e}). raw_history length=${t.length}`);const s={usage:this.accumulatedUsage,client_reason:e,raw_history:t};this.emit("buttonState","idle"),this.emit("session:end",{reason:e});try{if(this.currentSessionId){const r=this.proxyInitializeUrl.replace("/initialize-chat","/end-chat"),i={session_id:this.currentSessionId,token_usage:s.usage||void 0,raw_history:s.raw_history||void 0,client_reason:s.client_reason||void 0};$("DEBUG","BabelbeezClient: Sending /end-chat beacon",{...i,raw_history:i.raw_history?`[len=${i.raw_history.length}]`:void 0}),await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0})}}catch(r){$("ERROR","BabelbeezClient: Error sending /end-chat beacon.",r)}try{this.session&&(await this.session.close(),$("DEBUG","BabelbeezClient: RealtimeSession closed."))}catch(r){$("WARN","BabelbeezClient: Error closing RealtimeSession.",r)}this.session=null,this.agent=null,this.currentSystemSettings=null,this.currentChatbotSettings=null,this.currentSessionId=null,this.currentRagSearchUrl=null,this.sessionStartTime=null,this._resetInactivityState(),this.isUserSpeaking=!1,this.isAssistantSpeaking=!1,this._resetAccumulatedUsage(),this.hasEndConversationBeenHandled=!1,this.isTerminating=!1}}ee.BabelbeezClient=yf,Object.defineProperty(ee,Symbol.toStringTag,{value:"Module"})});
|