initial integration

inlinecompletion_update
Stéphane Tetsing 9 months ago
parent 26c7201950
commit 6d9d46342e
  1. 5
      apps/remix-ide/src/app.js
  2. 14
      apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts
  3. 2
      apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts
  4. 41
      apps/remix-ide/src/app/plugins/solcode_completion.tsx
  5. 4
      apps/remix-ide/src/app/tabs/locales/en/settings.json
  6. 17
      libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts

@ -59,6 +59,7 @@ import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin'
import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin' import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin'
import {OpenAIGpt} from './app/plugins/openaigpt' import {OpenAIGpt} from './app/plugins/openaigpt'
import {SolCodeComp} from './app/plugins/solcode_completion'
const isElectron = require('is-electron') const isElectron = require('is-electron')
@ -233,6 +234,7 @@ class AppComponent {
// ----------------- AI -------------------------------------- // ----------------- AI --------------------------------------
const openaigpt = new OpenAIGpt() const openaigpt = new OpenAIGpt()
const solcodercomp = new SolCodeComp()
const copilotSuggestion = new CopilotSuggestion() const copilotSuggestion = new CopilotSuggestion()
// ----------------- import content service ------------------------ // ----------------- import content service ------------------------
@ -360,6 +362,7 @@ class AppComponent {
solidityScript, solidityScript,
templates, templates,
openaigpt, openaigpt,
solcodercomp,
copilotSuggestion copilotSuggestion
]) ])
@ -515,7 +518,9 @@ class AppComponent {
} }
) )
await this.appManager.activatePlugin(['solidity-script', 'openaigpt']) await this.appManager.activatePlugin(['solidity-script', 'openaigpt'])
await this.appManager.activatePlugin(['solcodercomp'])
await this.appManager.activatePlugin(['filePanel']) await this.appManager.activatePlugin(['filePanel'])
// Set workspace after initial activation // Set workspace after initial activation

