Skip to content

Commit c36cdff

Browse files
committed
implement support for notebooks
- reads all cells (with their outputs) and uses it as prompt - markdown is handled as the language comment - only text output is used (also handled as the language comment)
1 parent 9288c45 commit c36cdff

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

src/prompts/filter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type vscode from 'vscode';
22

33
export function isSupported(doc: vscode.TextDocument) {
4-
return doc.uri.scheme === 'file';
4+
return doc.uri.scheme === 'file' || doc.uri.scheme === 'vscode-notebook-cell';
55
}
66

77
export function isNotNeeded(doc: vscode.TextDocument, position: vscode.Position, context: vscode.InlineCompletionContext): boolean {

src/prompts/preparePrompt.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,84 @@ import { detectLanguage } from './processors/detectLanguage';
33
import { fileHeaders } from './processors/fileHeaders';
44
import { languages } from './processors/languages';
55

6+
var decoder = new TextDecoder("utf8");
7+
8+
function getNotebookDocument(document: vscode.TextDocument): vscode.NotebookDocument | undefined {
9+
return vscode.workspace.notebookDocuments
10+
.find(x => x.uri.path === document.uri.path);
11+
}
12+
613
export async function preparePrompt(document: vscode.TextDocument, position: vscode.Position, context: vscode.InlineCompletionContext) {
714

815
// Load document text
16+
console.log(document);
917
let text = document.getText();
1018
let offset = document.offsetAt(position);
1119
let prefix = text.slice(0, offset);
1220
let suffix: string = text.slice(offset);
1321

22+
// If this is a notebook, add the surrounding cells to the prefix and suffix
23+
let notebookDocument = getNotebookDocument(document);
24+
let language = detectLanguage(document.uri.fsPath, document.languageId);
25+
let commentStart: string | undefined = undefined;
26+
if (language) {
27+
commentStart = languages[language].comment?.start;
28+
}
29+
30+
if (notebookDocument) {
31+
let beforeCurrentCell = true;
32+
33+
let prefixCells = "";
34+
let suffixCells = "";
35+
36+
notebookDocument.getCells().forEach((cell) => {
37+
let out = "";
38+
39+
if (cell.document.uri.fragment === document.uri.fragment) {
40+
beforeCurrentCell = false; // switch to suffix mode
41+
return;
42+
}
43+
44+
// add the markdown cell output to the prompt as a comment
45+
if (cell.kind === vscode.NotebookCellKind.Markup && commentStart) {
46+
for (const line of cell.document.getText().split('\n')) {
47+
out += `\n${commentStart}${line}`;
48+
}
49+
} else {
50+
out += cell.document.getText();
51+
}
52+
53+
// if there is any outputs add them to the prompt as a comment
54+
if (cell.kind === vscode.NotebookCellKind.Code && commentStart) {
55+
console.log(cell.outputs);
56+
let cellOutputs = cell.outputs
57+
.map(x => x.items
58+
.filter(x => x.mime === 'text/plain')
59+
.map(x => decoder.decode(x.data))
60+
.map(x => x.slice(0, 256).split('\n'))) // limit to 256 characters
61+
.flat(3);
62+
63+
if (cellOutputs.length > 0) {
64+
out += `\n${commentStart}Output:`;
65+
for (const line of cellOutputs) {
66+
out += `\n${commentStart}${line}`;
67+
}
68+
}
69+
}
70+
71+
// update the prefix/suffix
72+
if (beforeCurrentCell) {
73+
prefixCells += out;
74+
} else {
75+
suffixCells += out;
76+
}
77+
78+
});
79+
80+
prefix = prefixCells + prefix;
81+
suffix = suffix + suffixCells;
82+
}
83+
1484
// Trim suffix
1585
// If suffix is too small it is safe to assume that it could be ignored which would allow us to use
1686
// more powerful completition instead of in middle one
@@ -22,7 +92,6 @@ export async function preparePrompt(document: vscode.TextDocument, position: vsc
2292
// NOTE: Most networks don't have a concept of filenames and expected language, but we expect that some files in training set has something in title that
2393
// would indicate filename and language
2494
// NOTE: If we can't detect language, we could ignore this since the number of languages that need detection is limited
25-
let language = detectLanguage(document.uri.fsPath, document.languageId);
2695
if (language) {
2796
prefix = fileHeaders(prefix, document.uri.fsPath, languages[language]);
2897
}

src/prompts/processors/languages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export const languages: { [key in Language]: LanguageDescriptor } = {
111111
},
112112
python: {
113113
name: 'Python',
114-
extensions: ['.py'],
114+
extensions: ['.py', 'ipynb'],
115115
comment: { start: '#' }
116116
},
117117
c: {

0 commit comments

Comments
 (0)