initial working workspace completion

workspace_completion
STetsing 3 weeks ago
parent fab2076eb3
commit 7723356d66
  1. 21
      apps/remix-ide/src/app/plugins/remixAIPlugin.tsx
  2. 35
      libs/remix-ai-core/src/agents/completionAgent.ts
  3. 13
      libs/remix-ai-core/src/inferencers/remote/remoteInference.ts
  4. 4
      libs/remix-ai-core/src/types/types.ts

@ -65,6 +65,12 @@ export class RemixAIPlugin extends ViewPlugin {
this.initialize()
}
this.completionAgent = new CodeCompletionAgent(this)
// each 10 seconds update the workspace index
setInterval(() => {
console.log('Indexing workspace')
this.completionAgent.indexWorkspace()
}, 60000)
}
async initialize(model1?:IModel, model2?:IModel, remoteModel?:IRemoteModel, useRemote?:boolean){
@ -113,11 +119,15 @@ export class RemixAIPlugin extends ViewPlugin {
}
async code_completion(prompt: string, promptAfter: string): Promise<any> {
this.completionAgent.searchIndex(prompt)
if (this.completionAgent.indexer == null || this.completionAgent.indexer == undefined) await this.completionAgent.indexWorkspace()
const currentFile = await this.call('fileManager', 'getCurrentFile')
const contextfiles = await this.completionAgent.getContextFiles()
console.log('completion Context files', contextfiles)
if (this.isOnDesktop && !this.useRemoteInferencer) {
return await this.call(this.remixDesktopPluginName, 'code_completion', prompt, promptAfter)
} else {
return await this.remoteInferencer.code_completion(prompt, promptAfter)
return await this.remoteInferencer.code_completion(prompt, promptAfter, contextfiles, currentFile)
}
}
@ -179,11 +189,14 @@ export class RemixAIPlugin extends ViewPlugin {
}
async code_insertion(msg_pfx: string, msg_sfx: string): Promise<any> {
this.completionAgent.indexWorkspace()
if (this.completionAgent.indexer == null || this.completionAgent.indexer == undefined) await this.completionAgent.indexWorkspace()
const currentFile = await this.call('fileManager', 'getCurrentFile')
const contextfiles = this.completionAgent.getContextFiles()
if (this.isOnDesktop && !this.useRemoteInferencer) {
return await this.call(this.remixDesktopPluginName, 'code_insertion', msg_pfx, msg_sfx)
} else {
return await this.remoteInferencer.code_insertion(msg_pfx, msg_sfx)
return await this.remoteInferencer.code_insertion(msg_pfx, msg_sfx, contextfiles, currentFile)
}
}

@ -1,4 +1,3 @@
import FlexSearch from 'flexsearch';
import lunr from 'lunr';
interface Document {
@ -19,6 +18,8 @@ export class CodeCompletionAgent {
props: any;
indexer: any;
Documents: Document[] = [];
INDEX_THRESHOLD = 0.1;
N_MATCHES = 1;
constructor(props) {
this.props = props;
@ -40,7 +41,7 @@ export class CodeCompletionAgent {
id: ++c,
filename: file,
content: content,
identifier: c*34,
identifier: c-1,
});
}
}
@ -64,15 +65,33 @@ export class CodeCompletionAgent {
});
}
async searchIndex(query: string) {
async getContextFiles() {
try {
const searchResult = this.indexer.search(query);
console.log('Search result', searchResult);
return searchResult[0];
const currentFile = await this.props.call('fileManager', 'getCurrentFile');
const content = await this.props.call('fileManager', 'readFile', currentFile);
const searchResult = this.indexer.search(content);
const fcps = await this.processResults(searchResult, currentFile);
const resolvedFcps = await Promise.all(fcps);
return resolvedFcps;
} catch (error) {
console.log('Error searching index', error);
return null;
return [];
}
}
async processResults(results: any, currentFile: string) {
const rmResults = await results.filter(result => {
const document = this.Documents.find(doc => doc.id === Number(result.ref));
return document.filename !== currentFile;
});
const filteredResults = await rmResults.filter(result => result.score >= this.INDEX_THRESHOLD);
const topResults = filteredResults.slice(0, this.N_MATCHES);
const fileContentPairs = topResults.map(async result => {
const document = this.Documents.find(doc => doc.id === Number(result.ref));
const currentContent = await this.props.call('fileManager', 'readFile', document.filename);
return { file: document.filename, content: currentContent };
});
return fileContentPairs;
}
}

@ -12,7 +12,7 @@ export class RemoteInferencer implements ICompletions {
max_history = 7
model_op = RemoteBackendOPModel.CODELLAMA // default model operation change this to llama if necessary
event: EventEmitter
test_env=false
test_env=true
test_url="http://solcodertest.org"
constructor(apiUrl?:string, completionUrl?:string) {
@ -110,13 +110,16 @@ export class RemoteInferencer implements ICompletions {
}
}
async code_completion(prompt, promptAfter, options:IParams=CompletionParams): Promise<any> {
const payload = { prompt, 'context':promptAfter, "endpoint":"code_completion", ...options }
async code_completion(prompt, promptAfter, ctxFiles, fileName, options:IParams=CompletionParams): Promise<any> {
console.log("code_completion", ctxFiles)
const payload = { prompt, 'context':promptAfter, "endpoint":"code_completion",
'ctxFiles':ctxFiles, 'currentFileName':fileName, ...options }
return this._makeRequest(payload, AIRequestType.COMPLETION)
}
async code_insertion(msg_pfx, msg_sfx, options:IParams=InsertionParams): Promise<any> {
const payload = { "endpoint":"code_insertion", msg_pfx, msg_sfx, ...options, prompt: '' }
async code_insertion(msg_pfx, msg_sfx, ctxFiles, fileName, options:IParams=InsertionParams): Promise<any> {
const payload = { "endpoint":"code_insertion", msg_pfx, msg_sfx, 'ctxFiles':ctxFiles,
'currentFileName':fileName, ...options, prompt: '' }
return this._makeRequest(payload, AIRequestType.COMPLETION)
}

@ -50,8 +50,8 @@ export interface InferenceModel {
}
export interface ICompletions{
code_completion(context, params:IParams): Promise<any>;
code_insertion(msg_pfx, msg_sfx, params:IParams): Promise<any>;
code_completion(context, ctxFiles, fileName, params:IParams): Promise<any>;
code_insertion(msg_pfx, msg_sfx, ctxFiles, fileName, params:IParams): Promise<any>;
}
export interface IParams {

Loading…
Cancel
Save