Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request #31 from Aincvy/output-channel-comfortable-completion
Browse files Browse the repository at this point in the history
  • Loading branch information
Venthe committed Oct 17, 2023
2 parents b573f8a + c7bde16 commit 8d8e79e
Show file tree
Hide file tree
Showing 11 changed files with 862 additions and 138 deletions.
461 changes: 418 additions & 43 deletions package-lock.json

Large diffs are not rendered by default.

35 changes: 32 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "fauxpilot",
"displayName": "Fauxpilot",
"description": "Get completions from Fauxpilot server",
"version": "1.1.6",
"version": "1.1.7",
"icon": "assets/icon.png",
"keywords": [
"code-suggestion",
Expand Down Expand Up @@ -87,6 +87,33 @@
"fauxpilot.inlineCompletion": {
"type": "boolean",
"default": true
},
"fauxpilot.fileFilter": {
"type": "array",
"default": [
{
"pattern": "**"
}
],
"description": "Allow suggestion only for files matching given patterns; Reference: https://code.visualstudio.com/api/references/document-selector"
},
"fauxpilot.excludeFileExts": {
"type": "object",
"default": {},
"description": "File extensions to exclude from suggestions. e.g: {\"md\": true} "
},
"fauxpilot.allowPending": {
"type": "boolean",
"defaultValue": true,
"description": "Allow wait previous request? If false, current `provideInlineCompletionItems` call will do nothing."
},
"fauxpilot.requestType": {
"type": "string",
"default": "openai",
"enum": [
"openai",
"axios"
]
}
}
}
Expand Down Expand Up @@ -122,6 +149,8 @@
"webpack-cli": "^4.10.0"
},
"dependencies": {
"openai": "^3.0.0"
"axios": "^1.5.0",
"http": "^0.0.1-security",
"openai": "^4.3.1"
}
}
}
73 changes: 73 additions & 0 deletions src/AccessBackend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { fauxpilotClient, RequestType } from "./FauxpilotClient";

// import * as http from 'http'
// import * as https from 'https'
import axios from "axios";
import { AxiosInstance } from "axios";
import OpenAI from 'openai';

const http = require('http');
const https = require('https');

// It's quite strange, this does not work. The server received a request with `Connection: close` ,
// even if using Node to run a simple script, the server receives a request with `Connection: keep-alive`.
// Currently, whether using OpenAI or axios, it is impossible to achieve keep alive.
const httpAgent = new http.Agent({ keepAlive: true });
const httpsAgent = new https.Agent({ keepAlive: true });


class AccessBackendCache {
private openai: OpenAI;
private axiosInstance: AxiosInstance;


constructor() {
this.openai = new OpenAI({ apiKey: fauxpilotClient.Token, baseURL: fauxpilotClient.BaseUrl });
this.axiosInstance = axios.create({
httpAgent,
httpsAgent,
baseURL: fauxpilotClient.BaseUrl,
timeout: 20000,
});

}

public fetchUseOpenAI(data: any): Promise<OpenAI.Completion>{
return this.openai.completions.create(data);
}

public fetchUseAxios(data: any): Promise<OpenAI.Completion> {
return this.axiosInstance.post('/completions', data).then(response => response.data);
}
}

let cacheInScript: AccessBackendCache;

export function rebuildAccessBackendCache() {
cacheInScript = new AccessBackendCache();
}

function getCache(): AccessBackendCache {
if (!cacheInScript) {
console.log("rebuilding access backend cache");
rebuildAccessBackendCache();
}
return cacheInScript;
}

export function fetch(prompt: string): Promise<OpenAI.Completion> {

const data = {
model: fauxpilotClient.Model,
prompt: prompt,
max_tokens: fauxpilotClient.MaxTokens,

Check warning on line 63 in src/AccessBackend.ts

View workflow job for this annotation

GitHub Actions / test

Object Literal Property name `max_tokens` must match one of the following formats: camelCase
temperature: fauxpilotClient.Temperature,
stop: fauxpilotClient.StopWords
};

if (fauxpilotClient.RequestType == RequestType.OpenAI) {

Check warning on line 68 in src/AccessBackend.ts

View workflow job for this annotation

GitHub Actions / test

Expected '===' and instead saw '=='
return getCache().fetchUseOpenAI(data);
} else {
return getCache().fetchUseAxios(data);
}
}
4 changes: 3 additions & 1 deletion src/Commands.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ConfigurationTarget, workspace } from "vscode";
import { fauxpilotClient } from "./FauxpilotClient";

const configuration = workspace.getConfiguration();
const target = ConfigurationTarget.Global;

function setExtensionStatus(enabled: boolean) {
console.debug("Setting fauxpilot state to", enabled);
configuration.update('fauxpilot.enabled', enabled, target, false).then(console.error);
// configuration.update('fauxpilot.enabled', enabled, target, false).then(console.error);
fauxpilotClient.isEnabled = enabled;
}

export type Command = { command: string, callback: (...args: any[]) => any, thisArg?: any };
Expand Down
2 changes: 1 addition & 1 deletion src/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Proportion of lines from the beginning of the file in the prompt
export const LEADING_LINES_PROP = 0.15;
export const LEADING_LINES_PROP = 0.21;
153 changes: 153 additions & 0 deletions src/FauxpilotClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { WorkspaceConfiguration, OutputChannel, ConfigurationTarget } from "vscode";
import { currentTimeString } from "./Utils";
import { rebuildAccessBackendCache } from "./AccessBackend";

