| async function* completion (url, messages, controller) { |
| let data = { |
| model: 'gpt-3.5-turbo-16k', |
| messages, |
| temperature: 0.05, |
| stream: true |
| } |
| |
| |
| |
|
|
| |
|
|
| let response = await fetch(url, { |
| method: 'POST', |
| body: JSON.stringify(data), |
| headers: { |
| Connection: 'keep-alive', |
| 'Content-Type': 'application/json', |
| Accept: 'text/event-stream' |
| }, |
| signal: controller.signal |
| }) |
|
|
| const reader = response.body.getReader() |
| const decoder = new TextDecoder() |
|
|
| let content = '' |
| let leftover = '' |
|
|
| try { |
| let cont = true |
| while (cont) { |
| let result = await reader.read() |
| if (result.done) { |
| break |
| } |
|
|
| |
| const text = leftover + decoder.decode(result.value) |
|
|
| |
| const endsWithLineBreak = text.endsWith('\n') |
|
|
| |
| let lines = text.split('\n') |
|
|
| |
| |
| if (!endsWithLineBreak) { |
| leftover = lines.pop() |
| } else { |
| leftover = '' |
| } |
|
|
| |
| const regex = /^(\S+):\s(.*)$/gm |
| for (const line of lines) { |
| const match = regex.exec(line) |
| if (match) { |
| result[match[1]] = match[2] |
| |
| if (result.data) { |
| result.data = JSON.parse(result.data) |
| |
|
|
| content += result.data.choices[0].delta?.content || '' |
|
|
| |
| yield result |
|
|
| |
| if (result.data.choices[0].finish_reason == 'stop') { |
| if (result.data.generation_settings) { |
| |
| } |
| cont = false |
| break |
| } |
| } |
| } |
| } |
| } |
| } catch (e) { |
| console.error('llama error: ', e) |
| throw e |
| } finally { |
| controller.abort() |
| } |
|
|
| return content |
| |
| } |
|
|
| export async function completion_ (url, messages, controller, callback) { |
| let request = await completion(url, messages, controller) |
| for await (const chunk of request) { |
| let content = chunk.data.choices[0].delta.content || '' |
| if (chunk.data.choices[0].role == 'assistant') { |
| |
| content = '' |
| } |
|
|
| if (callback) callback(content) |
| } |
| } |
|
|