From 94408cd21f80adf79c5ca433276c7f91ae315b9b Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Wed, 22 Mar 2023 09:10:00 +0800 Subject: [PATCH] enhance: ChatGPT stream reception --- frontend/components.d.ts | 1 - frontend/package.json | 2 +- frontend/src/components/ChatGPT/ChatGPT.vue | 44 ++++++++++++----- frontend/src/version.json | 2 +- frontend/src/views/config/ConfigEdit.vue | 50 +++++++++++++------- frontend/version.json | 2 +- resources/demo/demo.db | Bin 53248 -> 53248 bytes server/api/config.go | 1 + 8 files changed, 70 insertions(+), 32 deletions(-) diff --git a/frontend/components.d.ts b/frontend/components.d.ts index df534f58..eded9875 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -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'] diff --git a/frontend/package.json b/frontend/package.json index 966c4d40..6f85c6f9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "nginx-ui-frontend-next", "private": true, - "version": "1.7.7", + "version": "1.7.8", "type": "commonjs", "scripts": { "dev": "vite", diff --git a/frontend/src/components/ChatGPT/ChatGPT.vue b/frontend/src/components/ChatGPT/ChatGPT.vue index c7045801..2d172909 100644 --- a/frontend/src/components/ChatGPT/ChatGPT.vue +++ b/frontend/src/components/ChatGPT/ChatGPT.vue @@ -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) +