Add context, !chat clears the context !cont keeps it
This commit is contained in:
		
							parent
							
								
									cb42f77ed2
								
							
						
					
					
						commit
						daa97f9d86
					
				
							
								
								
									
										74
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								index.js
									
									
									
									
									
								
							| @ -3,13 +3,62 @@ | |||||||
| const irc = require('irc'); | const irc = require('irc'); | ||||||
| const axios = require('axios'); | const axios = require('axios'); | ||||||
| const config = require('./config.json'); | const config = require('./config.json'); | ||||||
|  | 
 | ||||||
|  | // context is a list of strings that are used to seed the chatgpt api and it's responses
 | ||||||
|  | class Context { | ||||||
|  |     messages = []; | ||||||
|  |     currentResponse = ''; | ||||||
|  | 
 | ||||||
|  |     add_user_message(message) { | ||||||
|  |         this.messages.push({ role: 'user', content: message }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     add_assistant_message(message) { | ||||||
|  |         this.messages.push({ role: 'assistant', content: message }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     append_current_response(message) { | ||||||
|  |         this.currentResponse += message; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     end_line() { | ||||||
|  |         const response_so_far = this.currentResponse; | ||||||
|  |         this.currentResponse += "\n\n" | ||||||
|  |         return response_so_far; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     finish_current_response() { | ||||||
|  |         this.add_assistant_message(this.currentResponse); | ||||||
|  |         const the_response = this.currentResponse; | ||||||
|  |         this.currentResponse = ''; | ||||||
|  |         return the_response; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     is_response_in_progress() { | ||||||
|  |         return this.currentResponse !== ''; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     clear() { | ||||||
|  |         this.messages = []; | ||||||
|  |         this.currentResponse = ''; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const context = new Context(); | ||||||
|  | 
 | ||||||
| const client = new irc.Client(config.server, config.nick, { | const client = new irc.Client(config.server, config.nick, { | ||||||
|     channels: config.channels, |     channels: config.channels, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| // listen for messages that start with !chat and call the chatgpt api with a callback that prints the response line by line
 | // listen for messages that start with !chat and call the chatgpt api with a callback that prints the response line by line
 | ||||||
| client.addListener('message', async (from, to, message) => { | client.addListener('message', async (from, to, message) => { | ||||||
|     if (message.startsWith('!chat')) { |     is_chat_cmd = message.startsWith('!chat'); | ||||||
|  |     is_cont_cmd = message.startsWith('!cont'); | ||||||
|  |     if (is_chat_cmd || is_cont_cmd) { | ||||||
|  |         if(context.is_response_in_progress()) { return; } | ||||||
|  |         if(is_chat_cmd) { | ||||||
|  |             context.clear(); | ||||||
|  |         } | ||||||
|         const query = message.slice(6); |         const query = message.slice(6); | ||||||
|         chatgpt(query, (line) => { |         chatgpt(query, (line) => { | ||||||
|             client.say(to, line); |             client.say(to, line); | ||||||
| @ -19,10 +68,13 @@ client.addListener('message', async (from, to, message) => { | |||||||
| 
 | 
 | ||||||
| // function that calls the chatgpt streaming api (with server send events) and calls the callback function for each line
 | // function that calls the chatgpt streaming api (with server send events) and calls the callback function for each line
 | ||||||
| async function chatgpt(query, callback) { | async function chatgpt(query, callback) { | ||||||
|  |     // a very primitive mutex to prevent multiple calls to the api at once
 | ||||||
|  |     if(context.is_response_in_progress()) { return; } | ||||||
|  |     context.add_user_message(query); | ||||||
|     const apiUrl = 'https://api.openai.com/v1/chat/completions'; |     const apiUrl = 'https://api.openai.com/v1/chat/completions'; | ||||||
|      | 
 | ||||||
|     const response = await axios.post(apiUrl, { |     const response = await axios.post(apiUrl, { | ||||||
|         messages: [{ role: 'user', content: query }], |         messages: [context.messages], | ||||||
|         model: 'gpt-3.5-turbo', |         model: 'gpt-3.5-turbo', | ||||||
|         stream: true, |         stream: true, | ||||||
|     }, { |     }, { | ||||||
| @ -33,7 +85,6 @@ async function chatgpt(query, callback) { | |||||||
|         responseType: 'stream', |         responseType: 'stream', | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     let line = ''; |  | ||||||
|     response.data.on('data', (event) => { |     response.data.on('data', (event) => { | ||||||
|         let data = event.toString(); |         let data = event.toString(); | ||||||
|         let parts = data.split('\n'); |         let parts = data.split('\n'); | ||||||
| @ -41,8 +92,7 @@ async function chatgpt(query, callback) { | |||||||
|         for(part of parts) { |         for(part of parts) { | ||||||
| 		console.log(part); | 		console.log(part); | ||||||
|             if(part === 'data: [DONE]') { |             if(part === 'data: [DONE]') { | ||||||
| 		callback(line); |                 callback(context.finish_current_response()); | ||||||
| 		line = ''; |  | ||||||
|             } else if(part.startsWith('data: ')) { |             } else if(part.startsWith('data: ')) { | ||||||
|                 let jsonString = part.slice(part.indexOf('{'), part.lastIndexOf('}') + 1); |                 let jsonString = part.slice(part.indexOf('{'), part.lastIndexOf('}') + 1); | ||||||
|                 try { |                 try { | ||||||
| @ -60,20 +110,18 @@ async function chatgpt(query, callback) { | |||||||
|                     let hasEndNewline = chunk.endsWith("\n"); |                     let hasEndNewline = chunk.endsWith("\n"); | ||||||
| 
 | 
 | ||||||
|                     if(hasStartNewline) { |                     if(hasStartNewline) { | ||||||
|                         callback(line); |                         callback(context.end_line()) | ||||||
|                         line = ''; |  | ||||||
|                     } |                     } | ||||||
|                      |                      | ||||||
|                     for (let i = 0; i < lines.length - 1; i++) { |                     for (let i = 0; i < lines.length - 1; i++) { | ||||||
|                         callback(line+lines[i]); |                         context.append_current_response(lines[i]); | ||||||
|                         line = ''; |                         callback(context.end_line()); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     line += lines[lines.length - 1]; |                     context.append_current_response(lines[lines.length - 1]); | ||||||
| 
 | 
 | ||||||
|                     if(hasEndNewline) { |                     if(hasEndNewline) { | ||||||
|                         callback(line); |                         callback(context.end_line()); | ||||||
|                         line = ''; |  | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
| 		    if(line.length > 400) { | 		    if(line.length > 400) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user