From e45875ce06c51087ef3066d30adb4dab0b5d4c66 Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:01:51 +0100 Subject: [PATCH] Revert "removed user consens" --- .../suggestion-service/copilot-suggestion.ts | 1 - .../copilot/suggestion-service/worker.js | 1 + apps/remix-ide/src/app/plugins/solcoderAI.tsx | 10 +-- apps/remix-ide/src/app/tabs/settings-tab.tsx | 3 +- apps/remixdesktop/src/menus/view.ts | 90 +++++++++++++++++++ .../lib/providers/inlineCompletionProvider.ts | 71 +++++++-------- .../settings/src/lib/remix-ui-settings.tsx | 77 ++++++++++++---- 7 files changed, 187 insertions(+), 66 deletions(-) create mode 100644 apps/remixdesktop/src/menus/view.ts 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 6c474fa8ba..e094677026 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 @@ -31,7 +31,6 @@ export class CopilotSuggestion extends Plugin { this.service.events.on('done', (data) => { }) this.service.events.on('ready', (data) => { - this.emit('ready', data) this.ready = true }) } 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 0623b3712f..04b77ba634 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 @@ -22,6 +22,7 @@ class CodeCompletionPipeline { // Listen for messages from the main thread self.addEventListener('message', async (event) => { + console.log("worker message ", event.data) const { id, model, text, max_new_tokens, cmd, diff --git a/apps/remix-ide/src/app/plugins/solcoderAI.tsx b/apps/remix-ide/src/app/plugins/solcoderAI.tsx index cdf2af2f1b..aa99c74f3a 100644 --- a/apps/remix-ide/src/app/plugins/solcoderAI.tsx +++ b/apps/remix-ide/src/app/plugins/solcoderAI.tsx @@ -35,7 +35,7 @@ export class SolCoder extends Plugin { body: JSON.stringify({"data":[prompt, "code_generation", false,1000,0.2,0.8,50]}), }) ).json() - return "error" in result? result.error : result.data[0] + return result.data[0] } catch (e) { this.call('terminal', 'log', { type: 'typewritererror', value: `Unable to get a response ${e.message}` }) return @@ -91,7 +91,7 @@ export class SolCoder extends Plugin { }) ).json() if (result) { - this.call('terminal', 'log', { type: 'typewriterwarning', value: "\n"+result.data[0]}) + this.call('terminal', 'log', { type: 'typewriterwarning', value: result.data[0]}) } return result.data[0] } catch (e) { @@ -135,12 +135,6 @@ export class SolCoder extends Plugin { }) ).json() - if ("error" in result){ - console.log("error", result.error) - 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}` }) diff --git a/apps/remix-ide/src/app/tabs/settings-tab.tsx b/apps/remix-ide/src/app/tabs/settings-tab.tsx index 61710675af..7954bf5d36 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.tsx +++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx @@ -62,7 +62,8 @@ module.exports = class SettingsTab extends ViewPlugin { onActivation(): void { this.on('copilot-suggestion', 'loading', (data) => { - this.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot: ${(data.loaded / data.total) * 100}%.` }) + this.call('terminal', 'log', { type: 'typewritererror', value: `.` }) + console.log("oninit") }) } render() { diff --git a/apps/remixdesktop/src/menus/view.ts b/apps/remixdesktop/src/menus/view.ts new file mode 100644 index 0000000000..e488cfa50e --- /dev/null +++ b/apps/remixdesktop/src/menus/view.ts @@ -0,0 +1,90 @@ +import {BrowserWindow, MenuItemConstructorOptions} from 'electron'; + +export default ( + commandKeys: Record, + execCommand: (command: string, focusedWindow?: BrowserWindow) => void +): MenuItemConstructorOptions => { + const isMac = process.platform === 'darwin'; + + return { + label: 'View', + submenu: [ + { + label: 'Toggle Developer Tools', + accelerator: (function() { + if (process.platform === 'darwin') + return 'Alt+Command+I'; + else + return 'Ctrl+Shift+I'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.webContents.toggleDevTools(); + } + }, + { + label: 'Reload', + accelerator: 'CmdOrCtrl+R', + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.reload(); + } + }, + { + label: 'Toggle Full Screen', + accelerator: (function() { + if (process.platform === 'darwin') + + return 'Ctrl+Command+F'; + else + return 'F11'; + })(), + click: function(item, focusedWindow) { + if (focusedWindow) + focusedWindow.setFullScreen(!focusedWindow.isFullScreen()); + } + }, + { + label: 'Zoom In', + accelerator: 'CmdOrCtrl+=', + click: function(item, focusedWindow) { + if (focusedWindow){ + let factor = focusedWindow.webContents.getZoomFactor() + if (factor < 4) { + factor = factor + 0.25 + focusedWindow.webContents.setZoomFactor(factor) + } + } + } + }, + { + label: 'Zoom Out', + accelerator: 'CmdOrCtrl+-', + click: function(item, focusedWindow) { + if (focusedWindow){ + let factor = focusedWindow.webContents.getZoomFactor() + console.log(factor) + if (factor > 1.25) { + factor = factor - 0.25 + focusedWindow.webContents.setZoomFactor(factor) + }else{ + focusedWindow.webContents.setZoomFactor(1) + } + + } + } + }, + { + label: 'Reset Zoom', + accelerator: 'CmdOrCtrl+0', + click: function(item, focusedWindow) { + if (focusedWindow) + { + focusedWindow.webContents.setZoomFactor(1) + } + } + }, + + ] + }; +}; diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 1090c7c5d5..9944f29ec4 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -11,9 +11,11 @@ const result: string = '' export class RemixInLineCompletionProvider implements monacoTypes.languages.InlineCompletionsProvider { props: EditorUIProps monaco: any + running:boolean constructor(props: any, monaco: any) { this.props = props this.monaco = monaco + this.running = false } async provideInlineCompletions(model: monacoTypes.editor.ITextModel, position: monacoTypes.Position, context: monacoTypes.languages.InlineCompletionContext, token: monacoTypes.CancellationToken): Promise> { @@ -47,26 +49,24 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli const split = word.split('\n') if (split.length < 2) return const ask = split[split.length - 2].trimStart() - if (split[split.length - 1].trim() === '' && ask.startsWith('///')) { + if (split[split.length - 1].trim() === '' && ask.startsWith('///') && (!this.running)) { // 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('///', '')}) - + this.running = true const data = await this.props.plugin.call('solcoder', 'code_completion', word) - if ("error" in data) return - console.log("solcoder completion data", data) const parsedData = data[0].trimStart() //JSON.parse(data).trimStart() const item: monacoTypes.languages.InlineCompletion = { insertText: parsedData }; + this.running =false return { items: [item], enableForwardStability: true } } } catch (e) { - return - } + console.error(e) + } if (word.split('\n').at(-1).trimStart().startsWith('//') || word.split('\n').at(-1).trimStart().startsWith('/*') || @@ -84,47 +84,38 @@ 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 - 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, '') - clean = this.process_completion(clean) - - const item: monacoTypes.languages.InlineCompletion = { - insertText: clean - }; - return { - items: [item], - enableForwardStability: true + if (!this.running){ + result = await this.props.plugin.call('copilot-suggestion', 'suggest', word) + this.running = true } } catch (err) { + this.running=false return } - } - process_completion(data: any) { - const lines = data.split('\n') - const result = [] - let incode = 0 - for (const line of lines){ - if (line.includes('{')) incode += 1 - if (line.includes('}')) incode -= 1 - - if (!line.includes('//') || !line.endsWith('}')) result.push(line) - if (incode === 0) { - return result.join('\n').trimStart() - } + const generatedText = (result as any).output[0].generated_text as string + let clean = generatedText + console.log('solcoder inline data:\n', clean) + if (generatedText.indexOf('@custom:dev-run-script./') !== -1) { + clean = generatedText.replace('@custom:dev-run-script', '@custom:dev-run-script ') + } + clean = clean.replace(word, '') - if (incode <= 0 && line.includes('}')) { - return result.join('\n').trimStart() - } + const item: monacoTypes.languages.InlineCompletion = { + insertText: clean + }; + this.running=false + + // abort if there is a signal + if (token.isCancellationRequested) { + return + } + return { + items: [item], + enableForwardStability: true } - return result.join('\n').trimStart() - } + } 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 db7e810eb7..aeaa5f8b22 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -4,6 +4,11 @@ import React, {useState, useRef, useReducer, useEffect, useCallback} from 'react import {AppModal, AlertModal, ModalTypes} from '@remix-ui/app' import {labels, textDark, textSecondary} from './constants' +enum CONSENT { + GIVEN = 0, + NOT_GIVEN, + NOT_ASKED +} import './remix-ui-settings.css' import { @@ -57,6 +62,7 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { const [ipfsProjectSecret, setipfsProjectSecret] = useState('') const copilotDownload = useRef(null) + let consentGivenForAI = CONSENT.NOT_ASKED const intl = useIntl() const initValue = () => { const metadataConfig = props.config.get('settings/generate-contract-metadata') @@ -123,6 +129,15 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { if (props.useMatomoAnalytics !== null) useMatomoAnalytics(props.config, props.useMatomoAnalytics, dispatch) }, [props.useMatomoAnalytics]) + useEffect(() => { + console.log("useEffect on useCopilot") + if (props.useCopilot !== null) copilotActivate(props.config, props.useCopilot, dispatch) + if (props.useCopilot) { + onchangeCopilotActivate() + } + console.log("useEffect on useCopilot finish") + }, [props.useCopilot]) + const onchangeGenerateContractMetadata = (event) => { generateContractMetadat(props.config, event.target.checked, dispatch) } @@ -132,40 +147,70 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { } const onchangeCopilotActivate = () => { + 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` }) return } + const message =
Please wait while the copilot is downloaded. 0/100 .
props.plugin.on('copilot-suggestion', 'loading', (data) => { - props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot: ${(data.loaded / data.total) * 100}% done.` }) + 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 startCopilot = async () => { await props.plugin.call('copilot-suggestion', 'init') + 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) + } + } + const modalActivate: AppModal = { + id: 'loadcopilotActivate', + title: 'Download Solidity copilot', + modalType: ModalTypes.default, + okLabel: 'Hide', + cancelLabel: 'Cancel', + message, + okFn: async() => { + consentGivenForAI = CONSENT.GIVEN + startCopilot() + }, + hideFn: async () => { + consentGivenForAI = CONSENT.NOT_GIVEN + 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 (consentGivenForAI === CONSENT.NOT_ASKED) { + console.log("CONSENT.NOT_ASKED modal") + props.plugin.call('notification', 'modal', modalActivate) + } else if (consentGivenForAI === CONSENT.GIVEN) { + startCopilot() + } else { + // NOT_GIVEN } - - props.plugin.on('copilot-suggestion', 'ready', (data) => { - copilotActivate(props.config, true, dispatch) - props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `Solidity Copilot activated` }) - }) if (props.plugin.call('copilot-suggestion', 'status')) { copilotActivate(props.config, true, dispatch) } else { - startCopilot() + props.plugin.call('copilot-suggestion', 'uninstall') + copilotActivate(props.config, false, dispatch) } } - useEffect(() => { - if (props.useCopilot !== null) copilotActivate(props.config, props.useCopilot, dispatch) - onchangeCopilotActivate() - }, [props.useCopilot]) - const onchangeCopilotMaxNewToken = (event) => { copilotMaxNewToken(props.config, parseInt(event.target.value), dispatch) } @@ -437,8 +482,8 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { } let copilotTemperatureValue = (props.config.get('settings/copilot/suggest/temperature')) * 100 if (!copilotTemperatureValue) { - props.config.set('settings/copilot/suggest/temperature', 0.9) - copilotTemperatureValue = 0.9 + props.config.set('settings/copilot/suggest/temperature', 0.5) + copilotTemperatureValue = 0.5 } //if (isCopilotActivated) props.plugin.call('copilot-suggestion', 'init')