Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/pipeline/parseInput.ts
13388 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 * as fs from 'fs/promises';
7
import { IAlternativeAction } from '../../src/extension/inlineEdits/node/nextEditProviderTelemetry';
8
9
/**
10
* A single row from the JSON input.
11
*/
12
export interface IInputRow {
13
readonly originalRowIndex: number;
14
readonly suggestionStatus: string;
15
readonly alternativeAction: IAlternativeAction;
16
readonly prompt: unknown[];
17
readonly modelResponse: string;
18
readonly postProcessingOutcome: {
19
suggestedEdit: string;
20
isInlineCompletion: boolean;
21
};
22
readonly activeDocumentLanguageId: string;
23
}
24
25
const requiredKeys = [
26
'status',
27
'action',
28
'input',
29
'response',
30
'outcome',
31
'language',
32
] as const;
33
34
/**
35
* Parse a JSON array of input entries into structured rows.
36
*/
37
function parseInputJson(jsonContents: string): {
38
rows: IInputRow[];
39
errors: { rowIndex: number; error: string }[];
40
} {
41
const records = JSON.parse(jsonContents) as Record<string, string>[];
42
43
const rows: IInputRow[] = [];
44
const errors: { rowIndex: number; error: string }[] = [];
45
46
for (let i = 0; i < records.length; i++) {
47
const record = records[i];
48
try {
49
for (const key of requiredKeys) {
50
if (!(key in record)) {
51
throw new Error(`Missing key: ${key}`);
52
}
53
}
54
55
const alternativeAction = JSON.parse(record['action']) as IAlternativeAction;
56
const prompt = JSON.parse(record['input']) as unknown[];
57
const postProcessingOutcome = JSON.parse(record['outcome']) as {
58
suggestedEdit: string;
59
isInlineCompletion: boolean;
60
};
61
62
if (!alternativeAction.recording) {
63
throw new Error('action.recording is missing');
64
}
65
if (!alternativeAction.recording.entries || alternativeAction.recording.entries.length === 0) {
66
throw new Error('action.recording.entries is empty');
67
}
68
if (!postProcessingOutcome.suggestedEdit) {
69
throw new Error('outcome.suggestedEdit is missing');
70
}
71
72
rows.push({
73
originalRowIndex: i,
74
suggestionStatus: record['status'],
75
alternativeAction,
76
prompt,
77
modelResponse: record['response'],
78
postProcessingOutcome,
79
activeDocumentLanguageId: record['language'],
80
});
81
} catch (e) {
82
errors.push({
83
rowIndex: i,
84
error: e instanceof Error ? e.message : String(e),
85
});
86
}
87
}
88
89
return { rows, errors };
90
}
91
92
export async function loadAndParseInput(inputPath: string, verbose = false): Promise<{
93
rows: IInputRow[];
94
errors: { rowIndex: number; error: string }[];
95
}> {
96
const contents = await fs.readFile(inputPath, 'utf8');
97
if (verbose) {
98
console.log(`Read ${contents.length} chars from ${inputPath}`);
99
}
100
return parseInputJson(contents);
101
}
102
103