mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-08-15 12:15:37 +08:00
fix: cannot stop when using azure openai api
This commit is contained in:
Generated
+7
-41
@@ -9,8 +9,6 @@
|
||||
"@nem035/gpt-3-encoder": "^1.1.7",
|
||||
"@picocss/pico": "^1.5.7",
|
||||
"@primer/octicons-react": "^18.2.0",
|
||||
"@vespaiach/axios-fetch-adapter": "^0.3.1",
|
||||
"azure-openai": "^0.9.4",
|
||||
"countries-list": "^2.6.1",
|
||||
"eventsource-parser": "^0.1.0",
|
||||
"expiry-map": "^2.0.0",
|
||||
@@ -2300,14 +2298,6 @@
|
||||
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vespaiach/axios-fetch-adapter": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/@vespaiach/axios-fetch-adapter/-/axios-fetch-adapter-0.3.1.tgz",
|
||||
"integrity": "sha512-+1F52VWXmQHSRFSv4/H0wtnxfvjRMPK5531e880MIjypPdUSX6QZuoDgEVeCE1vjhzDdxCVX7rOqkub7StEUwQ==",
|
||||
"peerDependencies": {
|
||||
"axios": ">=0.26.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.1.tgz",
|
||||
@@ -2761,7 +2751,8 @@
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
@@ -2772,23 +2763,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
}
|
||||
},
|
||||
"node_modules/azure-openai": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmmirror.com/azure-openai/-/azure-openai-0.9.4.tgz",
|
||||
"integrity": "sha512-7uii4ZInxzu2zjLg45PdvgOaw3ps18tEAw0Yux9mo8anX4PwnCMSS9xdlKNiNQyyEKPogvAcxH2PIufHXFLx6Q==",
|
||||
"dependencies": {
|
||||
"axios": "^0.26.0",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-loader": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-9.1.2.tgz",
|
||||
@@ -3107,6 +3081,7 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
@@ -3606,6 +3581,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@@ -4373,19 +4349,6 @@
|
||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz",
|
||||
@@ -4399,6 +4362,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
@@ -6331,6 +6295,7 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@@ -6339,6 +6304,7 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
"@nem035/gpt-3-encoder": "^1.1.7",
|
||||
"@picocss/pico": "^1.5.7",
|
||||
"@primer/octicons-react": "^18.2.0",
|
||||
"@vespaiach/axios-fetch-adapter": "^0.3.1",
|
||||
"azure-openai": "^0.9.4",
|
||||
"countries-list": "^2.6.1",
|
||||
"eventsource-parser": "^0.1.0",
|
||||
"expiry-map": "^2.0.0",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Configuration, OpenAIApi } from 'azure-openai'
|
||||
import { getUserConfig, maxResponseTokenLength } from '../../config/index.mjs'
|
||||
import { getChatSystemPromptBase, pushRecord, setAbortController } from './shared.mjs'
|
||||
import { getConversationPairs } from '../../utils/get-conversation-pairs'
|
||||
import fetchAdapter from '@vespaiach/axios-fetch-adapter'
|
||||
import { fetchSSE } from '../../utils/fetch-sse'
|
||||
import { isEmpty } from 'lodash-es'
|
||||
|
||||
/**
|
||||
* @param {Runtime.Port} port
|
||||
@@ -17,72 +17,54 @@ export async function generateAnswersWithAzureOpenaiApi(port, question, session)
|
||||
prompt.unshift({ role: 'system', content: await getChatSystemPromptBase() })
|
||||
prompt.push({ role: 'user', content: question })
|
||||
|
||||
const openAiApi = new OpenAIApi(
|
||||
new Configuration({
|
||||
apiKey: config.azureApiKey,
|
||||
azure: {
|
||||
apiKey: config.azureApiKey,
|
||||
endpoint: config.azureEndpoint,
|
||||
deploymentName: config.azureDeploymentName,
|
||||
let answer = ''
|
||||
await fetchSSE(
|
||||
`${config.azureEndpoint.replace(/\/$/, '')}/openai/deployments/${
|
||||
config.azureDeploymentName
|
||||
}/chat/completions?api-version=2023-03-15-preview`,
|
||||
{
|
||||
method: 'POST',
|
||||
signal: controller.signal,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'api-key': config.azureApiKey,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const response = await openAiApi
|
||||
.createChatCompletion(
|
||||
{
|
||||
body: JSON.stringify({
|
||||
messages: prompt,
|
||||
stream: true,
|
||||
max_tokens: maxResponseTokenLength,
|
||||
}),
|
||||
onMessage(message) {
|
||||
console.debug('sse message', message)
|
||||
let data
|
||||
try {
|
||||
data = JSON.parse(message)
|
||||
} catch (error) {
|
||||
console.debug('json error', error)
|
||||
return
|
||||
}
|
||||
if ('content' in data.choices[0].delta) {
|
||||
answer += data.choices[0].delta.content
|
||||
port.postMessage({ answer: answer, done: false, session: null })
|
||||
}
|
||||
if (data.choices[0].finish_reason === 'stop') {
|
||||
pushRecord(session, question, answer)
|
||||
console.debug('conversation history', { content: session.conversationRecords })
|
||||
port.postMessage({ answer: null, done: true, session: session })
|
||||
}
|
||||
},
|
||||
{
|
||||
signal: controller.signal,
|
||||
responseType: 'stream',
|
||||
adapter: fetchAdapter,
|
||||
async onStart() {},
|
||||
async onEnd() {
|
||||
port.onMessage.removeListener(messageListener)
|
||||
},
|
||||
)
|
||||
.catch((err) => {
|
||||
port.onMessage.removeListener(messageListener)
|
||||
throw err
|
||||
})
|
||||
|
||||
let chunkData = ''
|
||||
const step = 1500
|
||||
let length = 0
|
||||
for await (const chunk of response.data) {
|
||||
chunkData += chunk
|
||||
length += 1
|
||||
if (length % step !== 0 && !chunkData.endsWith('[DONE]')) continue
|
||||
|
||||
const lines = chunkData
|
||||
.toString('utf8')
|
||||
.split('\n')
|
||||
.filter((line) => line.trim().startsWith('data: '))
|
||||
|
||||
let answer = ''
|
||||
let message = ''
|
||||
let data
|
||||
for (const line of lines) {
|
||||
message = line.replace(/^data: /, '')
|
||||
try {
|
||||
data = JSON.parse(message)
|
||||
} catch (error) {
|
||||
continue
|
||||
}
|
||||
if ('content' in data.choices[0].delta) answer += data.choices[0].delta.content
|
||||
}
|
||||
if (data) {
|
||||
console.debug('sse message', data)
|
||||
port.postMessage({ answer: answer, done: false, session: null })
|
||||
}
|
||||
if (message === '[DONE]') {
|
||||
console.debug('sse message', '[DONE]')
|
||||
pushRecord(session, question, answer)
|
||||
console.debug('conversation history', { content: session.conversationRecords })
|
||||
port.postMessage({ answer: null, done: true, session: session })
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
port.onMessage.removeListener(messageListener)
|
||||
async onError(resp) {
|
||||
port.onMessage.removeListener(messageListener)
|
||||
if (resp instanceof Error) throw resp
|
||||
const error = await resp.json().catch(() => ({}))
|
||||
throw new Error(
|
||||
!isEmpty(error) ? JSON.stringify(error) : `${resp.status} ${resp.statusText}`,
|
||||
)
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -125,8 +125,10 @@ export async function generateAnswersWithChatgptApi(port, question, session, api
|
||||
console.debug('json error', error)
|
||||
return
|
||||
}
|
||||
if ('content' in data.choices[0].delta) answer += data.choices[0].delta.content
|
||||
port.postMessage({ answer: answer, done: false, session: null })
|
||||
if ('content' in data.choices[0].delta) {
|
||||
answer += data.choices[0].delta.content
|
||||
port.postMessage({ answer: answer, done: false, session: null })
|
||||
}
|
||||
},
|
||||
async onStart() {},
|
||||
async onEnd() {
|
||||
|
||||
Reference in New Issue
Block a user