export enum RequestType {
OpenAI,

Check warning on line 6 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Enum Member name `OpenAI` must match one of the following formats: camelCase
Aixos

Check warning on line 7 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Enum Member name `Aixos` must match one of the following formats: camelCase
}

export class FauxpilotClient {
private outputChannel?: OutputChannel;
private extConfig?: WorkspaceConfiguration;
private enabled = false;
private suggestionDelay = 0;
private excludeFileExts: Array<String>;
private baseUrl: string;
private model: string;
private maxTokens: number;
private temperature: number;
private stopWords: string[];
private token: string;
private requestType = RequestType.OpenAI;
private maxLines: number;

public version: string;

constructor() {
// this.outputChannel = null;
this.excludeFileExts = [];
this.baseUrl = '';
this.model = '<<UNSET>>';
this.maxTokens = 80;
this.temperature = 0.5;
this.stopWords = [];
this.version = '';
this.token = '';
this.maxLines = 150;
}

public init(extConfig: WorkspaceConfiguration, channel: OutputChannel) {

this.extConfig = extConfig;
this.outputChannel = channel;
this.reload(extConfig);
}

public reload(extConfig: WorkspaceConfiguration) {
this.extConfig = extConfig;
this.enabled = extConfig.get<boolean>("enabled", false) ?? false;
this.suggestionDelay = extConfig.get("suggestionDelay", 0) ?? 0;
this.baseUrl = `${extConfig.get("server")}/${extConfig.get("engine")}`;

this.excludeFileExts = [];
// let excludeFileExtsConfig = extConfig.get("excludeFileExts", new Map<String, Boolean>());
let excludeFileExtsConfig: { [key: string]: boolean } = extConfig.get("excludeFileExts", {});
for (const key in excludeFileExtsConfig as object) {
if (excludeFileExtsConfig[key]) {
this.excludeFileExts.push(key);
}
}

this.model = extConfig.get("model") ?? "<<UNSET>>";
this.maxTokens = extConfig.get("maxTokens", 80);
this.temperature = extConfig.get("temperature", 0.5);
this.stopWords = extConfig.get("inlineCompletion") ? ["\n"] : [];
this.token = extConfig.get("token", '');
this.requestType = extConfig.get("requestType", 'openai') === 'openai' ? RequestType.OpenAI : RequestType.Aixos;
this.maxLines = extConfig.get("maxLines", 150);

this.log(`enabled = ${this.enabled}`);
this.log(`baseUrl = ${this.baseUrl}`);
this.log(`suggestionDelay = ${this.suggestionDelay}`);
this.log(`excludeFileExts = ${this.excludeFileExts}`);
this.log(`model = ${this.model}`);
this.log(`maxTokens = ${this.maxTokens}`);
this.log(`temperature = ${this.temperature}`);
this.log(`stopWords = ${this.stopWords}`);
this.log(`token = ${this.token}`);
this.log(`requestType = ${this.requestType}`);
this.log(`maxLines = ${this.maxLines}`);

rebuildAccessBackendCache();
this.log("reload config finish.");
}

public log(str: string) {
if (!this.outputChannel) {
console.log('[Error] outputChannel is undefined!');
return;
}
this.outputChannel?.appendLine(`${currentTimeString()} ${str}`);
}

public get isEnabled(): boolean {
return this.enabled;
}

public set isEnabled(value: boolean) {
if (this.isEnabled !== value) {
this.enabled = value;
this.extConfig?.update("enabled", value);
this.outputChannel?.appendLine("change status to: " + this.enabled);
}
}

public get OutputChannel(): OutputChannel| undefined {

Check warning on line 106 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `OutputChannel` must match one of the following formats: camelCase
return this.outputChannel;
}

public get SuggestionDelay(): number {

Check warning on line 110 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `SuggestionDelay` must match one of the following formats: camelCase
return this.suggestionDelay;
}

public get BaseUrl(): string {

Check warning on line 114 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `BaseUrl` must match one of the following formats: camelCase
return this.baseUrl;
}

public get ExcludeFileExts(): Array<String> {

Check warning on line 118 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `ExcludeFileExts` must match one of the following formats: camelCase
return this.excludeFileExts;
}

public get Model(): string {

Check warning on line 122 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `Model` must match one of the following formats: camelCase
return this.model;
}

public get MaxTokens(): number {

Check warning on line 126 in src/FauxpilotClient.ts

View workflow job for this annotation

GitHub Actions / test

Accessor name `MaxTokens` must match one of the following formats: camelCase
return this.maxTokens;
}

public get MaxLines(): number {
return this.maxLines;
}
public get Temperature(): number {
return this.temperature;
}
public get StopWords(): Array<string> {
return this.stopWords;
}

public get Token(): string {
return this.token;
}

public get RequestType(): RequestType {
return this.requestType;
}

}

const client = new FauxpilotClient();

export const fauxpilotClient = client;

Loading

0 comments on commit 8d8e79e

Please sign in to comment.