diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index e1f7c2c1..1b8a7e54 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -52,7 +52,7 @@ jobs: e2e: runs-on: ubuntu-latest needs: [build_api, build_ui] - timeout-minutes: 5 + timeout-minutes: 10 steps: - uses: actions/checkout@v3 - name: Login to GitHub Container Registry diff --git a/api/chat_main_handler.go b/api/chat_main_handler.go index 8eed5565..cae537b8 100644 --- a/api/chat_main_handler.go +++ b/api/chat_main_handler.go @@ -207,7 +207,7 @@ func genAnswer(h *ChatHandler, w http.ResponseWriter, chatSessionUuid string, ch } if isTest(msgs) { - answerText, answerID, shouldReturn := chatStreamTest(w, chatSession, msgs) + answerText, answerID, shouldReturn := chatStreamTest(w, chatSession, msgs, chatUuid, false) if shouldReturn { return } @@ -219,7 +219,7 @@ func genAnswer(h *ChatHandler, w http.ResponseWriter, chatSessionUuid string, ch ) } } else { - answerText, answerID, shouldReturn := chatStream(w, chatSession, msgs) + answerText, answerID, shouldReturn := chatStream(w, chatSession, msgs, chatUuid, false) if shouldReturn { return } @@ -252,26 +252,25 @@ func regenerateAnswer(h *ChatHandler, w http.ResponseWriter, chatSessionUuid str isTestChat := isTest(chatCompletionMessages) if isTestChat { - answerText, answerID, shouldReturn := chatStreamTest(w, chat_session, chatCompletionMessages) + answerText, _, shouldReturn := chatStreamTest(w, chat_session, chatCompletionMessages, chatUuid, true) if shouldReturn { return } // Delete previous message and create new one - err := h.chatService.DeleteAndCreateChatMessage(chatSessionUuid, chatUuid, chat_session.UserID, answerID, answerText) + err := h.chatService.UpdateChatMessageContent(ctx, chatUuid, answerText) if err != nil { - RespondWithError(w, http.StatusInternalServerError, eris.Wrap(err, "fail to create message: ").Error(), nil) + RespondWithError(w, http.StatusInternalServerError, eris.Wrap(err, "fail to update chat message: ").Error(), nil) } } else { - answerText, answerID, shouldReturn := chatStream(w, chat_session, chatCompletionMessages) + answerText, _, shouldReturn := chatStream(w, chat_session, chatCompletionMessages, chatUuid, true) if shouldReturn { return } // Delete previous message and create new one - err := h.chatService.DeleteAndCreateChatMessage(chatSessionUuid, chatUuid, chat_session.UserID, answerID, answerText) - + err := h.chatService.UpdateChatMessageContent(ctx, chatUuid, answerText) if err != nil { - RespondWithError(w, http.StatusInternalServerError, eris.Wrap(err, "fail to create message: ").Error(), nil) + RespondWithError(w, http.StatusInternalServerError, eris.Wrap(err, "fail to update message: ").Error(), nil) } } } @@ -282,7 +281,7 @@ func isTest(msgs []openai.ChatCompletionMessage) bool { return promptMsg.Content == "test_demo_bestqa" || lastMsgs.Content == "test_demo_bestqa" } -func chatStream(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, chat_compeletion_messages []openai.ChatCompletionMessage) (string, string, bool) { +func chatStream(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, chat_compeletion_messages []openai.ChatCompletionMessage, chatUuid string, regenerate bool) (string, string, bool) { client := openai.NewClient(appConfig.OPENAI.API_KEY) openai_req := NewChatCompletionRequest(chatSession, chat_compeletion_messages) @@ -305,6 +304,11 @@ func chatStream(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, cha var answer string var answer_id string + + if regenerate { + answer_id = chatUuid + } + for { response, err := stream.Recv() if errors.Is(err, io.EOF) { @@ -349,10 +353,13 @@ func chatStream(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, cha return answer, answer_id, false } -func chatStreamTest(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, chat_compeletion_messages []openai.ChatCompletionMessage) (string, string, bool) { +func chatStreamTest(w http.ResponseWriter, chatSession sqlc_queries.ChatSession, chat_compeletion_messages []openai.ChatCompletionMessage, chatUuid string, regenerate bool) (string, string, bool) { //message := Message{Role: "assitant", Content:} - uuid, _ := uuid.NewV4() - answer_id := uuid.String() + answer_id := chatUuid + if !regenerate { + uuid, _ := uuid.NewV4() + answer_id = uuid.String() + } setSSEHeader(w) flusher, ok := w.(http.Flusher) diff --git a/e2e/package-lock.json b/e2e/package-lock.json index 8fc48e89..b23d8ce9 100644 --- a/e2e/package-lock.json +++ b/e2e/package-lock.json @@ -12,7 +12,7 @@ "pg": "^8.10.0" }, "devDependencies": { - "@playwright/test": "^1.32.0", + "@playwright/test": "^1.32.1", "@types/node": "^18.15.3" } }, diff --git a/e2e/package.json b/e2e/package.json index 3d38756c..afac578f 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -8,7 +8,7 @@ "author": "", "license": "ISC", "devDependencies": { - "@playwright/test": "^1.32.0", + "@playwright/test": "^1.32.1", "@types/node": "^18.15.3" }, "dependencies": { diff --git a/e2e/tests/09_session_answer.spec.ts b/e2e/tests/09_session_answer.spec.ts index a2b49a56..72631fd8 100644 --- a/e2e/tests/09_session_answer.spec.ts +++ b/e2e/tests/09_session_answer.spec.ts @@ -28,7 +28,7 @@ test('test', async ({ page }) => { await input_area?.press('Enter'); await page.waitForTimeout(1000); - const first_answer = await page.$eval('#image-wrapper .chat-message:nth-child(2) .message-text', el => el.innerText); + const first_answer = await page.$eval('#image-wrapper .chat-message:nth-child(2) .message-text', (el: HTMLElement) => el.innerText); // check the answer return by the server expect(first_answer).toContain('test_demo_bestqa'); @@ -38,7 +38,7 @@ test('test', async ({ page }) => { await page.waitForTimeout(1000); // check the answer return by the server await page.waitForSelector('#image-wrapper .chat-message:nth-child(4) .message-text'); - const sec_answer = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', el => el.innerText); + const sec_answer = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', (el: HTMLElement) => el.innerText); // check the sec_answer has the debug message expect(sec_answer).toContain('test_debug_1'); @@ -49,7 +49,7 @@ test('test', async ({ page }) => { await page.waitForTimeout(1000); // check the answer return by the server await page.waitForSelector('#image-wrapper .chat-message:nth-child(6) .message-text'); - const third_answer = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', el => el.innerText); + const third_answer = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', (el: HTMLElement) => el.innerText); // check the third_answer has the debug message expect(third_answer).toContain('test_debug_2'); diff --git a/e2e/tests/10_session_answer_regenerate.spec.ts b/e2e/tests/10_session_answer_regenerate.spec.ts index 517b344c..78ce9faa 100644 --- a/e2e/tests/10_session_answer_regenerate.spec.ts +++ b/e2e/tests/10_session_answer_regenerate.spec.ts @@ -33,8 +33,7 @@ test('test', async ({ page }) => { await input_area?.press('Enter'); await page.waitForTimeout(1000); - const first_answer = await page.$eval('#image-wrapper .chat-message:nth-child(2) .message-text', el => el.innerText); - console.log(first_answer) + const first_answer = await page.$eval('#image-wrapper .chat-message:nth-child(2) .message-text', (el: HTMLElement) => el.innerText); // check the answer return by the server expect(first_answer).toContain('test_demo_bestqa'); @@ -44,17 +43,15 @@ test('test', async ({ page }) => { await page.waitForTimeout(1000); // check the answer return by the server await page.waitForSelector('#image-wrapper .chat-message:nth-child(4) .message-text'); - const sec_answer = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', el => el.innerText); + const sec_answer = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', (el: HTMLElement) => el.innerText); // check the sec_answer has the debug message - console.log(sec_answer) expect(sec_answer).toContain('test_debug_1'); await page.locator('#image-wrapper .chat-message:nth-child(4) .chat-message-regenerate').click(); await page.waitForTimeout(1000); - const sec_answer_regen = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', el => el.innerText); + const sec_answer_regen = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', (el: HTMLElement) => el.innerText); // check the sec_answer has the debug message - console.log(sec_answer_regen) expect(sec_answer_regen).toContain('test_debug_1'); // add new message "test_debug_2" @@ -64,14 +61,14 @@ test('test', async ({ page }) => { await page.waitForTimeout(1000); // check the answer return by the server await page.waitForSelector('#image-wrapper .chat-message:nth-child(6) .message-text'); - const third_answer = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', el => el.innerText); + const third_answer = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', (el: HTMLElement) => el.innerText); // check the third_answer has the debug message expect(third_answer).toContain('test_debug_2'); await page.locator('#image-wrapper .chat-message:nth-child(6) .chat-message-regenerate').click(); await page.waitForTimeout(1000); - const third_answer_regen = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', el => el.innerText); + const third_answer_regen = await page.$eval('#image-wrapper .chat-message:nth-child(6) .message-text', (el: HTMLElement) => el.innerText); // check the third_answer has the debug message expect(third_answer_regen).toContain('test_debug_2'); @@ -80,8 +77,9 @@ test('test', async ({ page }) => { await page.waitForTimeout(1000); // check the second answer has been regenerated - const sec_answer_regen_2 = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', el => el.innerText); + const sec_answer_regen_2 = await page.$eval('#image-wrapper .chat-message:nth-child(4) .message-text', (el: HTMLElement) => el.innerText); // check the sec_answer has the debug message expect(sec_answer_regen_2).toContain('test_debug_1'); + expect(sec_answer_regen_2).not.toContain('test_debug_2') }); \ No newline at end of file diff --git a/web/src/views/chat/components/Message/index.vue b/web/src/views/chat/components/Message/index.vue index 95406125..d97b44dd 100644 --- a/web/src/views/chat/components/Message/index.vue +++ b/web/src/views/chat/components/Message/index.vue @@ -79,8 +79,10 @@ function handleRegenerate() {