initial commit
This commit is contained in:
commit
745444b564
30
.eslintrc.json
Normal file
30
.eslintrc.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"warn",
|
||||
{
|
||||
"selector": "import",
|
||||
"format": [ "camelCase", "PascalCase" ]
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/semi": "warn",
|
||||
"curly": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"no-throw-literal": "warn",
|
||||
"semi": "off"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"out",
|
||||
"dist",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
out
|
||||
dist
|
||||
node_modules
|
||||
.vscode-test/
|
||||
*.vsix
|
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
}
|
34
.vscode/launch.json
vendored
Normal file
34
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
}
|
||||
]
|
||||
}
|
11
.vscode/settings.json
vendored
Normal file
11
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.exclude": {
|
||||
"out": false // set this to true to hide the "out" folder with the compiled JS files
|
||||
},
|
||||
"search.exclude": {
|
||||
"out": true // set this to false to include "out" folder in search results
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off"
|
||||
}
|
20
.vscode/tasks.json
vendored
Normal file
20
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"problemMatcher": "$tsc-watch",
|
||||
"isBackground": true,
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
10
.vscodeignore
Normal file
10
.vscodeignore
Normal file
@ -0,0 +1,10 @@
|
||||
.vscode/**
|
||||
.vscode-test/**
|
||||
src/**
|
||||
.gitignore
|
||||
.yarnrc
|
||||
vsc-extension-quickstart.md
|
||||
**/tsconfig.json
|
||||
**/.eslintrc.json
|
||||
**/*.map
|
||||
**/*.ts
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# dumbpilot
|
||||
|
||||
Get inline completions using llama.cpp as as server backend
|
||||
|
||||
## Usage
|
||||
|
||||
1. start llama.cpp/server in the background or on a remote machine
|
||||
2. configure the host
|
||||
3. press `ctrl+shift+l` to use code prediction
|
2637
package-lock.json
generated
Normal file
2637
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
133
package.json
Normal file
133
package.json
Normal file
@ -0,0 +1,133 @@
|
||||
{
|
||||
"name": "dumbpilot",
|
||||
"displayName": "dumbpilot",
|
||||
"description": "Simple code prediction using llama.cpp server api",
|
||||
"version": "0.0.1",
|
||||
"engines": {
|
||||
"vscode": "^1.84.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onLanguage:ada",
|
||||
"onLanguage:agda",
|
||||
"onLanguage:alloy",
|
||||
"onLanguage:antlr",
|
||||
"onLanguage:applescript",
|
||||
"onLanguage:assembly",
|
||||
"onLanguage:augeas",
|
||||
"onLanguage:awk",
|
||||
"onLanguage:batchfile",
|
||||
"onLanguage:bluespec",
|
||||
"onLanguage:c-sharp",
|
||||
"onLanguage:c",
|
||||
"onLanguage:clojure",
|
||||
"onLanguage:cmake",
|
||||
"onLanguage:coffeescript",
|
||||
"onLanguage:common-lisp",
|
||||
"onLanguage:cpp",
|
||||
"onLanguage:css",
|
||||
"onLanguage:cuda",
|
||||
"onLanguage:dart",
|
||||
"onLanguage:dockerfile",
|
||||
"onLanguage:elixir",
|
||||
"onLanguage:elm",
|
||||
"onLanguage:emacs-lisp",
|
||||
"onLanguage:erlang",
|
||||
"onLanguage:f-sharp",
|
||||
"onLanguage:fortran",
|
||||
"onLanguage:glsl",
|
||||
"onLanguage:go",
|
||||
"onLanguage:groovy",
|
||||
"onLanguage:haskell",
|
||||
"onLanguage:html",
|
||||
"onLanguage:idris",
|
||||
"onLanguage:isabelle",
|
||||
"onLanguage:java-server-pages",
|
||||
"onLanguage:java",
|
||||
"onLanguage:javascript",
|
||||
"onLanguage:json",
|
||||
"onLanguage:julia",
|
||||
"onLanguage:jupyter-notebook",
|
||||
"onLanguage:kotlin",
|
||||
"onLanguage:lean",
|
||||
"onLanguage:literate-agda",
|
||||
"onLanguage:literate-coffeescript",
|
||||
"onLanguage:literate-haskell",
|
||||
"onLanguage:lua",
|
||||
"onLanguage:makefile",
|
||||
"onLanguage:maple",
|
||||
"onLanguage:markdown",
|
||||
"onLanguage:mathematica",
|
||||
"onLanguage:matlab",
|
||||
"onLanguage:ocaml",
|
||||
"onLanguage:pascal",
|
||||
"onLanguage:perl",
|
||||
"onLanguage:php",
|
||||
"onLanguage:powershell",
|
||||
"onLanguage:prolog",
|
||||
"onLanguage:protocol-buffer",
|
||||
"onLanguage:python",
|
||||
"onLanguage:r",
|
||||
"onLanguage:racket",
|
||||
"onLanguage:restructuredtext",
|
||||
"onLanguage:rmarkdown",
|
||||
"onLanguage:ruby",
|
||||
"onLanguage:rust",
|
||||
"onLanguage:sas",
|
||||
"onLanguage:scala",
|
||||
"onLanguage:scheme",
|
||||
"onLanguage:shell",
|
||||
"onLanguage:smalltalk",
|
||||
"onLanguage:solidity",
|
||||
"onLanguage:sparql",
|
||||
"onLanguage:sql",
|
||||
"onLanguage:stan",
|
||||
"onLanguage:standard-ml",
|
||||
"onLanguage:stata",
|
||||
"onLanguage:systemverilog",
|
||||
"onLanguage:tcl",
|
||||
"onLanguage:tcsh",
|
||||
"onLanguage:tex",
|
||||
"onLanguage:thrift",
|
||||
"onLanguage:typescript",
|
||||
"onLanguage:verilog",
|
||||
"onLanguage:vhdl",
|
||||
"onLanguage:visual-basic",
|
||||
"onLanguage:xslt",
|
||||
"onLanguage:yacc",
|
||||
"onLanguage:yaml",
|
||||
"onLanguage:zig"
|
||||
],
|
||||
"main": "./out/extension.js",
|
||||
"contributes": {
|
||||
"commands": [],
|
||||
"keybindings": [
|
||||
{
|
||||
"key": "ctrl+shift+l",
|
||||
"command": "editor.action.inlineSuggest.trigger"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"pretest": "npm run compile && npm run lint",
|
||||
"lint": "eslint src --ext ts",
|
||||
"test": "node ./out/test/runTest.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/vscode": "^1.84.0",
|
||||
"@types/mocha": "^10.0.3",
|
||||
"@types/node": "18.x",
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
||||
"@typescript-eslint/parser": "^6.9.0",
|
||||
"eslint": "^8.52.0",
|
||||
"glob": "^10.3.10",
|
||||
"mocha": "^10.2.0",
|
||||
"typescript": "^5.2.2",
|
||||
"@vscode/test-electron": "^2.3.6"
|
||||
}
|
||||
}
|
163
src/extension.ts
Normal file
163
src/extension.ts
Normal file
@ -0,0 +1,163 @@
|
||||
import { ok } from 'assert';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
|
||||
// llama.cpp server response format
|
||||
type llama_data = {
|
||||
content: string,
|
||||
generation_settings: JSON,
|
||||
model: string,
|
||||
prompt: string,
|
||||
stopped_eos: boolean,
|
||||
stopped_limit: boolean,
|
||||
stopped_word: boolean,
|
||||
stopping_word: string,
|
||||
timings: {
|
||||
predicted_ms: number,
|
||||
predicted_n: number,
|
||||
predicted_per_second: number,
|
||||
predicted_per_token_ms: number,
|
||||
prompt_ms: number,
|
||||
prompt_n: number,
|
||||
prompt_per_second: number,
|
||||
prompt_per_token_ms: number
|
||||
},
|
||||
tokens_cached: number,
|
||||
tokens_evaluated: number,
|
||||
tokens_predicted: number,
|
||||
truncated: boolean
|
||||
|
||||
};
|
||||
|
||||
|
||||
const llama_ctxsize = 2048;
|
||||
const llama_maxtokens = -1;
|
||||
const llama_mirostat = 0;
|
||||
const llama_repeat_penalty = 1.11;
|
||||
const llama_frequency_penalty = 0.0;
|
||||
const llama_presence_penalty = 0.0;
|
||||
const llama_repeat_ctx = 256;
|
||||
const llama_temperature = 0.25;
|
||||
const llama_top_p = 0.95;
|
||||
const llama_top_k = 40;
|
||||
const llama_typical_p = 0.95;
|
||||
const llama_tailfree_z = 0.5;
|
||||
const llama_session_seed = -1;
|
||||
|
||||
const llama_host = "http://0.0.0.0:8080";
|
||||
|
||||
|
||||
export function activate(cotext: vscode.ExtensionContext) {
|
||||
|
||||
console.log('dumbpilot is now active');
|
||||
|
||||
// Register a new provider of inline completions, this does not decide how it is invoked
|
||||
// only what the completion should be
|
||||
// https://github.com/microsoft/vscode-extension-samples/blob/main/inline-completions/src/extension.ts
|
||||
const provider: vscode.InlineCompletionItemProvider = {
|
||||
async provideInlineCompletionItems(document, position, context, token) {
|
||||
|
||||
// Since for every completion we want to query the server, we want to filter out
|
||||
// accidental automatic completion invokes
|
||||
if (context.triggerKind === vscode.InlineCompletionTriggerKind.Automatic) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// FIXME: I don't know if this works
|
||||
token.onCancellationRequested(() => {
|
||||
console.log("dumbpilot: operation cancelled, may still be running on the server");
|
||||
return null;
|
||||
});
|
||||
|
||||
//console.log('dumbpilot: completion invoked at position: line=' + position.line + ' char=' + position.character);
|
||||
|
||||
const result: vscode.InlineCompletionList = {
|
||||
items: []
|
||||
};
|
||||
|
||||
// Get the document's text and position to send to the model
|
||||
const doc_text = document.getText();
|
||||
const doc_off = document.offsetAt(position);
|
||||
var doc_before = doc_text.substring(0, doc_off);
|
||||
var doc_after = doc_text.substring(doc_off);
|
||||
|
||||
// clean up the document, stuff commented is already done by JSON.stringify()
|
||||
//doc_before = doc_before.replace(/(\r\n|\n|\r)/gm, "\\n");
|
||||
//doc_before = doc_before.replace(/\t/gm, "\\t");
|
||||
//doc_after = doc_before.replace(/(\r\n|\n|\r)/gm, "\\n");
|
||||
//doc_after = doc_before.replace(/\t/gm, "\\t");
|
||||
|
||||
// FIXME: I don't know if this penalizes some results since most people indent with spaces
|
||||
//doc_before = doc_before.replace(/\s+/gm, " ");
|
||||
//doc_after = doc_before.replace(/\s+/gm, " ");
|
||||
|
||||
// prefix commented filename, is this the best way?
|
||||
var comment_prefix: string = '';
|
||||
switch (document.languageId) {
|
||||
case 'c':
|
||||
case 'js':
|
||||
case 'ts':
|
||||
comment_prefix = '//';
|
||||
break;
|
||||
case 'sh':
|
||||
case 'bash':
|
||||
case 'zsh':
|
||||
case 'py':
|
||||
case 'python':
|
||||
comment_prefix = '#';
|
||||
break;
|
||||
}
|
||||
doc_before = comment_prefix + ' ' + document.fileName + '\n' + doc_before;
|
||||
|
||||
// server request object
|
||||
const request = {
|
||||
n_predict: llama_maxtokens,
|
||||
mirostat: llama_mirostat,
|
||||
repeat_penalty: llama_repeat_penalty,
|
||||
frequency_penalty: llama_frequency_penalty,
|
||||
presence_penalty: llama_presence_penalty,
|
||||
repeat_last_n: llama_repeat_ctx,
|
||||
temperature: llama_temperature,
|
||||
top_p: llama_top_p,
|
||||
top_k: llama_top_k,
|
||||
typical_p: llama_typical_p,
|
||||
tfs_z: llama_tailfree_z,
|
||||
seed: llama_session_seed,
|
||||
// input_prefix: doc_before,
|
||||
// input_suffix: doc_after,
|
||||
prompt: doc_before,
|
||||
};
|
||||
|
||||
var data: llama_data;
|
||||
// try to send the request to the running server
|
||||
try {
|
||||
const response = await fetch(
|
||||
llama_host.concat('/completion'),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json; charset=UTF-8'
|
||||
},
|
||||
body: JSON.stringify(request)
|
||||
}
|
||||
);
|
||||
if (response.ok === false) {
|
||||
throw new Error("llama server request is not ok??");
|
||||
}
|
||||
|
||||
data = await response.json() as llama_data;
|
||||
|
||||
} catch (e: any) {
|
||||
console.log('dumbpilot: ' + e.message);
|
||||
return null;
|
||||
};
|
||||
|
||||
result.items.push({insertText: data.content, range: new vscode.Range(position, position)});
|
||||
return result;
|
||||
},
|
||||
};
|
||||
vscode.languages.registerInlineCompletionItemProvider({pattern: '**'}, provider);
|
||||
}
|
||||
|
||||
// This method is called when your extension is deactivated
|
||||
export function deactivate() {}
|
23
src/test/runTest.ts
Normal file
23
src/test/runTest.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import { runTests } from '@vscode/test-electron';
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// The folder containing the Extension Manifest package.json
|
||||
// Passed to `--extensionDevelopmentPath`
|
||||
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
|
||||
|
||||
// The path to test runner
|
||||
// Passed to --extensionTestsPath
|
||||
const extensionTestsPath = path.resolve(__dirname, './suite/index');
|
||||
|
||||
// Download VS Code, unzip it and run the integration test
|
||||
await runTests({ extensionDevelopmentPath, extensionTestsPath });
|
||||
} catch (err) {
|
||||
console.error('Failed to run tests', err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
15
src/test/suite/extension.test.ts
Normal file
15
src/test/suite/extension.test.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import * as assert from 'assert';
|
||||
|
||||
// You can import and use all API from the 'vscode' module
|
||||
// as well as import your extension to test it
|
||||
import * as vscode from 'vscode';
|
||||
// import * as myExtension from '../../extension';
|
||||
|
||||
suite('Extension Test Suite', () => {
|
||||
vscode.window.showInformationMessage('Start all tests.');
|
||||
|
||||
test('Sample test', () => {
|
||||
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
|
||||
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
|
||||
});
|
||||
});
|
32
src/test/suite/index.ts
Normal file
32
src/test/suite/index.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import * as path from 'path';
|
||||
import Mocha from 'mocha';
|
||||
import { glob } from 'glob';
|
||||
|
||||
export async function run(): Promise<void> {
|
||||
// Create the mocha test
|
||||
const mocha = new Mocha({
|
||||
ui: 'tdd',
|
||||
color: true
|
||||
});
|
||||
|
||||
const testsRoot = path.resolve(__dirname, '..');
|
||||
const files = await glob('**/**.test.js', { cwd: testsRoot });
|
||||
|
||||
// Add files to the test suite
|
||||
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
|
||||
|
||||
try {
|
||||
return new Promise<void>((c, e) => {
|
||||
// Run the mocha test
|
||||
mocha.run(failures => {
|
||||
if (failures > 0) {
|
||||
e(new Error(`${failures} tests failed.`));
|
||||
} else {
|
||||
c();
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"target": "ES2022",
|
||||
"outDir": "out",
|
||||
"lib": [
|
||||
"ES2022"
|
||||
],
|
||||
"sourceMap": true,
|
||||
"rootDir": "src",
|
||||
"strict": true /* enable all strict type-checking options */
|
||||
/* Additional Checks */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user