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 a7d8e5fbfa..708243fca8 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,14 +8,13 @@ const profile = { name: 'copilot-suggestion', displayName: 'copilot-suggestion', description: 'Get Solidity suggestions in editor', - methods: ['suggest', 'init', 'uninstall', 'status', 'isActivate', 'useRemoteService', 'discardRemoteService', 'useconfig'], + methods: ['suggest', 'init', 'uninstall', 'status', 'isActivate', 'discardRemoteService', 'useconfig'], version: '0.1.0-alpha', maintainedBy: "Remix" } export class CopilotSuggestion extends Plugin { service: SuggestionService - remoteService: string context: string ready: boolean config: { [id: string]: string } @@ -23,27 +22,17 @@ export class CopilotSuggestion extends Plugin { super(profile) this.service = new SuggestionService() this.context = '' - this.service.events.on('progress', (data) => { - this.emit('loading', data) - }) - this.service.events.on('done', (data) => { - }) - this.service.events.on('ready', (data) => { - this.ready = true - }) + this.ready = true // always ready for service this.config = {} } - useRemoteService(service: string) { - this.remoteService = service - } useconfig(config ){ this.config = config } discardRemoteService() { - this.remoteService = null + this.ready = false } status () { @@ -65,22 +54,19 @@ export class CopilotSuggestion extends Plugin { 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: false, - top_k: 0, - top_p: 0, + top_k: 50, + top_p: 0.92, stream_result: false, - temperature: temperature || 0, + temperature: temperature || 0.9, max_new_tokens: max_new_tokens || 0 } - if (this.remoteService) { - 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() + if (this.ready){ + const data = await this.call('solcoder', 'code_completion', content.split(" ").slice(-1000).join(" "), options) + const parsedData = data[0].trimStart() return {output: [{generated_text: parsedData}]} - } else { - return this.service.suggest(this.context ? this.context + '\n\n' + content : content, options) + }else{ + return } } 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 4ec2d864dd..49323aeda6 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,10 @@ import EventEmitter from 'events' -export type SuggestOptions = { max_new_tokens: number, temperature: number, top_k: number, top_p:number, do_sample: boolean, stream_result:boolean} +export type SuggestOptions = { max_new_tokens: number, + temperature: number, + top_k: number, + top_p:number, + stream_result:boolean} export class SuggestionService { worker: Worker @@ -89,7 +93,6 @@ export class SuggestionService { max_new_tokens: options.max_new_tokens, temperature: options.temperature, top_k: options.top_k, - do_sample: options.do_sample }) this.responses[timespan] = (error, result) => { if (error) return reject(error) 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 index a5affc48b1..864c56737d 100644 --- a/apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js +++ b/apps/remix-ide/src/app/plugins/copilot/suggestion-service/worker.js @@ -35,12 +35,12 @@ self.addEventListener('message', async (event) => { 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); - }); + // 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 } @@ -48,8 +48,8 @@ self.addEventListener('message', async (event) => { // Send the output back to the main thread self.postMessage({ id, - status: 'error', - message: 'model not yet loaded' + status: 'info', + message: 'model not longer supported' }); } diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index 65b7040306..298dcdde36 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -1,4 +1,5 @@ import { Plugin } from '@remixproject/engine' +import {SuggestOptions} from './copilot/suggestion-service/suggestion-service' const _paq = (window._paq = window._paq || []) @@ -6,7 +7,7 @@ const profile = { name: 'solcoder', displayName: 'solcoder', description: 'solcoder', - methods: ['code_generation', 'code_completion'], + methods: ['code_generation', 'code_completion', "solidity_answer"], events: [], maintainedBy: 'Remix', } @@ -31,6 +32,28 @@ export class SolCoder extends Plugin { body: JSON.stringify({"data":[prompt,false,1000,0.2,0.8,50]}), }) ).json() + return result.data[0] + } catch (e) { + this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) + return + } + } + + async solidity_answer(prompt): Promise { + this.call('layout', 'maximizeTerminal') + this.call('terminal', 'log', 'Waiting for Solcoder answer...') + let result + try { + result = await( + await fetch("https://hkfll35zthu6e2-7861.proxy.runpod.net/api/solidity_answer", { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({"data":[prompt,false,1000,0.9,0.8,50]}), + }) + ).json() } catch (e) { this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) return @@ -44,7 +67,7 @@ export class SolCoder extends Plugin { } - async code_completion(prompt): Promise { + async code_completion(prompt, options:SuggestOptions=null): Promise { let result try { result = await( @@ -54,19 +77,27 @@ export class SolCoder extends Plugin { Accept: 'application/json', 'Content-Type': 'application/json', }, - body: JSON.stringify({"data":[ - 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 - ]}), + body: JSON.stringify({"data": !options? [ + 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.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 + ] : [ + prompt, + "", + options.stream_result, + options.max_new_tokens, + options.temperature, + options.top_p, + options.top_k + ] + }), }) ).json() - console.log('solcoder result', result.data) return result.data } catch (e) { this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index c6e0c19515..4744139524 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -41,10 +41,9 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli if (split.length < 2) return const ask = split[split.length - 2].trimStart() if (split[split.length - 1].trim() === '' && ask.startsWith('///')) { - // use the code generation model - - const data = await this.props.plugin.call('solcoder', 'code_completion', word) - console.log("received solcoder data", data) + // use the code generation model, only take max 1000 word as context + const data = await this.props.plugin.call('solcoder', 'code_completion', word.split(" ").slice(-1000).join(" ")) + console.log("solcoder completion data", data) const parsedData = data[0].trimStart() //JSON.parse(data).trimStart() const item: monacoTypes.languages.InlineCompletion = { insertText: parsedData @@ -62,8 +61,17 @@ 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 let clean = generatedText + console.log('solcoder inline data:\n', clean) const item: monacoTypes.languages.InlineCompletion = { insertText: 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 34bac76242..8b0600f509 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -134,41 +134,15 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { copilotActivate(props.config, event.target.checked, dispatch) props.plugin.call('copilot-suggestion', 'uninstall') return - } - const message =
Please wait while the copilot is downloaded. 0/100 .
- props.plugin.on('copilot-suggestion', 'loading', (data) => { - if (!copilotDownload.current) return - const loaded = ((data.loaded / data.total) * 100).toString() - const dot = loaded.match(/(.*)\./g) - copilotDownload.current.innerText = dot ? dot[0].replace('.', '') : loaded - }) - const modalActivate: AppModal = { - id: 'loadcopilotActivate', - title: 'Download Solidity copilot', - modalType: ModalTypes.default, - okLabel: 'Close', - message, - okFn: async() => { - props.plugin.off('copilot-suggestion', 'loading') - if (await props.plugin.call('copilot-suggestion', 'status')) { - copilotActivate(props.config, true, dispatch) - } else { - props.plugin.call('copilot-suggestion', 'uninstall') - copilotActivate(props.config, false, dispatch) - } - }, - hideFn: async () => { - props.plugin.off('copilot-suggestion', 'loading') - if (await props.plugin.call('copilot-suggestion', 'status')) { - copilotActivate(props.config, true, dispatch) - } else { - props.plugin.call('copilot-suggestion', 'uninstall') - copilotActivate(props.config, false, dispatch) - } - } + } + if (await props.plugin.call('copilot-suggestion', 'status')) { + copilotActivate(props.config, true, dispatch) + } else { + props.plugin.call('copilot-suggestion', 'uninstall') + copilotActivate(props.config, false, dispatch) } + props.plugin.call('copilot-suggestion', 'init') - props.plugin.call('notification', 'modal', modalActivate) } diff --git a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx index 3a35adbf08..1cea4662a0 100644 --- a/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx +++ b/libs/remix-ui/terminal/src/lib/remix-ui-terminal.tsx @@ -239,9 +239,9 @@ export const RemixUiTerminal = (props: RemixUiTerminalProps) => { call('terminal', 'log',{ type: 'warn', value: `> ${script}` }) await call('openaigpt', 'message', script) _paq.push(['trackEvent', 'ai', 'openai', 'askFromTerminal']) - } else if (script.trim().startsWith('gpt-sol')) { + } else if (script.trim().startsWith('sol-gpt')) { call('terminal', 'log',{ type: 'warn', value: `> ${script}` }) - await call('solcoder', 'code_generation', script) + await call('solcoder', 'solidity_answer', script) _paq.push(['trackEvent', 'ai', 'solcoder', 'askFromTerminal']) }else { await call('scriptRunner', 'execute', script) diff --git a/libs/remix-ui/terminal/src/lib/utils/wrapScript.ts b/libs/remix-ui/terminal/src/lib/utils/wrapScript.ts index 26ded2f581..41d027b12d 100644 --- a/libs/remix-ui/terminal/src/lib/utils/wrapScript.ts +++ b/libs/remix-ui/terminal/src/lib/utils/wrapScript.ts @@ -1,5 +1,5 @@ export const wrapScript = (script) => { - const isKnownScript = ['remix.', 'console.', 'git', 'gpt'].some(prefix => script.trim().startsWith(prefix)) + const isKnownScript = ['remix.', 'console.', 'git', 'gpt', 'sol-gpt'].some(prefix => script.trim().startsWith(prefix)) if (isKnownScript) return script return ` try {