mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-12 02:45:49 +02:00
enhance: ChatGPT stream reception
This commit is contained in:
parent
11d1d59725
commit
94408cd21f
8 changed files with 70 additions and 32 deletions
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
|
@ -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']
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "nginx-ui-frontend-next",
|
||||
"private": true,
|
||||
"version": "1.7.7",
|
||||
"version": "1.7.8",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":"1.7.7","build_id":85,"total_build":155}
|
||||
{"version":"1.7.8","build_id":86,"total_build":156}
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
@ -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,
|
||||
})
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue