跳到主要内容

chatgpt deno deploy

转发响应流

import { serve } from "https://deno.land/std@0.184.0/http/server.ts";

function handler(_req: Request): Response {

return fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",

"Authorization": "Bearer {you key} ",
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
stream: true,
messages: [{ role: 'assistant', content: '28星宿'} ]}),
})
.then((response) => response.body)
.then((body) => {
const reader = body.getReader();

return new ReadableStream({
start(controller) {
return pump();

function pump() {
return reader.read().then(({ done, value }) => {
// When no more data needs to be consumed, close the stream

console.log(typeof value)

if (done) {
controller.close();
return;
}
const decoder= new TextDecoder()
const text = decoder.decode(value, {stream: true});
const dataObjects = text.split('\n').filter(Boolean);

const latestData = dataObjects[dataObjects.length - 1].replace(/^data: /, '');
const jsonData = JSON.parse(latestData);
// console.log(jsonData )
const finalData = jsonData["choices"][0]
console.log(finalData)
const encoder = new TextEncoder()
const s=[]
const finalValue= encoder.encode(JSON.stringify({
choices:finalData
}))
// Enqueue the next data chunk into our target stream
controller.enqueue(finalValue);
return pump();
});
}
},
});
}) .then((stream) => new Response(stream))
}
console.log("Listening on http://localhost:8000");
serve(handler);

前端参照demo

demo来源 https://www.reddit.com/r/ChatGPT/comments/11m3jdw/chatgpt_api_streaming/


fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer {your key}",
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
stream: true,
messages: messageHistory }),
})
.then(response => {
const reader = response.body.getReader();
const decoder = new TextDecoder();
let chunk = '';

reader.read().then(function processResult(result) {
chunk += decoder.decode(result.value, {stream: true});

// Split chunk into individual data objects
const dataObjects = chunk.split('\n').filter(Boolean);
// Process latest data object
const latestData = dataObjects[dataObjects.length - 1].replace(/^data: /, '');
if (latestData === '[DONE]') {
console.log('Conversation finished');
reader.cancel();
// add the user's message to the message history
messageHistory.push({ role: 'assistant', content: daveMessage.innerText });

return;
}

//Display Dave's response
const jsonData = JSON.parse(latestData);
if (jsonData.choices) {
// Get content of Dave's response
const daveResponse = jsonData.choices[0].delta.content;

// display Dave's message to the user
daveMessage.innerText += daveResponse;
}
// Continue streaming responses
reader.read().then(processResult);
});
})
.catch((error) => {
console.log(error);
const errorMessageContainer = document.createElement("div");
errorMessageContainer.classList.add("assistant-message");
errorMessageContainer.innerText = `Sorry, something went wrong. Please try again later.`;
messageContainer.appendChild(errorMessageContainer);
messageHistory.pop();
});

ReadableStream使用 参照 demo

mdn文档 https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams

fetch("./tortoise.png")
// Retrieve its body as ReadableStream
.then((response) => response.body)
.then((body) => {
const reader = body.getReader();

return new ReadableStream({
start(controller) {
return pump();

function pump() {
return reader.read().then(({ done, value }) => {
// When no more data needs to be consumed, close the stream
if (done) {
controller.close();
return;
}

// Enqueue the next data chunk into our target stream
controller.enqueue(value);
return pump();
});
}
},
});
})
.then((stream) => new Response(stream))
.then((response) => response.blob())
.then((blob) => URL.createObjectURL(blob))
.then((url) => console.log((image.src = url)))
.catch((err) => console.error(err));