enhance: ChatGPT stream reception

This commit is contained in:
0xJacky 2023-03-22 09:10:00 +08:00
parent 11d1d59725
commit 94408cd21f
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
8 changed files with 70 additions and 32 deletions

View file

@ -56,7 +56,6 @@ declare module '@vue/runtime-core' {
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATag: typeof import('ant-design-vue/es')['Tag']
ATextarea: typeof import('ant-design-vue/es')['Textarea']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
BreadcrumbBreadcrumb: typeof import('./src/components/Breadcrumb/Breadcrumb.vue')['default']
ChartAreaChart: typeof import('./src/components/Chart/AreaChart.vue')['default']
ChartRadialBarChart: typeof import('./src/components/Chart/RadialBarChart.vue')['default']

View file

@ -1,7 +1,7 @@
{
"name": "nginx-ui-frontend-next",
"private": true,
"version": "1.7.7",
"version": "1.7.8",
"type": "commonjs",
"scripts": {
"dev": "vite",

View file

@ -46,13 +46,15 @@ async function request() {
console.log('fetching...')
messages.value.push(t.value)
emit('update:history_messages', messages.value)
let res = await fetch(urlJoin(window.location.pathname, '/api/chat_gpt'), {
method: 'POST',
headers: {'Accept': 'text/event-stream', Authorization: token.value},
body: JSON.stringify({messages: messages.value})
body: JSON.stringify({messages: messages.value.slice(0, messages.value?.length - 1)})
})
messages.value.push(t.value)
// read body as stream
console.log('reading...')
let reader = res.body!.getReader()
@ -62,6 +64,8 @@ async function request() {
let buffer = ''
let hasCodeBlockIndicator = false
while (true) {
let {done, value} = await reader.read()
if (done) {
@ -78,17 +82,32 @@ async function request() {
const decoder = new TextDecoder('utf-8')
const raw = decoder.decode(input)
const regex = /{"content":"(.+?)"}/g
const matches = raw.match(regex)
// console.log(input, raw)
const line = raw.split('\n\n')
line?.forEach(v => {
const data = v.slice('event:message\ndata:'.length)
if (!data) {
return
}
const content = JSON.parse(data).content
if (!hasCodeBlockIndicator) {
hasCodeBlockIndicator = content.indexOf('`') > -1
}
matches?.forEach(v => {
const content = JSON.parse(v).content
for (let c of content) {
buffer += c
if (isCodeBlockComplete(buffer)) {
t.value.content = buffer
if (hasCodeBlockIndicator) {
if (isCodeBlockComplete(buffer)) {
t.value.content = buffer
hasCodeBlockIndicator = false
} else {
t.value.content = buffer + '\n```'
}
} else {
t.value.content = buffer + '\n```'
t.value.content = buffer
}
}
})
@ -167,11 +186,12 @@ async function regenerate(index: number) {
const editing_idx = ref(-1)
const button_shape = computed(() => loading.value ? 'square' : 'circle')
const show = computed(() => messages?.value?.length > 1)
</script>
<template>
<a-card class="chatgpt" title="ChatGPT" v-if="messages?.length>1">
<a-card class="chatgpt" title="ChatGPT" v-if="show">
<div class="chatgpt-container">
<a-list
class="chatgpt-log"

View file

@ -1 +1 @@
{"version":"1.7.7","build_id":85,"total_build":155}
{"version":"1.7.8","build_id":86,"total_build":156}

View file

@ -8,6 +8,7 @@ import {message} from 'ant-design-vue'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
import ngx from '@/api/ngx'
import InspectConfig from '@/views/config/InspectConfig.vue'
import ChatGPT from '@/components/ChatGPT/ChatGPT.vue'
const {$gettext, interpolate} = gettext
const route = useRoute()
@ -23,16 +24,22 @@ const name = computed(() => {
})
const configText = ref('')
const history_chatgpt_record = ref([])
const file_path = ref('')
function init() {
if (name.value) {
config.get(name.value).then(r => {
configText.value = r.config
history_chatgpt_record.value = r.chatgpt_messages
file_path.value = r.file_path
}).catch(r => {
message.error(r.message ?? $gettext('Server error'))
})
} else {
configText.value = ''
history_chatgpt_record.value = []
file_path.value = ''
}
}
@ -58,28 +65,39 @@ function format_code() {
})
}
const editor_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 16 : 24)
const chat_md = computed(() => history_chatgpt_record?.value?.length > 1 ? 8 : 24)
</script>
<template>
<inspect-config ref="inspect_config"/>
<a-row :gutter="16">
<a-col :xs="24" :sm="24" :md="editor_md">
<a-card :title="$gettext('Edit Configuration')">
<code-editor v-model:content="configText"/>
<footer-tool-bar>
<a-space>
<a-button @click="$router.go(-1)">
<translate>Back</translate>
</a-button>
<a-button @click="format_code">
<translate>Format Code</translate>
</a-button>
<a-button type="primary" @click="save">
<translate>Save</translate>
</a-button>
</a-space>
</footer-tool-bar>
</a-card>
</a-col>
<a-card :title="$gettext('Edit Configuration')">
<code-editor v-model:content="configText"/>
<footer-tool-bar>
<a-space>
<a-button @click="$router.go(-1)">
<translate>Back</translate>
</a-button>
<a-button @click="format_code">
<translate>Format Code</translate>
</a-button>
<a-button type="primary" @click="save">
<translate>Save</translate>
</a-button>
</a-space>
</footer-tool-bar>
</a-card>
<a-col class="col-right" :xs="24" :sm="24" :md="chat_md">
<chat-g-p-t :content="configText" :path="file_path"
v-model:history_messages="history_chatgpt_record"/>
</a-col>
</a-row>
</template>
<style lang="less" scoped>

View file

@ -1 +1 @@
{"version":"1.7.7","build_id":85,"total_build":155}
{"version":"1.7.8","build_id":86,"total_build":156}

Binary file not shown.

View file

@ -96,6 +96,7 @@ func GetConfig(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"config": string(content),
"chatgpt_messages": chatgpt.Content,
"file_path": path,
})
}