From 6d9d46342e8092d696378f700ef1aa6b84f145bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Fri, 2 Feb 2024 16:53:36 +0100 Subject: [PATCH] initial integration --- apps/remix-ide/src/app.js | 5 +++ .../suggestion-service/copilot-suggestion.ts | 14 ++++++- .../suggestion-service/suggestion-service.ts | 2 +- .../src/app/plugins/solcode_completion.tsx | 41 +++++++++++++++++++ .../src/app/tabs/locales/en/settings.json | 4 +- .../lib/providers/inlineCompletionProvider.ts | 17 ++------ 6 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 apps/remix-ide/src/app/plugins/solcode_completion.tsx diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 6f01181fa5..cceb3ec091 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -59,6 +59,7 @@ import { ripgrepPlugin } from './app/plugins/electron/ripgrepPlugin' import { compilerLoaderPlugin, compilerLoaderPluginDesktop } from './app/plugins/electron/compilerLoaderPlugin' import {OpenAIGpt} from './app/plugins/openaigpt' +import {SolCodeComp} from './app/plugins/solcode_completion' const isElectron = require('is-electron') @@ -233,6 +234,7 @@ class AppComponent { // ----------------- AI -------------------------------------- const openaigpt = new OpenAIGpt() + const solcodercomp = new SolCodeComp() const copilotSuggestion = new CopilotSuggestion() // ----------------- import content service ------------------------ @@ -360,6 +362,7 @@ class AppComponent { solidityScript, templates, openaigpt, + solcodercomp, copilotSuggestion ]) @@ -515,7 +518,9 @@ class AppComponent { } ) await this.appManager.activatePlugin(['solidity-script', 'openaigpt']) + await this.appManager.activatePlugin(['solcodercomp']) + await this.appManager.activatePlugin(['filePanel']) // Set workspace after initial activation diff --git a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts index ac1798b400..a7d8e5fbfa 100644 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts +++ b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts @@ -8,7 +8,7 @@ const profile = { name: 'copilot-suggestion', displayName: 'copilot-suggestion', 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', maintainedBy: "Remix" } @@ -18,6 +18,7 @@ export class CopilotSuggestion extends Plugin { remoteService: string context: string ready: boolean + config: { [id: string]: string } constructor() { super(profile) this.service = new SuggestionService() @@ -30,12 +31,17 @@ export class CopilotSuggestion extends Plugin { this.service.events.on('ready', (data) => { this.ready = true }) + this.config = {} } useRemoteService(service: string) { this.remoteService = service } + useconfig(config ){ + this.config = config + } + discardRemoteService() { this.remoteService = null } @@ -61,12 +67,16 @@ export class CopilotSuggestion extends Plugin { const options: SuggestOptions = { do_sample: false, top_k: 0, + top_p: 0, + stream_result: false, temperature: temperature || 0, max_new_tokens: max_new_tokens || 0 } 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() return {output: [{generated_text: parsedData}]} } else { diff --git a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts index b85647cb9f..4ec2d864dd 100644 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts +++ b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts @@ -1,6 +1,6 @@ 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 { worker: Worker diff --git a/apps/remix-ide/src/app/plugins/solcode_completion.tsx b/apps/remix-ide/src/app/plugins/solcode_completion.tsx new file mode 100644 index 0000000000..76b4bec519 --- /dev/null +++ b/apps/remix-ide/src/app/plugins/solcode_completion.tsx @@ -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 { + 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 + } + } +} diff --git a/apps/remix-ide/src/app/tabs/locales/en/settings.json b/apps/remix-ide/src/app/tabs/locales/en/settings.json index b290156eec..18806855e6 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/settings.json +++ b/apps/remix-ide/src/app/tabs/locales/en/settings.json @@ -40,5 +40,7 @@ "settings.copilot": "Solidity copilot - Alpha", "settings.copilot.activate": "Load & Activate copilot", "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" } diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 7f047833e1..5de52f2b63 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -42,7 +42,8 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli const ask = split[split.length - 2].trimStart() if (split[split.length - 1].trim() === '' && ask.startsWith('///')) { // 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 item: monacoTypes.languages.InlineCompletion = { insertText: parsedData @@ -60,21 +61,9 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli if (token.isCancellationRequested) { 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 - // the generated text remove a space from the context... 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 = { insertText: clean };