commit
745444b564
@ -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" |
||||
] |
||||
} |
@ -0,0 +1,5 @@ |
||||
out |
||||
dist |
||||
node_modules |
||||
.vscode-test/ |
||||
*.vsix |
@ -0,0 +1,7 @@ |
||||
{ |
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846 |
||||
// for the documentation about the extensions.json format |
||||
"recommendations": [ |
||||
"dbaeumer.vscode-eslint" |
||||
] |
||||
} |
@ -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}" |
||||
} |
||||
] |
||||
} |
@ -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" |
||||
} |
@ -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 |
||||
} |
||||
} |
||||
] |
||||
} |
@ -0,0 +1,10 @@ |
||||
.vscode/** |
||||
.vscode-test/** |
||||
src/** |
||||
.gitignore |
||||
.yarnrc |
||||
vsc-extension-quickstart.md |
||||
**/tsconfig.json |
||||
**/.eslintrc.json |
||||
**/*.map |
||||
**/*.ts |
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -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" |
||||
} |
||||
} |
@ -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() {} |
@ -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(); |
@ -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)); |
||||
}); |
||||
}); |
@ -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); |
||||
} |
||||
} |
@ -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