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