@ -8,7 +8,7 @@ const profile = {
name: 'copilot-suggestion', name: 'copilot-suggestion',
displayName: 'copilot-suggestion', displayName: 'copilot-suggestion',
description: 'Get Solidity suggestions in editor', description: 'Get Solidity suggestions in editor',
methods: ['suggest', 'init', 'uninstall', 'status', 'isActivate', 'useRemoteService', 'discardRemoteService'], methods: ['suggest', 'init', 'uninstall', 'status', 'isActivate', 'useRemoteService', 'discardRemoteService', 'useconfig'],
version: '0.1.0-alpha', version: '0.1.0-alpha',
maintainedBy: "Remix" maintainedBy: "Remix"
} }
@ -18,6 +18,7 @@ export class CopilotSuggestion extends Plugin {
remoteService: string remoteService: string
context: string context: string
ready: boolean ready: boolean
config: { [id: string]: string }
constructor() { constructor() {
super(profile) super(profile)
this.service = new SuggestionService() this.service = new SuggestionService()
@ -30,12 +31,17 @@ export class CopilotSuggestion extends Plugin {
this.service.events.on('ready', (data) => { this.service.events.on('ready', (data) => {
this.ready = true this.ready = true
}) })
this.config = {}
} }
useRemoteService(service: string) { useRemoteService(service: string) {
this.remoteService = service this.remoteService = service
} }
useconfig(config ){
this.config = config
}
discardRemoteService() { discardRemoteService() {
this.remoteService = null this.remoteService = null
} }
@ -61,12 +67,16 @@ export class CopilotSuggestion extends Plugin {
const options: SuggestOptions = { const options: SuggestOptions = {
do_sample: false, do_sample: false,
top_k: 0, top_k: 0,
top_p: 0,
stream_result: false,
temperature: temperature || 0, temperature: temperature || 0,
max_new_tokens: max_new_tokens || 0 max_new_tokens: max_new_tokens || 0
} }
if (this.remoteService) { if (this.remoteService) {
const {data} = await axios.post(this.remoteService, {context: content, max_new_words: options.max_new_tokens, temperature: options.temperature}) let confs = {context: content, max_new_words: options.max_new_tokens, temperature: options.temperature}
// confs = {confs, ...this.config}
const {data} = await axios.post(this.remoteService, confs)
const parsedData = JSON.parse(data).trimStart() const parsedData = JSON.parse(data).trimStart()
return {output: [{generated_text: parsedData}]} return {output: [{generated_text: parsedData}]}
} else { } else {

@ -1,6 +1,6 @@
import EventEmitter from 'events' import EventEmitter from 'events'
export type SuggestOptions = { max_new_tokens: number, temperature: number, top_k: number, do_sample: boolean } export type SuggestOptions = { max_new_tokens: number, temperature: number, top_k: number, top_p:number, do_sample: boolean, stream_result:boolean}
export class SuggestionService { export class SuggestionService {
worker: Worker worker: Worker

@ -0,0 +1,41 @@
import { Plugin } from '@remixproject/engine'
import { client } from "@gradio/client"
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'solcoder_completion',
displayName: 'solcoder_completion',
description: 'solcoder_completion',
methods: ['message'],
events: [],
maintainedBy: 'Remix',
}
export class SolCodeComp extends Plugin {
constructor() {
super(profile)
}
async message(prompt): Promise<any> {
this.call('layout', 'maximizeTerminal')
this.call('terminal', 'log', 'Waiting for GPT answer...')
let result
try {
const app = await client("http://127.0.0.1:7860/", null);
const result = await app.predict("/code_completion", [
prompt, // string in 'context_code' Textbox component
"", // string in 'comment' Textbox component
false, // boolean in 'stream_result' Checkbox component
200, // number (numeric value between 0 and 2000) in 'max_new_tokens' Slider component
0.4, // number (numeric value between 0.01 and 1) in 'temperature' Slider component
0.90, // number (numeric value between 0 and 1) in 'top_p' Slider component
50, // number (numeric value between 1 and 200) in 'top_k' Slider component
]);
return result
} catch (e) {
this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` })
return
}
}
}

@ -40,5 +40,7 @@
"settings.copilot": "Solidity copilot - Alpha", "settings.copilot": "Solidity copilot - Alpha",
"settings.copilot.activate": "Load & Activate copilot", "settings.copilot.activate": "Load & Activate copilot",
"settings.copilot.max_new_tokens": "Maximum number of words to generate", "settings.copilot.max_new_tokens": "Maximum number of words to generate",
"settings.copilot.temperature": "Temperature" "settings.copilot.temperature": "Temperature",
"settings.copilot.top_k": "top_k",
"settings.copilot.top_p": "top_p"
} }

@ -42,7 +42,8 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
const ask = split[split.length - 2].trimStart() const ask = split[split.length - 2].trimStart()
if (split[split.length - 1].trim() === '' && ask.startsWith('///')) { if (split[split.length - 1].trim() === '' && ask.startsWith('///')) {
// use the code generation model // use the code generation model
const {data} = await axios.post('https://gpt-chat.remixproject.org/infer', {comment: ask.replace('///', '')})
const {data} = await this.props.plugin.call('solcoder_completion', 'message', ask)
const parsedData = JSON.parse(data).trimStart() const parsedData = JSON.parse(data).trimStart()
const item: monacoTypes.languages.InlineCompletion = { const item: monacoTypes.languages.InlineCompletion = {
insertText: parsedData insertText: parsedData
@ -60,21 +61,9 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
if (token.isCancellationRequested) { if (token.isCancellationRequested) {
return return
} }
let result
try {
result = await this.props.plugin.call('copilot-suggestion', 'suggest', word)
} catch (err) {
return
}
const generatedText = (result as any).output[0].generated_text as string const generatedText = (result as any).output[0].generated_text as string
// the generated text remove a space from the context...
let clean = generatedText let clean = generatedText
if (generatedText.indexOf('@custom:dev-run-script./') !== -1) {
clean = generatedText.replace('@custom:dev-run-script', '@custom:dev-run-script ')
}
clean = clean.replace(word, '')
const item: monacoTypes.languages.InlineCompletion = { const item: monacoTypes.languages.InlineCompletion = {
insertText: clean insertText: clean
}; };

Loading…
Cancel
Save