diff --git a/controller/relay-openai.go b/controller/relay-openai.go index 7cb4b87..29545d3 100644 --- a/controller/relay-openai.go +++ b/controller/relay-openai.go @@ -9,11 +9,10 @@ import ( "net/http" "one-api/common" "strings" - "sync" ) func openaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*OpenAIErrorWithStatusCode, string) { - var responseTextBuilder strings.Builder + responseText := "" scanner := bufio.NewScanner(resp.Body) scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) { if atEOF && len(data) == 0 { @@ -29,10 +28,7 @@ func openaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*O }) dataChan := make(chan string) stopChan := make(chan bool) - var wg sync.WaitGroup go func() { - wg.Add(1) - var streamItems []string for scanner.Scan() { data := scanner.Text() if len(data) < 6 { // ignore blank line or wrong format @@ -44,39 +40,30 @@ func openaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*O dataChan <- data data = data[6:] if !strings.HasPrefix(data, "[DONE]") { - streamItems = append(streamItems, data) - } - } - streamResp := "[" + strings.Join(streamItems, ",") + "]" - switch relayMode { - case RelayModeChatCompletions: - var streamResponses []ChatCompletionsStreamResponseSimple - err := json.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses) - if err != nil { - common.SysError("error unmarshalling stream response: " + err.Error()) - wg.Done() - return // just ignore the error - } - for _, streamResponse := range streamResponses { - for _, choice := range streamResponse.Choices { - responseTextBuilder.WriteString(choice.Delta.Content) - } - } - case RelayModeCompletions: - var streamResponses []CompletionsStreamResponse - err := json.Unmarshal(common.StringToByteSlice(streamResp), &streamResponses) - if err != nil { - common.SysError("error unmarshalling stream response: " + err.Error()) - wg.Done() - return // just ignore the error - } - for _, streamResponse := range streamResponses { - for _, choice := range streamResponse.Choices { - responseTextBuilder.WriteString(choice.Text) + switch relayMode { + case RelayModeChatCompletions: + var streamResponse ChatCompletionsStreamResponseSimple + err := json.Unmarshal(common.StringToByteSlice(data), &streamResponse) + if err != nil { + common.SysError("error unmarshalling stream response: " + err.Error()) + continue // just ignore the error + } + for _, choice := range streamResponse.Choices { + responseText += choice.Delta.Content + } + case RelayModeCompletions: + var streamResponse CompletionsStreamResponse + err := json.Unmarshal(common.StringToByteSlice(data), &streamResponse) + if err != nil { + common.SysError("error unmarshalling stream response: " + err.Error()) + continue + } + for _, choice := range streamResponse.Choices { + responseText += choice.Text + } } } } - wg.Done() stopChan <- true }() setEventStreamHeaders(c) @@ -98,8 +85,7 @@ func openaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*O if err != nil { return errorWrapper(err, "close_response_body_failed", http.StatusInternalServerError), "" } - wg.Wait() - return nil, responseTextBuilder.String() + return nil, responseText } func openaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model string) (*OpenAIErrorWithStatusCode, *Usage) { diff --git a/web/src/components/LoginForm.js b/web/src/components/LoginForm.js index 8c3639c..03aec65 100644 --- a/web/src/components/LoginForm.js +++ b/web/src/components/LoginForm.js @@ -1,13 +1,10 @@ import React, {useContext, useEffect, useState} from 'react'; -import { - Modal, -} from 'semantic-ui-react'; import {Link, useNavigate, useSearchParams} from 'react-router-dom'; import {UserContext} from '../context/User'; import {API, getLogo, isMobile, showError, showInfo, showSuccess, showWarning} from '../helpers'; import {onGitHubOAuthClicked} from './utils'; import Turnstile from "react-turnstile"; -import {Layout, Card, Image, Form, Button, Divider} from "@douyinfe/semi-ui"; +import {Layout, Card, Image, Form, Button, Divider, Modal} from "@douyinfe/semi-ui"; import Title from "@douyinfe/semi-ui/lib/es/typography/title"; import Text from "@douyinfe/semi-ui/lib/es/typography/text"; @@ -92,8 +89,7 @@ const LoginForm = () => { localStorage.setItem('user', JSON.stringify(data)); showSuccess('登录成功!'); if (username === 'root' && password === '123456') { - showWarning('请立刻修改默认密码!'); - Modal.error({title: '您正在使用默认密码!', content: '请立刻修改默认密码!'}); + Modal.error({title: '您正在使用默认密码!', content: '请立刻修改默认密码!', centered: true}); } navigate('/token'); } else { diff --git a/web/src/components/UsersTable.js b/web/src/components/UsersTable.js index 5a9cfd1..95416a4 100644 --- a/web/src/components/UsersTable.js +++ b/web/src/components/UsersTable.js @@ -80,7 +80,6 @@ const UsersTable = () => { { manageUser(record.username, 'promote', record) }} @@ -90,7 +89,6 @@ const UsersTable = () => { { manageUser(record.username, 'demote', record) }}