@@ -18,14 +18,15 @@ const openai = new OpenAI({
1818
1919let textInputBox = document . getElementById ( 'text-input-box' )
2020let chatHistory = document . getElementById ( 'chat-history' )
21- const defaultSystemPrompt = "You are an event manager AI who creates inspiring events with interesting emoji-choices and powerful, fitting writing." ;
21+ const defaultSystemPrompt = "You are an event manager AI who creates inspiring events with inspired emoji-choices and powerful, fitting writing." ;
2222const GPT4o = "gpt-4o" ;
2323const GPT4 = "gpt-4-turbo-preview" ;
2424const GPT3_5 = 'gpt-3.5-turbo-0125' ;
2525
2626const CHAT_WINDOW_STATES = {
2727 CREATE : 'Create' ,
2828 SPECIFY : 'Specify' ,
29+ ACCEPT : 'Accept' ,
2930} ;
3031
3132class ChatWindow {
@@ -49,9 +50,6 @@ class ChatWindow {
4950 }
5051
5152 setState ( state ) {
52- if ( state != CHAT_WINDOW_STATES . CREATE && state != CHAT_WINDOW_STATES . SPECIFY ) {
53- throw new Error ( `State '${ model } ' does not exist.` )
54- }
5553 this . #STATE = state ;
5654 }
5755
@@ -100,7 +98,7 @@ class ChatWindow {
10098 chatHistory . scrollTo ( { top : chatHistory . scrollHeight } ) ;
10199 }
102100
103- async extractAndParseJSON ( jsonString ) {
101+ async # extractAndParseJSON( jsonString ) {
104102 const normalizedJSONString = this . #extractJSONFromString( jsonString ) ;
105103 return await this . #parseJSONToObject( normalizedJSONString ) ;
106104 }
@@ -173,16 +171,65 @@ class ChatWindow {
173171 this . #messages = [ ] ;
174172 }
175173
176- async sendUserMessage ( prompt , prettyPrinted = "" ) {
174+ #makeNewEventsPrompt( prompt ) {
175+ let today = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
176+ let time = new Date ( ) . toTimeString ( ) . split ( ' ' ) [ 0 ] ;
177+ let day = new Date ( ) . toLocaleString ( 'en-us' , { weekday : 'long' } ) ;
178+ let newEventsPrompt = `Given the following current date and time: ${ day } , ${ today } T${ time } :00 and planning prompt: '${ prompt } ', format the prompt's contents as JSON objects with the following keys: summary, description (brief, beautiful and helpful), start, end (don't write timezone.), allDay (boolean) and location (if provided) in an array that can be parsed to create calendar events. Please use 1-2 emojis per complex sentence in the title's lhs and description to make them more personal.` ;
179+ return newEventsPrompt ;
180+ }
181+
182+ async sendUserMessage ( prompt ) {
177183 let userMessage = this . #makeMessage( this . #USER, prompt ) ;
178- this . #messagesAppend( userMessage ) ;
179- let printedMessage = ( prettyPrinted === "" ) ? userMessage : this . #makeMessage( this . #USER, prettyPrinted ) ;
180- this . #generateMessageHTML( printedMessage ) ;
181- if ( this . getState ( ) === CHAT_WINDOW_STATES . CREATE ) {
182- let messages = this . getMessages ( ) ;
183- let emptyResponseMessage = this . #makeMessage( this . #ASSISTANT, "" ) ;
184- this . #generateMessageHTML( emptyResponseMessage ) ;
185- await this . #streamResponse( messages ) ;
184+ this . #generateMessageHTML( userMessage ) ;
185+ switch ( this . #STATE) {
186+ case CHAT_WINDOW_STATES . CREATE :
187+ let newEventsPrompt = this . #makeNewEventsPrompt( prompt )
188+ let newEventsMessage = this . #makeMessage( this . #USER, newEventsPrompt ) ;
189+ this . #messagesAppend( newEventsMessage ) ;
190+ let messages = this . getMessages ( ) ;
191+ let emptyResponseMessage = this . #makeMessage( this . #ASSISTANT, "" ) ;
192+ this . #generateMessageHTML( emptyResponseMessage ) ;
193+ await this . #streamResponse( messages ) ;
194+
195+ this . setState ( CHAT_WINDOW_STATES . SPECIFY ) ;
196+ await this . sendSystemMessage ( "Is this event ok, then write \"yes\" to confirm." ) ;
197+ break ;
198+ case CHAT_WINDOW_STATES . SPECIFY :
199+ let normalizedPrompt = prompt . trim ( ) . toLowerCase ( ) ;
200+ if ( normalizedPrompt === "exit" ) {
201+ this . setState ( CHAT_WINDOW_STATES . CREATE ) ;
202+ this . clearMessages ( ) ;
203+ await this . sendSystemMessage ( "Please write your plans here in as much detail as you like." ) ;
204+ } else if ( normalizedPrompt === "yes" ) {
205+ let messages = this . getMessages ( ) ;
206+ let events_message = messages . slice ( - 1 ) [ 0 ] . content ;
207+ let events_json = await this . #extractAndParseJSON( events_message ) ;
208+ let eventsToProcess = Array . isArray ( events_json ) ? events_json : [ events_json ] ;
209+ let events = calendarjs . createEventObjects ( eventsToProcess ) ;
210+ try {
211+ const auth = await calendarjs . authorize ( ) ;
212+ await calendarjs . createEvents ( auth , events ) ;
213+ let summaryList = events . map ( event => event . summary ) . join ( ', ' ) ;
214+ await this . sendSystemMessage ( `Events '${ summaryList } ' created!` ) ;
215+ } catch ( error ) {
216+ console . error ( error ) ;
217+ await this . sendSystemMessage ( `Events failed to be made!` ) ;
218+ }
219+
220+ this . setState ( CHAT_WINDOW_STATES . CREATE ) ;
221+ await this . sendSystemMessage ( "Please write your plans here in as much detail as you like." ) ;
222+ this . clearMessages ( ) ;
223+ } else {
224+ this . #messagesAppend( userMessage ) ;
225+ let messages = this . getMessages ( ) ;
226+ let emptyResponseMessage = this . #makeMessage( this . #ASSISTANT, "" ) ;
227+ this . #generateMessageHTML( emptyResponseMessage ) ;
228+ await this . #streamResponse( messages ) ;
229+ await this . sendSystemMessage ( "Is this event ok, then write \"yes\" to confirm." ) ;
230+ }
231+ default :
232+ break ;
186233 }
187234 }
188235
@@ -209,61 +256,8 @@ textInputBox.addEventListener('keydown', async function (e) {
209256 if ( e . key != 'Shift' ) {
210257 e . preventDefault ( ) ;
211258 }
212- let today = new Date ( ) . toISOString ( ) . split ( 'T' ) [ 0 ] ;
213- let time = new Date ( ) . toTimeString ( ) . split ( ' ' ) [ 0 ] ;
214- let day = new Date ( ) . toLocaleString ( 'en-us' , { weekday : 'long' } ) ;
215259 let textFromInputBox = textInputBox . value ;
216- let planning_prompt = textFromInputBox ;
217-
218260 textInputBox . value = "" ;
219-
220- let constructedPrompt = planning_prompt //`Given the following current date and time: ${day}, ${today}T${time} and planning prompt: '${planning_prompt}', format the prompt's contents as JSON objects with the following keys: summary, location (Optional.), description, start (ISO 8601), end, recurrence (Optional. array of RRULE strings), reminders (Optional. useDefault, overrides), timeZone (Etc/GMT+2), allDay (boolean), in an array that can be parsed to create calendar events. Please use 1-2 emojis per complex sentence in the title's lhs and description to make them more personal.`;
221-
222- if ( chatWindow . getState ( ) == CHAT_WINDOW_STATES . CREATE ) {
223- constructedPrompt = `Given the following current date and time: ${ day } , ${ today } T${ time } :00 and planning prompt: '${ planning_prompt } ', format the prompt's contents as JSON objects with the following keys: summary, description (brief, beautiful and helpful), start, end (don't write timezone.), allDay (boolean) and location (if provided) in an array that can be parsed to create calendar events. Please use 1-2 emojis per complex sentence in the title's lhs and description to make them more personal.` ;
224- await chatWindow . sendUserMessage ( constructedPrompt , planning_prompt ) ;
225- ( async ( ) => {
226- await chatWindow . sendSystemMessage ( "Is this event ok, then write \"yes\" to confirm." ) ;
227- } ) ( ) ;
228- chatWindow . setState ( CHAT_WINDOW_STATES . SPECIFY ) ;
229- } else {
230- if ( constructedPrompt . trim ( ) . toLowerCase ( ) === "exit" ) {
231- chatWindow . setState ( CHAT_WINDOW_STATES . CREATE ) ;
232- await chatWindow . sendUserMessage ( constructedPrompt ) ;
233- chatWindow . clearMessages ( ) ;
234- await chatWindow . sendSystemMessage ( "Please write your plans here in as much detail as you like." ) ;
235- } else if ( constructedPrompt . trim ( ) . toLowerCase ( ) === "yes" ) {
236- let messages = chatWindow . getMessages ( ) ;
237- let events_message = messages . slice ( - 1 ) [ 0 ] . content ;
238- let events_json = await chatWindow . extractAndParseJSON ( events_message ) ;
239- let eventsToProcess = Array . isArray ( events_json ) ? events_json : [ events_json ] ;
240- console . log ( "The created events array after events_json call" ) ;
241- console . log ( events_json ) ;
242- let events = calendarjs . createEventObjects ( eventsToProcess ) ;
243-
244- await chatWindow . sendUserMessage ( constructedPrompt ) ;
245-
246- try {
247- const auth = await calendarjs . authorize ( ) ;
248- await calendarjs . createEvents ( auth , events ) ;
249- let summaryList = events . map ( event => event . summary ) . join ( ', ' ) ;
250- await chatWindow . sendSystemMessage ( `Events '${ summaryList } ' created!` ) ;
251- } catch ( error ) {
252- console . error ( error ) ;
253- await chatWindow . sendSystemMessage ( `Events failed to be made!` ) ;
254- }
255-
256- chatWindow . setState ( CHAT_WINDOW_STATES . CREATE ) ;
257- await chatWindow . sendSystemMessage ( "Please write your plans here in as much detail as you like." ) ;
258- chatWindow . clearMessages ( ) ;
259- } else {
260- chatWindow . setState ( CHAT_WINDOW_STATES . CREATE ) ;
261- await chatWindow . sendUserMessage ( constructedPrompt ) ;
262- ( async ( ) => {
263- await chatWindow . sendSystemMessage ( "Is this event ok, then write \"yes\" to confirm." ) ;
264- } ) ( ) ;
265- chatWindow . setState ( CHAT_WINDOW_STATES . SPECIFY ) ;
266- }
267- }
261+ chatWindow . sendUserMessage ( textFromInputBox ) ;
268262 }
269263} ) ;
0 commit comments