11import { endpoints } from '$lib/services/api-endpoints.js' ;
22import { replaceUrl } from '$lib/helpers/http' ;
33import axios from 'axios' ;
4+ import { json } from '@sveltejs/kit' ;
45
56export const llmRealtime = {
67 /** @type {RTCPeerConnection } */
78 pc : new RTCPeerConnection ( ) ,
8- /** @param {string } agentId */
9- async start ( agentId ) {
9+ /**
10+ * @param {string } agentId
11+ * @param {function } onMessageReceived
12+ */
13+ async start ( agentId , onMessageReceived ) {
1014 const session = await initRealtimeSession ( agentId ) ;
1115 const EPHEMERAL_KEY = session . client_secret . value ;
1216
@@ -25,10 +29,13 @@ export const llmRealtime = {
2529
2630 // Set up data channel for sending and receiving events
2731 const dc = this . pc . createDataChannel ( "oai-events" ) ;
28- dc . addEventListener ( "message" , ( e ) => {
32+ dc . addEventListener ( "message" , async ( e ) => {
2933 // Realtime server events appear here!
3034 var data = JSON . parse ( e . data ) ;
3135 console . log ( data ) ;
36+ if ( data . type === "response.done" && data . response . status == "completed" ) {
37+ await handleServerEvents ( agentId , data , dc ) ;
38+ }
3239 } ) ;
3340
3441 // Start the session using the Session Description Protocol (SDP)
@@ -51,6 +58,20 @@ export const llmRealtime = {
5158 sdp : await sdpResponse . text ( ) ,
5259 } ;
5360 await this . pc . setRemoteDescription ( answer ) ;
61+
62+ // send on data channel connect is open
63+ dc . onopen = ( ) => {
64+ console . log ( "Data channel is open" ) ;
65+ /*const responseCreate = {
66+ type: "response.create",
67+ response: {
68+ modalities: ["audio", "text"],
69+ instructions: "Write a haiku about code",
70+ },
71+ };
72+ dc.send(JSON.stringify(responseCreate));*/
73+ } ;
74+
5475 } ,
5576
5677 stop ( ) {
@@ -68,4 +89,58 @@ export async function initRealtimeSession(agentId) {
6889 let url = replaceUrl ( endpoints . agentInitRealtimeSessionUrl , { agentId : agentId } ) ;
6990 var response = await axios . get ( url ) ;
7091 return response . data ;
92+ }
93+
94+ /**
95+ * Handle server events
96+ * @param {string } agentId
97+ * @param {Object } data
98+ * @param {RTCDataChannel } dc
99+ */
100+ async function handleServerEvents ( agentId , data , dc ) {
101+ // for each response.output, do something with it
102+ data . response . output . forEach ( async completion => {
103+ if ( completion . type === "function_call" ) {
104+ const result = await callFunction ( agentId , completion . name , completion . arguments ) ;
105+ console . log ( result ) ;
106+
107+ // send the result back to the model
108+ const conversationItemCreation = {
109+ "type" : "conversation.item.create" ,
110+ "item" : {
111+ "call_id" : completion . call_id ,
112+ "type" : "function_call_output" ,
113+ "output" : result
114+ }
115+ } ;
116+ dc . send ( JSON . stringify ( conversationItemCreation ) ) ;
117+
118+ /*const conversationItemResponse = {
119+ "type": "response.create",
120+ "response": {
121+ "modalities": ["text", "audio"],
122+ "instructions": "Please continue the conversation based on the function output.",
123+ }
124+ };
125+ dc.send(JSON.stringify(conversationItemResponse));*/
126+ }
127+ } ) ;
128+ }
129+
130+ /**
131+ * Execute agent function call
132+ * @param {string } agentId
133+ * @param {string } functionName
134+ * @param {string } args
135+ * @returns {Promise<string> }
136+ */
137+ async function callFunction ( agentId , functionName , args ) {
138+ let url = replaceUrl ( endpoints . agentFunctionCallUrl , {
139+ agentId : agentId ,
140+ functionName : functionName
141+ } ) ;
142+
143+ const functionArgs = JSON . parse ( args ) ;
144+ var response = await axios . post ( url , functionArgs ) ;
145+ return JSON . stringify ( response . data ) ;
71146}
0 commit comments