Changeset 38816 for gs3-extensions
- Timestamp:
- 2024-03-02T23:03:08+13:00 (3 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
gs3-extensions/dl-chatgpt/trunk/src/react-gui/pages/api/chat.ts
r38809 r38816 18 18 19 19 20 import { MessageCreateParams, MessageContentText } from 'openai/resources/beta/threads/messages/messages' 21 20 import { 21 MessageContentText, 22 MessageCreateParams 23 } from 'openai/resources/beta/threads/messages/messages' 22 24 23 25 import type { NextApiRequest, NextApiResponse } from "next"; … … 28 30 }); 29 31 30 const threadByUserId = new Map<string, any>(); 32 let GS3AssistantLookup : any = null 33 34 async function initGS3AssistantsLookup() { 35 //const initGS3AssistantsLookup = async () => { 36 GS3AssistantLookup = new Map<string, any>(); 37 38 console.log("Setting up GS3AssistantsLookup table"); 39 40 console.log(" Retriving first page block, reverse order, so latest GS3 assistant IDs stored"); 41 // AssistantsPage 42 //let assistants_list_cursor : CursorPage<Assistant> = await openai.beta.assistants.list({ 43 let assistants_list_cursor = await openai.beta.assistants.list({ 44 order: "asc", 45 limit: 20, 46 }); 47 let paginated_items = assistants_list_cursor.getPaginatedItems(); 48 49 //while (assistants_list_cursor !== null) { 50 while (paginated_items.length > 0) { 51 let last_checked_assistant_id = ""; 52 53 for (const openai_assistant of paginated_items) { 54 const current_assistant_id = openai_assistant.id; 55 56 const metadata : any = openai_assistant.metadata; 57 58 if ("greenstone3" in metadata) { 59 if (metadata.greenstone3 === "True") { 60 console.log(" Processing Greenstone3 Assistant:"); 61 //console.log(openai_assistant); 62 63 const site_name = metadata.siteName; 64 const coll_name = metadata.collectionName; 65 66 //console.log(` Adding entry for site: ${site_name}, collect: ${coll_name}`); 67 68 if (!(site_name in GS3AssistantLookup)) { 69 GS3AssistantLookup[site_name] = new Map<string, any>(); 70 } 71 else { 72 // site already setup and going .... 73 // check to see if pre-existign coll_name already there? 74 if (coll_name in GS3AssistantLookup[site_name]) { 75 console.error(`Warning: Overwriting pre-existing GS3 assistant for site: ${site_name}, collection: ${coll_name}`); 76 } 77 } 78 79 console.log(` Storing GS3AssistantsLook[${site_name}][${coll_name}]: ${current_assistant_id}`); 80 GS3AssistantLookup[site_name][coll_name] = current_assistant_id; 81 82 } 83 } 84 last_checked_assistant_id = current_assistant_id; 85 } 86 87 88 console.log(" Retrieving next page block, ordered by most recent assistants"); 89 assistants_list_cursor = await openai.beta.assistants.list({ 90 after: last_checked_assistant_id, 91 order: "asc", 92 limit: 20, 93 }); 94 paginated_items = assistants_list_cursor.getPaginatedItems(); 95 } 96 console.log("Finished setting up GS3AssistantsLookup table"); 97 } 98 99 /* 100 101 function processAnnotations(message_content) 102 { 103 104 annotations = message_content.annotations; 105 106 citations = []; 107 108 // Iterate over the annotations and add footnotes 109 for index, annotation in enumerate(annotations) { 110 //Replace the text with a footnote 111 message_content.value = message_content.value.replace(annotation.text, f' [{index}]')l 112 113 // Gather citations based on annotation attributes 114 if (file_citation := getattr(annotation, 'file_citation', None)) { 115 cited_file = client.files.retrieve(file_citation.file_id) 116 citations.append(f'[{index}] {file_citation.quote} from {cited_file.filename}') 117 } 118 elif (file_path := getattr(annotation, 'file_path', None)) { 119 cited_file = client.files.retrieve(file_path.file_id) 120 citations.append(f'[{index}] Click <here> to download {cited_file.filename}') 121 // Note: File download functionality not implemented above for brevity 122 } 123 } 124 125 //Add footnotes to the end of the message before displaying to user 126 message_content.value += '\n' + '\n'.join(citations) 127 } 128 */ 129 130 131 132 function processAnnotations(message : MessageContentText) 133 { 134 console.log("Process Annotations"); 135 136 const messageContent = message.text; 137 const annotations = messageContent.annotations; 138 139 const citations: string[] = []; 140 141 // Iterate over the annotations and add footnotes 142 annotations.forEach(async (annotation, index) => { 143 // Replace the text with a footnote 144 console.log(` Annotation[${index}: `, annotation); 145 146 messageContent.value = messageContent.value.replace(annotation.text, ` [${index}]`); 147 148 // Gather citations based on annotation attributes 149 if ("file_citation" in annotation) { 150 const file_citation = annotation.file_citation; 151 console.log(` Retrieving file_citation for ${file_citation.file_id}`); 152 const citedFile = await openai.files.retrieve(file_citation.file_id); 153 const quote_html = file_citation.quote; 154 const quote = quote_html.replace(/(<([^>]+)>)/g," ").replace(/(\\n|\n)/," ").replace(/\s+/g," ") 155 console.log(` quote = ${quote}`); 156 157 citations.push(`[${index}] ${file_citation.quote} from ${citedFile.filename}`); 158 } 159 else if ("file_path" in annotation) { 160 const file_path = annotation.file_path; 161 console.log(` Retrieving file_path for ${annotation.file_path.file_id}`); 162 const citedFile = await openai.files.retrieve(annotation.file_path.file_id); 163 citations.push(`[${index}] Click <here> to download ${citedFile.filename}`); 164 // Note: File download functionality not implemented above for brevity 165 } 166 }); 167 168 // Add footnotes to the end of the message before displaying to the user 169 console.log("Citations: ", citations, '\n'); 170 //console.log("Appending: " + citations.join('\n')); 171 172 messageContent.value += '\n' + citations.join('\n'); 173 174 //return messageContent.value; 175 } 176 177 178 179 180 181 const UserThreadIdLookup = new Map<string, any>(); 31 182 32 183 async function assistantHandler( … … 34 185 res: NextApiResponse 35 186 ) { 36 const assistantIdToUse = process.env.ASSISTANT_ID || ""; 37 // const assistantIdToUse = "asst_LwUi7f2YMkZG5qTIPtpyhCOD"; 187 if (GS3AssistantLookup === null) { 188 await initGS3AssistantsLookup(); 189 } 190 191 192 // const assistantIdToUse = process.env.ASSISTANT_ID || ""; 193 // // const assistantIdToUse = "asst_LwUi7f2YMkZG5qTIPtpyhCOD"; 194 195 const assistantIdToUse = GS3AssistantLookup["thewillow"]["community-contributions"]; 38 196 39 197 //const userId = req.body.userId; // You should include the user ID in the request 40 198 const userId = "test_username"; 199 41 200 42 201 // Create a new thread if it's the user's first message 43 //if (! threadByUserId[userId]) {44 if (! threadByUserId.has(userId)) {202 //if (!UserThreadIdLookup[userId]) { 203 if (!UserThreadIdLookup.has(userId)) { 45 204 try { 46 205 const myThread = await openai.beta.threads.create(); … … 48 207 console.log(`Created new thread with ID: '${myThread.id}'"`); 49 208 console.log("========") 50 // threadByUserId[userId] = myThread.id; // Store the thread ID for this user51 52 threadByUserId.set(userId,myThread.id); // Store the thread ID for this user209 //UserThreadIdLookup[userId] = myThread.id; // Store the thread ID for this user 210 211 UserThreadIdLookup.set(userId,myThread.id); // Store the thread ID for this user 53 212 } 54 213 catch (error) { … … 73 232 try { 74 233 console.log(" Retrieving thread for userId: " + userId); 75 const myThreadId = threadByUserId.get(userId);234 const myThreadId = UserThreadIdLookup.get(userId); 76 235 console.log(" myThreadId = " + myThreadId); 77 236 console.log(""); … … 84 243 const myThreadMessage = await openai.beta.threads.messages.create(myThreadId,user_message); 85 244 86 console.log("This is the message object: ", myThreadMessage, "\n");245 //console.log("This is the message object: ", myThreadMessage, "\n"); 87 246 88 247 // Run the Assistant 89 248 console.log("Starting run for threadId: " + myThreadId); 90 249 const myRun = await openai.beta.threads.runs.create( 91 // threadByUserId.get(userId),250 //UserThreadIdLookup.get(userId), 92 251 myThreadId, 93 252 { … … 100 259 } 101 260 ); 102 console.log("This is the run object: ", myRun, "\n"); 261 //console.log("This is the run object: ", myRun, "\n"); 262 console.log("myRun: ", myRun, "\n"); 263 264 const checkStatusUntilCompleted = async (thread_id: string, run_id: string) => { 265 // Give a run that's just started some time to get going 266 await new Promise((resolve) => setTimeout(resolve, 5000)); 267 let run = await openai.beta.threads.runs.retrieve(thread_id,run_id); 268 269 let run_loop_count = 0; 270 while ((run.status === "queued") || (run.status === "in_progress")) { 271 run_loop_count++; 272 273 await new Promise((resolve) => setTimeout(resolve, 1000)); 274 console.log(` ${thread_id} run_id ${run_id}: Getting update on progress [ ` + "=".repeat(run_loop_count)+"> ]"); 275 run = await openai.beta.threads.runs.retrieve(thread_id,run_id); 276 console.log(` ${thread_id} run_id ${run_id}: Status = ${run.status}`); 277 278 // The following is not strictly necessary, but nice to have logged 279 if (run.status === "completed") { 280 console.log(` ${thread_id} run_id ${run_id}: Completed!`); 281 console.log("--------"); 282 break; 283 } 284 285 } 286 } 103 287 104 288 // Periodically retrieve the Run to check on its status … … 112 296 113 297 while (myRun.status !== "completed") { 114 console.log(` ${rrId}: Away to do runs.retrieve() when myRun id ${myRun.id} status is ${myRun.status}`);298 //console.log(` ${rrId}: Away to do runs.retrieve() when myRun id ${myRun.id} status is ${myRun.status}`); 115 299 keepRetrievingRun = await openai.beta.threads.runs.retrieve( 116 // threadByUserId.get(userId), // Use the stored thread ID for this user300 //UserThreadIdLookup.get(userId), // Use the stored thread ID for this user 117 301 myThreadId, 118 302 myRun.id … … 134 318 // Retrieve the Messages added by the Assistant to the Thread 135 319 const waitForAssistantMessage = async () => { 136 console.log("waitForAssistantMessage() away to call await retrieveRun()"); 137 await retrieveRun("withinWait"); 138 console.log("waitForAssistantMessage() returned from retrieveRun()"); 320 console.log("waitForAssistantMessage() away to call await checkStatusUntilComplete()"); 321 //await retrieveRun("withinWait"); 322 await checkStatusUntilCompleted(myThreadId,myRun.id); 323 console.log("waitForAssistantMessage() returned from checkRunUntilComplete()"); 139 324 140 325 console.log(`Retrieving messages list for ${myThreadId}`); 141 326 const allMessages = await openai.beta.threads.messages.list( 142 // threadByUserId.get(userId) // Use the stored thread ID for this user327 //UserThreadIdLookup.get(userId) // Use the stored thread ID for this user 143 328 myThreadId 144 329 ); 145 330 146 // Send the response back to the front end147 /*148 res.status(200).json({149 response: allMessages.data[0].content[0].text.value,150 });151 */152 331 console.log( 153 "-------- ----------------------------------------------------\n"332 "--------\n" 154 333 ); 155 334 156 335 const user_request_message: MessageContentText = (myThreadMessage.content[0]) as MessageContentText; 157 const assistant_response_message = allMessages.data[0].content[0] as MessageContentText; 158 336 const assistant_response_message = (allMessages.data[0].content[0]) as MessageContentText; 337 338 console.log("#####") 339 console.log("Assistant response message:", assistant_response_message, "\n"); 340 console.log("#####") 341 342 processAnnotations(assistant_response_message); 343 159 344 console.log("User: ", user_request_message.text.value); 160 345 console.log("Assistant: ", assistant_response_message.text.value);
Note:
See TracChangeset
for help on using the changeset viewer.