From 78f348cd1406cfaf3d0247973b826783ab3532b5 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 17 Sep 2024 21:05:17 -0400 Subject: from last --- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 282 ++++++++++++----------------- 1 file changed, 112 insertions(+), 170 deletions(-) (limited to 'src/client/views/pdf/GPTPopup') diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 53bedbb65..ed3f99377 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -3,7 +3,7 @@ import { Button, IconButton, Type } from 'browndash-components'; import { action, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { CgClose, CgPathBack, CgArrowLeftO, CgCornerUpLeft } from 'react-icons/cg'; +import { CgClose, CgCornerUpLeft } from 'react-icons/cg'; import ReactLoading from 'react-loading'; import { TypeAnimation } from 'react-type-animation'; import { ClientUtils } from '../../../../ClientUtils'; @@ -11,16 +11,14 @@ import { Doc } from '../../../../fields/Doc'; import { NumCast, StrCast } from '../../../../fields/Types'; import { Networking } from '../../../Network'; import { GPTCallType, gptAPICall, gptImageCall } from '../../../apis/gpt/GPT'; -import { Docs } from '../../../documents/Documents'; import { DocUtils } from '../../../documents/DocUtils'; -import { ObservableReactComponent } from '../../ObservableReactComponent'; -import { AnchorMenu } from '../AnchorMenu'; -import './GPTPopup.scss'; +import { Docs } from '../../../documents/Documents'; import { SettingsManager } from '../../../util/SettingsManager'; import { SnappingManager } from '../../../util/SnappingManager'; +import { ObservableReactComponent } from '../../ObservableReactComponent'; import { DocumentView } from '../../nodes/DocumentView'; -import { DocCast } from '../../../../fields/Types'; -import { RTFCast } from '../../../../fields/Types'; +import { AnchorMenu } from '../AnchorMenu'; +import './GPTPopup.scss'; export enum GPTPopupMode { SUMMARY, @@ -30,21 +28,15 @@ export enum GPTPopupMode { DATA, CARD, SORT, - QUIZ + QUIZ, } export enum GPTQuizType { CURRENT = 0, CHOOSE = 1, - MULTIPLE = 2 - + MULTIPLE = 2, } - - - - - interface GPTPopupProps {} @observer @@ -168,30 +160,29 @@ export class GPTPopup extends ObservableReactComponent { this.cardsDoneLoading = done; } - @observable sortRespText: string = '' + @observable sortRespText: string = ''; @action setSortRespText(resp: string) { - this.sortRespText = resp + this.sortRespText = resp; } - @observable chatSortPrompt: string = "" + @observable chatSortPrompt: string = ''; sortPromptChanged = action((e: React.ChangeEvent) => { this.chatSortPrompt = e.target.value; }); - @observable quizAnswer: string = "" + @observable quizAnswer: string = ''; quizAnswerChanged = action((e: React.ChangeEvent) => { this.quizAnswer = e.target.value; }); - @observable conversationArray: string[] = ["Hi! In this pop up, you can ask ChatGPT questions about your documents and filter / sort them. "] - + @observable conversationArray: string[] = ['Hi! In this pop up, you can ask ChatGPT questions about your documents and filter / sort them. ']; /** * When the cards are in quiz mode in the card view, allows gpt to determine whether the user's answer was correct - * @returns + * @returns */ generateQuiz = async () => { this.setLoading(true); @@ -201,14 +192,13 @@ export class GPTPopup extends ObservableReactComponent { const selected = DocumentView.SelectedDocs().lastElement(); - const questionText = 'Question: ' + StrCast(selected['gptInputText']); if (StrCast(selected['gptRubric']) === '') { - const rubricText = 'Rubric: ' + await this.generateRubric(StrCast(selected['gptInputText']), selected) + const rubricText = 'Rubric: ' + (await this.generateRubric(StrCast(selected['gptInputText']), selected)); } - const rubricText = 'Rubric: ' + (StrCast(selected['gptRubric'])) + const rubricText = 'Rubric: ' + StrCast(selected['gptRubric']); const queryText = questionText + ' UserAnswer: ' + this.quizAnswer + '. ' + 'Rubric' + rubricText; try { @@ -217,23 +207,20 @@ export class GPTPopup extends ObservableReactComponent { console.error('GPT call failed'); return; } - console.log(res) - this.setQuizResp(res) - this.conversationArray.push(res) + console.log(res); + this.setQuizResp(res); + this.conversationArray.push(res); this.setLoading(false); this.setSortDone(true); - } catch (err) { console.error('GPT call failed'); } - - if (this.onQuizRandom){ - this.onQuizRandom() + if (this.onQuizRandom) { + this.onQuizRandom(); } - - } + }; /** * Generates a rubric by which to compare the user's answer to @@ -241,105 +228,95 @@ export class GPTPopup extends ObservableReactComponent { * @param doc the doc the user is providing info about * @returns gpt's response */ - generateRubric = async (inputText: string, doc:Doc) => { + generateRubric = async (inputText: string, doc: Doc) => { try { - const res = await gptAPICall(inputText, GPTCallType.RUBRIC); - doc['gptRubric']= res; - return res + const res = await gptAPICall(inputText, GPTCallType.RUBRIC); + doc['gptRubric'] = res; + return res; } catch (err) { console.error('GPT call failed'); } - - } - - + }; @observable private regenerateCallback: (() => Promise) | null = null; /** * Callback function that causes the card view to update the childpair string list - * @param callback + * @param callback */ @action public setRegenerateCallback(callback: () => Promise) { this.regenerateCallback = callback; } - - - public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false; public createFilteredDoc: (axes?: string[]) => boolean = () => false; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; - @observable quizRespText: string = '' - - @action setQuizResp (resp: string) { - this.quizRespText = resp + @observable quizRespText: string = ''; + @action setQuizResp(resp: string) { + this.quizRespText = resp; } /** * Generates a response to the user's question depending on the type of their question */ generateCard = async () => { - console.log(this.chatSortPrompt + "USER PROMPT") + console.log(this.chatSortPrompt + 'USER PROMPT'); this.setLoading(true); this.setSortDone(false); if (this.regenerateCallback) { await this.regenerateCallback(); } - + try { // const res = await gptAPICall(this.sortDesc, GPTCallType.SORT, this.chatSortPrompt); const questionType = await gptAPICall(this.chatSortPrompt, GPTCallType.TYPE); - const questionNumber = questionType.split(' ')[0] - console.log(questionType) - let res = '' + const questionNumber = questionType.split(' ')[0]; + console.log(questionType); + let res = ''; switch (questionNumber) { case '1': case '2': case '4': res = await gptAPICall(this.sortDesc, GPTCallType.SUBSET, this.chatSortPrompt); - break + break; case '6': res = await gptAPICall(this.sortDesc, GPTCallType.SORT, this.chatSortPrompt); - break + break; default: - const selected = DocumentView.SelectedDocs().lastElement(); const questionText = StrCast(selected!['gptInputText']); - res = await gptAPICall(questionText, GPTCallType.INFO, this.chatSortPrompt); - break + break; } // Trigger the callback with the result if (this.onSortComplete) { this.onSortComplete(res || 'Something went wrong :(', questionNumber, questionType.split(' ').slice(1).join(' ')); - let explanation = res + let explanation = res; + + if (questionType != '5' && questionType != '3') { + // Extract explanation surrounded by ------ at the top or both at the top and bottom + const explanationMatch = res.match(/------\s*([\s\S]*?)\s*(?:------|$)/) || []; + explanation = explanationMatch[1] ? explanationMatch[1].trim() : 'No explanation found'; + } - if (questionType != '5' && questionType != '3'){ - - // Extract explanation surrounded by ------ at the top or both at the top and bottom - const explanationMatch = res.match(/------\s*([\s\S]*?)\s*(?:------|$)/) || []; - explanation = explanationMatch[1] ? explanationMatch[1].trim() : 'No explanation found'; - } - // Set the extracted explanation to sortRespText this.setSortRespText(explanation); - this.conversationArray.push(this.sortRespText) - this.scrollToBottom() - + this.conversationArray.push(this.sortRespText); + this.scrollToBottom(); + console.log(res); } } catch (err) { console.error(err); } - + this.setLoading(false); this.setSortDone(true); }; @@ -476,21 +453,16 @@ export class GPTPopup extends ObservableReactComponent { makeObservable(this); GPTPopup.Instance = this; this.messagesEndRef = React.createRef(); - } - - scrollToBottom = () => { - setTimeout(() => { - // Code to execute after 1 second (1000 ms) - if (this.messagesEndRef.current) { - + setTimeout(() => { + // Code to execute after 1 second (1000 ms) + if (this.messagesEndRef.current) { this.messagesEndRef.current.scrollIntoView({ behavior: 'smooth', block: 'end' }); - } - - }, 50); - } + } + }, 50); + }; componentDidUpdate = () => { if (this.loading) { @@ -498,9 +470,9 @@ export class GPTPopup extends ObservableReactComponent { } }; - @observable quizMode : GPTQuizType = GPTQuizType.CURRENT - @action setQuizMode (g: GPTQuizType) { - this.quizMode = g + @observable quizMode: GPTQuizType = GPTQuizType.CURRENT; + @action setQuizMode(g: GPTQuizType) { + this.quizMode = g; } cardMenu = () => ( @@ -517,21 +489,18 @@ export class GPTPopup extends ObservableReactComponent { textAlign: 'center', color: '#ffffff', fontSize: '16px', - marginBottom: '10px' + marginBottom: '10px', }} />