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 e094677026..6c474fa8ba 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,6 +31,7 @@ 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/tabs/settings-tab.tsx b/apps/remix-ide/src/app/tabs/settings-tab.tsx index 7954bf5d36..61710675af 100644 --- a/apps/remix-ide/src/app/tabs/settings-tab.tsx +++ b/apps/remix-ide/src/app/tabs/settings-tab.tsx @@ -62,8 +62,7 @@ module.exports = class SettingsTab extends ViewPlugin { onActivation(): void { this.on('copilot-suggestion', 'loading', (data) => { - this.call('terminal', 'log', { type: 'typewritererror', value: `.` }) - console.log("oninit") + this.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot: ${(data.loaded / data.total) * 100}%.` }) }) } render() { diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts index 9944f29ec4..687b961233 100644 --- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts +++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts @@ -15,7 +15,6 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli 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> { @@ -49,24 +48,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('///') && (!this.running)) { + if (split[split.length - 1].trim() === '' && ask.startsWith('///')) { // use the code generation model, only take max 1000 word as context - this.running = true + this.props.plugin.call('terminal', 'log', {type: 'typewritersuccess', value: 'Solcoder - generating code for following comment: ' + ask}) + const data = await this.props.plugin.call('solcoder', 'code_completion', word) 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) { - console.error(e) - } + return + } if (word.split('\n').at(-1).trimStart().startsWith('//') || word.split('\n').at(-1).trimStart().startsWith('/*') || @@ -84,37 +83,33 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli let result try { - if (!this.running){ - result = await this.props.plugin.call('copilot-suggestion', 'suggest', word) - this.running = true + result = await this.props.plugin.call('copilot-suggestion', 'suggest', word) + this.running=false + 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, '') + + const item: monacoTypes.languages.InlineCompletion = { + insertText: clean + }; + return { + items: [item], + enableForwardStability: true } } catch (err) { this.running=false return } - - 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, '') - - 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 - } - + } 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 6d3e733cd5..7a584f5ae4 100644 --- a/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx +++ b/libs/remix-ui/settings/src/lib/remix-ui-settings.tsx @@ -9,6 +9,7 @@ enum CONSENT { NOT_GIVEN, NOT_ASKED } +let consentGivenForAI = CONSENT.NOT_ASKED import './remix-ui-settings.css' import { @@ -62,7 +63,6 @@ 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') @@ -129,15 +129,6 @@ 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) { - const a = async () => await onchangeCopilotActivate() - } - console.log("useEffect on useCopilot finish") - }, [props.useCopilot]) - const onchangeGenerateContractMetadata = (event) => { generateContractMetadat(props.config, event.target.checked, dispatch) } @@ -151,65 +142,38 @@ export const RemixUiSettings = (props: RemixUiSettingsProps) => { 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) => { - 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 + props.plugin.call('terminal', 'log', {type: 'typewriterlog', value: `loading Solidity copilot: ${(data.loaded / data.total) * 100}% done.` }) }) 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: 'OK', - //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) { - 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 (await props.plugin.call('copilot-suggestion', 'status')) { copilotActivate(props.config, true, dispatch) - } else { - props.plugin.call('copilot-suggestion', 'uninstall') - copilotActivate(props.config, false, dispatch) + }else { + startCopilot() } } + 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) }