我正在编写一个 Chrome 扩展程序,我需要在内容脚本中流式传输来自 OpenAI 端点的响应。单击上下文菜单时,内容脚本将运行。我正在使用 Craco 构建反应文件作为扩展的内容脚本。 这是从流中提取文本的代码:
const getStream = async (data) => {
const nextTokens = await getNextTokens(data);
const reader = nextTokens.getReader();
const decoder = new TextDecoder();
let done = false;
let text = '';
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
const chunkValue = decoder.decode(value);
console.log(chunkValue)
text += chunkValue;
}
}
这是
getNextTokens
的代码:
const getNextTokens = async (prompt) => {
const url = "https://api.openai.com/v1/chat/completions";
// Get config from storage
const {
apiKey,
model,
temperature,
maxTokens,
topP,
frequencyPenalty,
presencePenalty,
} = await getConfig();
// Create request body
//const data = { model: model, messages: [{role: "user", content: prompt }], stream: true }
const encoder = new TextEncoder()
const decoder = new TextDecoder()
let counter = 0
// Create headers
const requestHeaders = {
'Content-Type': 'application/json',
Authorization: "Bearer " + apiKey,
}
const res = await fetch(url, {
headers: requestHeaders,
method: 'POST',
body: JSON.stringify({
model: model,
messages: [{role: "user", content: prompt }],
max_tokens: 1000,
temperature: 1,
stream: true,
}),
})
const stream = new ReadableStream({
async start(controller) {
// callback
function onParse(event) {
if (event.type === 'event') {
const data = event.data
// https://beta.openai.com/docs/api-reference/completions/create#completions/create-stream
if (data === '[DONE]') {
console.log('DONE')
controller.close()
return
}
try {
const json = JSON.parse(data)
const text = json.choices[0].delta?.content || ''
if (counter < 2 && (text.match(/\n/) || []).length) {
// this is a prefix character (i.e., "\n\n"), do nothing
return
}
const queue = encoder.encode(text)
controller.enqueue(queue)
counter++
} catch (e) {
// maybe parse error
controller.error(e)
}
}
}
// stream response (SSE) from OpenAI may be fragmented into multiple chunks
// this ensures we properly read chunks and invoke an event for each SSE event stream
const parser = createParser(onParse)
for await (const chunk of res.body) {
parser.feed(decoder.decode(chunk))
}
},
})
return stream
};
这总是返回
Object is not async iterable
错误。以前有人遇到过这个问题吗?我会很感激一些帮助。谢谢。