Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/nesFetch/common/completionHelpers.ts
13401 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { AsyncIterableEmitter, AsyncIterableObject } from '../../../util/vs/base/common/async';
7
import { assertType } from '../../../util/vs/base/common/types';
8
import { Completion } from './completionsAPI';
9
10
11
namespace LineOfText {
12
export type LineOfText = string & { _brand: 'LineOfText' };
13
14
export function make(s: string) {
15
return s as LineOfText;
16
}
17
}
18
19
/**
20
* Split an incoming stream of text to a stream of lines.
21
*/
22
export function streamLines(completions: AsyncIterable<Completion>, initialBuffer = ''): AsyncIterableObject<{
23
line: LineOfText.LineOfText;
24
finishReason: Completion.FinishReason | null;
25
}> {
26
27
async function splitLines(emitter: AsyncIterableEmitter<{
28
line: LineOfText.LineOfText;
29
finishReason: Completion.FinishReason | null;
30
}>) {
31
32
let buffer = initialBuffer;
33
let finishReason: Completion.FinishReason | null = null;
34
35
for await (const completion of completions) {
36
37
const choice = completion.choices.at(0);
38
assertType(choice !== undefined, 'we should have choices[0] to be defined');
39
40
buffer += choice.text ?? '';
41
finishReason = choice.finish_reason;
42
43
do {
44
const newlineIndex = buffer.indexOf('\n');
45
if (newlineIndex === -1) {
46
break;
47
}
48
49
// take the first line
50
const line = buffer.substring(0, newlineIndex);
51
buffer = buffer.substring(newlineIndex + 1);
52
53
emitter.emitOne({ line: LineOfText.make(line), finishReason });
54
} while (true);
55
}
56
57
if (buffer.length > 0) {
58
// last line which doesn't end with \n
59
emitter.emitOne({ line: LineOfText.make(buffer), finishReason });
60
}
61
}
62
63
return new AsyncIterableObject(splitLines);
64
}
65
66