From 2dc523a824e9baeebfabe4e237f1cf00d756a7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Thu, 7 Mar 2024 13:07:28 +0100 Subject: [PATCH 1/6] initial working tree remote code completion --- apps/remix-ide/src/app.js | 3 - .../suggestion-service/copilot-suggestion.ts | 103 ----------------- .../suggestion-service/suggestion-service.ts | 107 ------------------ .../copilot/suggestion-service/worker.js | 89 --------------- apps/remix-ide/src/app/plugins/solcoderAI.tsx | 19 +++- apps/remix-ide/src/app/tabs/settings-tab.tsx | 4 +- apps/remix-ide/src/remixAppManager.js | 1 - .../lib/providers/inlineCompletionProvider.ts | 23 +++- .../settings/src/lib/remix-ui-settings.tsx | 18 +-- 9 files changed, 36 insertions(+), 331 deletions(-) delete mode 100644 apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts delete mode 100644 apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts delete mode 100644 apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 33e0e4d4cb..e526b6dcbd 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -68,7 +68,6 @@ const remixLib = require('@remix-project/remix-lib') import { QueryParams } from '@remix-project/remix-lib' import { SearchPlugin } from './app/tabs/search' import { ElectronProvider } from './app/files/electronProvider' -import { CopilotSuggestion } from './app/plugins/copilot/suggestion-service/copilot-suggestion' const Storage = remixLib.Storage const RemixDProvider = require('./app/files/remixDProvider') @@ -235,7 +234,6 @@ class AppComponent { // ----------------- AI -------------------------------------- const openaigpt = new OpenAIGpt() const solcoder = new SolCoder() - const copilotSuggestion = new CopilotSuggestion() // ----------------- import content service ------------------------ const contentImport = new CompilerImports() @@ -363,7 +361,6 @@ class AppComponent { templates, openaigpt, solcoder, - copilotSuggestion ]) //---- fs plugin 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 deleted file mode 100644 index 61616ea4ce..0000000000 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/copilot-suggestion.ts +++ /dev/null @@ -1,103 +0,0 @@ -import {Plugin} from '@remixproject/engine' -import {SuggestionService, SuggestOptions} from './suggestion-service' -import axios, {AxiosResponse} from 'axios' -//@ts-ignore -const _paq = (window._paq = window._paq || []) //eslint-disable-line - -const profile = { - name: 'copilot-suggestion', - displayName: 'copilot-suggestion', - description: 'Get Solidity suggestions in editor', - methods: ['suggest', 'init', 'uninstall', 'status', 'isActivate', 'useRemoteService', 'discardRemoteService'], - version: '0.1.0-alpha', - maintainedBy: "Remix" -} - -export class CopilotSuggestion extends Plugin { - service: SuggestionService - remoteService: string - context: string - ready: boolean=false - constructor() { - super(profile) - this.context = '' - } - - onActivation(): void { - this.service = new SuggestionService() - this.service.events.on('progress', (data) => { - this.emit('loading', data) - }) - this.service.events.on('done', (data) => { - }) - this.service.events.on('ready', (data) => { - this.emit('ready', data) - this.ready = true - }) - } - - useRemoteService(service: string) { - this.remoteService = service - } - - discardRemoteService() { - this.remoteService = null - } - - status () { - return this.ready - } - - async isActivate () { - try { - return await this.call('settings', 'get', 'settings/copilot/suggest/activate') - } catch (e) { - console.error(e) - return false - } - } - - async suggest(content: string) { - if (!await this.call('settings', 'get', 'settings/copilot/suggest/activate')) return { output: [{ generated_text: ''}]} - - const max_new_tokens = await this.call('settings', 'get', 'settings/copilot/suggest/max_new_tokens') - const temperature = await this.call('settings', 'get', 'settings/copilot/suggest/temperature') - const options: SuggestOptions = { - do_sample: true, - top_k: 50, - top_p: 0.92, - 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}) - const parsedData = JSON.parse(data).trimStart() - return {output: [{generated_text: parsedData}]} - } else { - return this.service.suggest(this.context ? this.context + '\n\n' + content : content, options) - } - } - - async loadModeContent() { - let importsContent = '' - const imports = await this.call('codeParser', 'getImports') - for (const imp of imports.modules) { - try { - importsContent += '\n\n' + (await this.call('contentImport', 'resolve', imp)).content - } catch (e) { - console.log(e) - } - } - return importsContent - } - - async init() { - return this.service.init() - } - - async uninstall() { - this.service.terminate() - } -} 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 deleted file mode 100644 index a234b032ba..0000000000 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/suggestion-service.ts +++ /dev/null @@ -1,107 +0,0 @@ -import EventEmitter from 'events' - -export type SuggestOptions = { - max_new_tokens: number, - temperature: number, - do_sample:boolean - top_k: number, - top_p:number, - stream_result:boolean -} - -export class SuggestionService { - worker: Worker - // eslint-disable-next-line @typescript-eslint/ban-types - responses: { [key: number]: Function } - events: EventEmitter - current: number - constructor() { - this.worker = new Worker(new URL('./worker.js', import.meta.url), { - type: 'module' - }); - this.events = new EventEmitter() - this.responses = {} - this.current - } - - //todo ask Yann if we should keep the model - terminate(): void { - this.worker.terminate() - this.worker = new Worker(new URL('./worker.js', import.meta.url), { - type: 'module' - }); - } - - async init() { - const onMessageReceived = (e) => { - switch (e.data.status) { - case 'initiate': - this.events.emit(e.data.status, e.data) - // Model file start load: add a new progress item to the list. - break; - - case 'progress': - this.events.emit(e.data.status, e.data) - // Model file progress: update one of the progress items. - break; - - case 'done': - this.events.emit(e.data.status, e.data) - // Model file loaded: remove the progress item from the list. - break; - - case 'ready': - this.events.emit(e.data.status, e.data) - // Pipeline ready: the worker is ready to accept messages. - break; - - case 'update': - this.events.emit(e.data.status, e.data) - // Generation update: update the output text. - break; - - case 'complete': - if (this.responses[e.data.id]) { - if (this.current === e.data.id) { - this.responses[e.data.id](null, e.data) - } else { - this.responses[e.data.id]('aborted') - } - delete this.responses[e.data.id] - this.current = null - } - - // Generation complete: re-enable the "Generate" button - break; - } - }; - - // Attach the callback function as an event listener. - this.worker.addEventListener('message', onMessageReceived) - - this.worker.postMessage({ - cmd: 'init', - model: 'Pipper/finetuned_sol' - }) - } - - suggest (content: string, options: SuggestOptions) { - return new Promise((resolve, reject) => { - if (this.current) return reject(new Error('already running')) - const timespan = Date.now() - this.current = timespan - this.worker.postMessage({ - id: timespan, - cmd: 'suggest', - text: content, - max_new_tokens: options.max_new_tokens, - temperature: options.temperature, - top_k: options.top_k, - }) - this.responses[timespan] = (error, result) => { - if (error) return reject(error) - resolve(result) - } - }) - } -} diff --git a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js deleted file mode 100644 index 0623b3712f..0000000000 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js +++ /dev/null @@ -1,89 +0,0 @@ - -import { pipeline, env } from '@xenova/transformers'; - -env.allowLocalModels = true; - -/** - * This class uses the Singleton pattern to ensure that only one instance of the pipeline is loaded. - */ -class CodeCompletionPipeline { - static task = 'text-generation'; - static model = null - static instance = null; - - static async getInstance(progress_callback = null) { - if (this.instance === null) { - this.instance = pipeline(this.task, this.model, { progress_callback }); - } - - return this.instance; - } -} - -// Listen for messages from the main thread -self.addEventListener('message', async (event) => { - const { - id, model, text, max_new_tokens, cmd, - - // Generation parameters - temperature, - top_k, - do_sample, - } = event.data; - - if (cmd === 'init') { - // Retrieve the code-completion pipeline. When called for the first time, - // this will load the pipeline and save it for future use. - CodeCompletionPipeline.model = model - await CodeCompletionPipeline.getInstance(x => { - // We also add a progress callback to the pipeline so that we can - // track model loading. - self.postMessage(x); - }); - return - } - - if (!CodeCompletionPipeline.instance) { - // Send the output back to the main thread - self.postMessage({ - id, - status: 'error', - message: 'model not yet loaded' - }); - } - - if (cmd === 'suggest') { - // Retrieve the code-completion pipeline. When called for the first time, - // this will load the pipeline and save it for future use. - let generator = await CodeCompletionPipeline.getInstance(x => { - // We also add a progress callback to the pipeline so that we can - // track model loading. - self.postMessage(x); - }); - - // Actually perform the code-completion - let output = await generator(text, { - max_new_tokens, - temperature, - top_k, - do_sample, - - // Allows for partial output - callback_function: x => { - /*self.postMessage({ - id, - status: 'update', - output: generator.tokenizer.decode(x[0].output_token_ids, { skip_special_tokens: true }) - }); - */ - } - }); - - // Send the output back to the main thread - self.postMessage({ - id, - status: 'complete', - output: output, - }); - } -}); \ No newline at end of file diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index e443fa6c05..e1a9f3b0ec 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -1,5 +1,13 @@ import { Plugin } from '@remixproject/engine' -import {SuggestOptions} from './copilot/suggestion-service/suggestion-service' + +export type SuggestOptions = { + max_new_tokens: number, + temperature: number, + do_sample:boolean + top_k: number, + top_p:number, + stream_result:boolean +} const _paq = (window._paq = window._paq || []) @@ -14,9 +22,11 @@ const profile = { export class SolCoder extends Plugin { api_url: string + completion_url: string constructor() { super(profile) this.api_url = "https://solcoder.remixproject.org" + this.completion_url = "https://completion.remixproject.org" } async code_generation(prompt): Promise { @@ -107,7 +117,7 @@ export class SolCoder extends Plugin { let result try { result = await( - await fetch(this.api_url, { + await fetch(this.completion_url, { method: 'POST', headers: { Accept: 'application/json', @@ -118,7 +128,7 @@ export class SolCoder extends Plugin { "code_completion", "", // 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 + 30, // number (numeric value between 0 and 2000) in 'max_new_tokens' Slider component 0.9, // 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 @@ -139,9 +149,10 @@ export class SolCoder extends Plugin { this.call('terminal', 'log', { type: 'typewriterwarning', value: result.error }) return result } + return result.data } catch (e) { - this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) + this.call('terminal', 'log', { type: 'typewriterwarning', value: `Unable to get a response ${e.message}` }) return } finally { this.emit("aiInferingDone") diff --git a/apps/remix-ide/src/app/tabs/settings-tab.tsx b/apps/remix-ide/src/app/tabs/settings-tab.tsx index a09c661e50..1f69e113b6 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.tsx +++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx @@ -61,10 +61,8 @@ module.exports = class SettingsTab extends ViewPlugin { } onActivation(): void { - this.once('copilot-suggestion', 'loading', (data) => { - this.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot ...` }) - }) } + render() { return (
diff --git a/apps/remix-ide/src/remixAppManager.js b/apps/remix-ide/src/remixAppManager.js index 62692ec90d..25e25b38a5 100644 --- a/apps/remix-ide/src/remixAppManager.js +++ b/apps/remix-ide/src/remixAppManager.js @@ -81,7 +81,6 @@ let requiredModules = [ // services + layout views + system views 'home', 'doc-viewer', 'doc-gen', - 'copilot-suggestion', 'remix-templates' ] diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 0a1ab7fd81..1a82b5cffc 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -1,5 +1,6 @@ /* eslint-disable no-control-regex */ import { EditorUIProps, monacoTypes } from '@remix-ui/editor'; + import axios, {AxiosResponse} from 'axios' import { slice } from 'lodash'; const _paq = (window._paq = window._paq || []) @@ -28,16 +29,14 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli endColumn: position.column, }); - if (!word.endsWith(' ') && - !word.endsWith(';') && !word.endsWith('.') && !word.endsWith('(')) { return; } try { - const isActivate = await this.props.plugin.call('copilot-suggestion', 'isActivate') + const isActivate = await await this.props.plugin.call('settings', 'get', 'settings/copilot/suggest/activate') if (!isActivate) return } catch (err) { return; @@ -64,6 +63,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli } } } catch (e) { + console.error(e) return } @@ -84,15 +84,16 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli let result try { - result = await this.props.plugin.call('copilot-suggestion', 'suggest', word) - const generatedText = (result as any).output[0].generated_text as string + const output = await this.props.plugin.call('solcoder', 'code_completion', word) + const generatedText = output[0] 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, '').trimStart() - clean = clean.split('\n')[0].startsWith('\n') ? [clean.split('\n')[0], clean.split('\n')[1]].join('\n'): clean.split('\n')[0] + console.log('clean', clean) + clean = this.process_completion(clean) const item: monacoTypes.languages.InlineCompletion = { insertText: clean @@ -106,6 +107,16 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli } } + process_completion(data: any) { + const clean = data.split('\n')[0].startsWith('\n') ? [data.split('\n')[0], data.split('\n')[1]].join('\n'): data.split('\n')[0] + + // if clean starts with a comment, remove it + if (clean.startsWith('//') || clean.startsWith('/*') || clean.startsWith('*') || clean.startsWith('*/')){ + return "" + } + return clean + } + handleItemDidShow?(completions: monacoTypes.languages.InlineCompletions, item: monacoTypes.languages.InlineCompletion, updatedInsertText: string): void { } diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx index f9b903669d..5f3fb74378 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -134,28 +134,16 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { console.log("onchangeCopilotActivate ", props.useCopilot) if (!props.useCopilot) { copilotActivate(props.config, props.useCopilot, dispatch) - props.plugin.call('copilot-suggestion', 'uninstall') - props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot deactivated` }) + props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot deactivated!` }) return } - props.plugin.on('copilot-suggestion', 'ready', (data) => { - props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot: 100% done.` }) - }) - const startCopilot = async () => { - await props.plugin.call('copilot-suggestion', 'init') - if (await props.plugin.call('copilot-suggestion', 'status')) { - copilotActivate(props.config, true, dispatch) - } + copilotActivate(props.config, true, dispatch) + props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot activated!` }) } startCopilot() - if (props.plugin.call('copilot-suggestion', 'status')) { - copilotActivate(props.config, true, dispatch) - }else { - startCopilot() - } } useEffect(() => { From 8f61e38ed8347ec42b88c12840d3b7a2e2854090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Thu, 7 Mar 2024 14:32:49 +0100 Subject: [PATCH 2/6] removed comment from suggestion --- .../editor/src/lib/providers/inlineCompletionProvider.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 1a82b5cffc..21ba635521 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -108,12 +108,14 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli } process_completion(data: any) { - const clean = data.split('\n')[0].startsWith('\n') ? [data.split('\n')[0], data.split('\n')[1]].join('\n'): data.split('\n')[0] + let clean = data.split('\n')[0].startsWith('\n') ? [data.split('\n')[0], data.split('\n')[1]].join('\n'): data.split('\n')[0] // if clean starts with a comment, remove it if (clean.startsWith('//') || clean.startsWith('/*') || clean.startsWith('*') || clean.startsWith('*/')){ return "" } + // remove comment inline + clean = clean.split('//')[0] return clean } From ee8ea2d7f23bf17fa403fa0312944ac3b3e20bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Thu, 7 Mar 2024 15:25:34 +0100 Subject: [PATCH 3/6] added timer 2 sec to restrict completion request --- .../src/lib/providers/completionTimer.ts | 31 +++++++++++++++++++ .../lib/providers/inlineCompletionProvider.ts | 18 +++++++++-- .../settings/src/lib/remix-ui-settings.tsx | 2 -- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 libs/remix-ui/editor/src/lib/providers/completionTimer.ts diff --git a/libs/remix-ui/editor/src/lib/providers/completionTimer.ts b/libs/remix-ui/editor/src/lib/providers/completionTimer.ts new file mode 100644 index 0000000000..beb5613898 --- /dev/null +++ b/libs/remix-ui/editor/src/lib/providers/completionTimer.ts @@ -0,0 +1,31 @@ +export class CompletionTimer { + private duration: number; + private timerId: NodeJS.Timeout | null = null; + private callback: () => void; + + constructor(duration: number, callback: () => void) { + this.duration = duration; + this.callback = callback; + } + + start() { + if (this.timerId) { + console.error("Timer is already running."); + return; + } + + this.timerId = setTimeout(() => { + this.callback(); + this.timerId = null; + }, this.duration); + } + + stop() { + if (this.timerId) { + clearTimeout(this.timerId); + this.timerId = null; + } else { + console.error("Timer is not running."); + } + } +} \ No newline at end of file diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 21ba635521..6dd4f39909 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -1,5 +1,6 @@ /* eslint-disable no-control-regex */ import { EditorUIProps, monacoTypes } from '@remix-ui/editor'; +import { CompletionTimer } from './completionTimer'; import axios, {AxiosResponse} from 'axios' import { slice } from 'lodash'; @@ -12,11 +13,14 @@ const result: string = '' export class RemixInLineCompletionProvider implements monacoTypes.languages.InlineCompletionsProvider { props: EditorUIProps monaco: any + completionEnabled: boolean constructor(props: any, monaco: any) { this.props = props this.monaco = monaco + this.completionEnabled = true } + async provideInlineCompletions(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.InlineCompletionContext, token: monacoTypes.CancellationToken): Promise> { if (context.selectedSuggestionInfo) { return; @@ -82,6 +86,11 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli return } + // abort if the completion is not enabled + if (!this.completionEnabled) { + return + } + let result try { const output = await this.props.plugin.call('solcoder', 'code_completion', word) @@ -92,12 +101,17 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli clean = generatedText.replace('@custom:dev-run-script', '@custom:dev-run-script ') } clean = clean.replace(word, '').trimStart() - console.log('clean', clean) clean = this.process_completion(clean) const item: monacoTypes.languages.InlineCompletion = { insertText: clean }; + + // handle the completion timer by locking suggestions request for 2 seconds + this.completionEnabled = false + const handleCompletionTimer = new CompletionTimer(2000, () => { this.completionEnabled = true }); + handleCompletionTimer.start() + return { items: [item], enableForwardStability: true @@ -115,7 +129,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli return "" } // remove comment inline - clean = clean.split('//')[0] + clean = clean.split('//')[0].trimEnd() return clean } diff --git a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx index 5f3fb74378..4cb1c54092 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -131,7 +131,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { } const onchangeCopilotActivate = () => { - console.log("onchangeCopilotActivate ", props.useCopilot) if (!props.useCopilot) { copilotActivate(props.config, props.useCopilot, dispatch) props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity copilot deactivated!` }) @@ -426,7 +425,6 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { copilotTemperatureValue = 0.9 } - //if (isCopilotActivated) props.plugin.call('copilot-suggestion', 'init') const copilotSettings = () => (
From 20d0f373a913930f0994da496e5594407cf4c00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Tue, 12 Mar 2024 17:39:17 +0100 Subject: [PATCH 4/6] added eyplain this code to right click gpt --- libs/remix-ui/editor/src/lib/remix-ui-editor.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index adc5aadf85..d6116443c6 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -743,7 +743,7 @@ export const EditorUI = (props: EditorUIProps) => { let solgptExplainFunctionAction const executeSolgptExplainFunctionAction = { - id: 'explainFunction', + id: 'solExplainFunction', label: intl.formatMessage({id: 'editor.explainFunctionSol'}), contextMenuOrder: 1, // choose the order contextMenuGroupId: 'sol-gtp', // create a new grouping @@ -836,6 +836,8 @@ export const EditorUI = (props: EditorUIProps) => { gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction) executegptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunction'}, {name: functionImpl.name}) gptExplainFunctionAction = editor.addAction(executegptExplainFunctionAction) + executeSolgptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunctionSol'}) + solgptExplainFunctionAction = editor.addAction(executeSolgptExplainFunctionAction) }else{ executeSolgptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunctionSol'}) solgptExplainFunctionAction = editor.addAction(executeSolgptExplainFunctionAction) From 534d0f4dc337203a4c216ef06843add94749073c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Thu, 14 Mar 2024 12:19:04 +0100 Subject: [PATCH 5/6] renamed generation --- apps/remix-ide/src/app/plugins/solcoderAI.tsx | 10 ++++++++-- .../src/lib/providers/inlineCompletionProvider.ts | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index e1a9f3b0ec..49d81f7218 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -42,10 +42,15 @@ export class SolCoder extends Plugin { Accept: 'application/json', 'Content-Type': 'application/json', }, - body: JSON.stringify({"data":[prompt, "code_generation", false,1000,0.2,0.8,50]}), + body: JSON.stringify({"data":[prompt, "code_completion", "", false,1000,0.9,0.92,50]}), }) ).json() - return "error" in result? result.error : result.data[0] + console.log(result) + if ("error" in result){ + this.call('terminal', 'log', { type: 'typewriterwarning', value: result.error }) + return result + } + return result.data } catch (e) { this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) return @@ -159,4 +164,5 @@ export class SolCoder extends Plugin { } } + } diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 6dd4f39909..694af2a6b1 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -54,8 +54,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli // use the code generation model, only take max 1000 word as context this.props.plugin.call('terminal', 'log', {type: 'typewriterwarning', value: 'Solcoder - generating code for following comment: ' + ask.replace('///', '')}) - const data = await this.props.plugin.call('solcoder', 'code_completion', word) - if ("error" in data) return + const data = await this.props.plugin.call('solcoder', 'code_generation', word) const parsedData = data[0].trimStart() //JSON.parse(data).trimStart() const item: monacoTypes.languages.InlineCompletion = { From ba7815c88321b97e0ae784fd9c275c9db946a9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tetsing?= Date: Mon, 18 Mar 2024 13:03:58 +0100 Subject: [PATCH 6/6] minor refinements --- apps/remix-ide/src/app/plugins/solcoderAI.tsx | 7 +++++-- apps/remix-ide/src/assets/list.json | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index 49d81f7218..8eccbeebd6 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -32,7 +32,7 @@ export class SolCoder extends Plugin { async code_generation(prompt): Promise { this.emit("aiInfering") this.call('layout', 'maximizeTerminal') - this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for Solcoder answer...'}) + this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Code Generation: Waiting for Solcoder answer...'}) let result try { result = await( @@ -56,6 +56,7 @@ export class SolCoder extends Plugin { return }finally { this.emit("aiInferingDone") + this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Code Generation: Done'}) } } @@ -80,6 +81,7 @@ export class SolCoder extends Plugin { return }finally { this.emit("aiInferingDone") + this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Solcoder: Done'}) } if (result) { this.call('terminal', 'log', { type: 'typewriterwarning', value: result.data[0]}) @@ -92,7 +94,7 @@ export class SolCoder extends Plugin { async code_explaining(prompt): Promise { this.emit("aiInfering") this.call('layout', 'maximizeTerminal') - this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Waiting for Solcoder answer...'}) + this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Explain Code: Waiting for Solcoder answer...'}) let result try { result = await( @@ -114,6 +116,7 @@ export class SolCoder extends Plugin { return }finally { this.emit("aiInferingDone") + this.call('terminal', 'log', { type: 'typewriterwarning', value: 'Explaining: Done'}) } } diff --git a/apps/remix-ide/src/assets/list.json b/apps/remix-ide/src/assets/list.json index b22d882d4b..04a4929e01 100644 --- a/apps/remix-ide/src/assets/list.json +++ b/apps/remix-ide/src/assets/list.json @@ -1091,9 +1091,22 @@ "bzzr://c604bdd6384bf73594cd0e5cfbe979048191549ebc88e70996346f3b744c0680", "dweb:/ipfs/QmW2SQbEhiz3n2qV5iL8WBgzapv6cXjkLStvTMpCZhvr2x" ] + }, + { + "path": "soljson-v0.8.25+commit.b61c2a91.js", + "version": "0.8.25", + "build": "commit.b61c2a91", + "longVersion": "0.8.25+commit.b61c2a91", + "keccak256": "0x4639103a26b2f669bd3ecc22b1a1665819f2a2956f917ab91380bd9565dbcd01", + "sha256": "0xf8c9554471ff2db3843167dffb7a503293b5dc728c8305b044ef9fd37d626ca7", + "urls": [ + "bzzr://d201e60bd46193b11382988a854132b9e7fb0e1574cc766cb7f9efe8e44a680c", + "dweb:/ipfs/QmdduJxmPXungjJk2FBDw1bdDQ6ucHxYGLXRMBJqMFW7h9" + ] } ], "releases": { + "0.8.25": "soljson-v0.8.25+commit.b61c2a91.js", "0.8.24": "soljson-v0.8.24+commit.e11b9ed9.js", "0.8.23": "soljson-v0.8.23+commit.f704f362.js", "0.8.22": "soljson-v0.8.22+commit.4fc1097e.js", @@ -1186,5 +1199,5 @@ "0.4.0": "soljson-v0.4.0+commit.acd334c9.js", "0.3.6": "soljson-v0.3.6+commit.3fc68da5.js" }, - "latestRelease": "0.8.24" + "latestRelease": "0.8.25" } \ No newline at end of file