added code explain on selection and right click. Gpt function explanation still available

explain_function
Stéphane Tetsing 9 months ago
parent 1a7d5c1c2c
commit 9398cb0a8b
  1. 2
      apps/remix-ide/src/app/tabs/locales/en/editor.json
  2. 3
      libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
  3. 30
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  4. 89
      libs/remix-ui/editor/src/lib/suggestion-service/suggestion-service.ts
  5. 2
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx

@ -23,8 +23,10 @@
"editor.generateDocumentation2": "Generate documentation for the function \"{name}\"",
"editor.generateDocumentationByAI": "solidity code: {content}\n Generate the documentation for the function {currentFunction} using the Doxygen style syntax",
"editor.explainFunction": "Explain this function",
"editor.explainFunctionSol": "Explain this code",
"editor.explainFunction2": "Explain the function \"{name}\"",
"editor.explainFunctionByAI": "solidity code: {content}\n Explain the function {currentFunction}",
"editor.explainFunctionByAISol": "solidity code: {content}\n Explain the function {currentFunction}",
"editor.executeFreeFunction": "Run a free function",
"editor.executeFreeFunction2": "Run the free function \"{name}\"",
"editor.toastText1": "This can only execute free function",

@ -31,8 +31,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
});
if (!word.endsWith(' ') &&
!word.endsWith('\n') &&
if (!word.endsWith('\n') &&
!word.endsWith(';') &&
!word.endsWith('.') &&
!word.endsWith('(')) {

@ -3,7 +3,7 @@ import { FormattedMessage, useIntl } from 'react-intl'
import { isArray } from 'lodash'
import Editor, { loader, Monaco } from '@monaco-editor/react'
import { AlertModal } from '@remix-ui/app'
import { QueryParams } from '@remix-project/remix-lib'
import { ConsoleLogs, QueryParams } from '@remix-project/remix-lib'
import { reducerActions, reducerListener, initialState } from './actions/editor'
import { solidityTokensProvider, solidityLanguageConfig } from './syntaxes/solidity'
import { cairoTokensProvider, cairoLanguageConfig } from './syntaxes/cairo'
@ -741,6 +741,24 @@ export const EditorUI = (props: EditorUIProps) => {
},
}
let solgptExplainFunctionAction
const executeSolgptExplainFunctionAction = {
id: 'explainFunction',
label: intl.formatMessage({id: 'editor.explainFunctionSol'}),
contextMenuOrder: 1, // choose the order
contextMenuGroupId: 'sol-gtp', // create a new grouping
keybindings: [],
run: async () => {
const file = await props.plugin.call('fileManager', 'getCurrentFile')
const content = await props.plugin.call('fileManager', 'readFile', file)
const selectedCode = editor.getModel().getValueInRange(editor.getSelection())
await props.plugin.call('solcoder', 'code_explaining', selectedCode)
_paq.push(['trackEvent', 'ai', 'solcoder', 'explainFunction'])
},
}
const freeFunctionCondition = editor.createContextKey('freeFunctionCondition', false)
let freeFunctionAction
const executeFreeFunctionAction = {
@ -775,6 +793,7 @@ export const EditorUI = (props: EditorUIProps) => {
freeFunctionAction = editor.addAction(executeFreeFunctionAction)
gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction)
gptExplainFunctionAction = editor.addAction(executegptExplainFunctionAction)
solgptExplainFunctionAction = editor.addAction(executeSolgptExplainFunctionAction)
// we have to add the command because the menu action isn't always available (see onContextMenuHandlerForFreeFunction)
editor.addCommand(monacoRef.current.KeyMod.Shift | monacoRef.current.KeyMod.Alt | monacoRef.current.KeyCode.KeyR, () => executeFreeFunctionAction.run())
@ -794,6 +813,10 @@ export const EditorUI = (props: EditorUIProps) => {
gptExplainFunctionAction.dispose()
gptExplainFunctionAction = null
}
if (solgptExplainFunctionAction) {
solgptExplainFunctionAction.dispose()
solgptExplainFunctionAction = null
}
const file = await props.plugin.call('fileManager', 'getCurrentFile')
if (!file.endsWith('.sol')) {
@ -811,8 +834,11 @@ export const EditorUI = (props: EditorUIProps) => {
currentFunction.current = functionImpl.name
executeGptGenerateDocumentationAction.label = intl.formatMessage({id: 'editor.generateDocumentation2'}, {name: functionImpl.name})
gptGenerateDocumentationAction = editor.addAction(executeGptGenerateDocumentationAction)
executegptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunction2'}, {name: functionImpl.name})
executegptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunction'}, {name: functionImpl.name})
gptExplainFunctionAction = editor.addAction(executegptExplainFunctionAction)
}else{
executeSolgptExplainFunctionAction.label = intl.formatMessage({id: 'editor.explainFunctionSol'})
solgptExplainFunctionAction = editor.addAction(executeSolgptExplainFunctionAction)
}
freeFunctionCondition.set(!!freeFunctionNode)
}

@ -0,0 +1,89 @@
import EventEmitter from 'events'
export class SuggestionService {
worker: Worker
responses: Array<any>
events: EventEmitter
constructor() {
console.log('SuggestionService instanciate worker')
this.worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module'
});
this.init()
this.events = new EventEmitter()
this.responses = []
}
async init() {
const onMessageReceived = (e) => {
switch (e.data.status) {
case 'initiate':
console.log(e.data)
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)
console.log(e.data)
// Model file progress: update one of the progress items.
break;
case 'done':
this.events.emit(e.data.status, e.data)
console.log(e.data)
// Model file loaded: remove the progress item from the list.
break;
case 'ready':
this.events.emit(e.data.status, e.data)
console.log(e.data)
// Pipeline ready: the worker is ready to accept messages.
break;
case 'update':
this.events.emit(e.data.status, e.data)
console.log(e.data)
// Generation update: update the output text.
break;
case 'complete':
console.log(e.data)
if (this.responses[e.data.id]) {
this.responses[e.data.id](null, e.data)
} else {
console.log('no callback for', e.data)
}
// 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/solstarcoder'
})
}
suggest (content: string, max_new_tokens: number, temperature: number, top_k: number, do_sample: boolean) {
return new Promise((resolve, reject) => {
this.worker.postMessage({
id: this.responses.length,
cmd: 'suggest',
text: content,
max_new_tokens,
temperature,
top_k,
do_sample
})
this.responses.push((error, result) => {
if (error) return reject(error)
resolve(result)
})
})
}
}

@ -62,7 +62,7 @@ export const TabsUI = (props: TabsUIProps) => {
const currentIndexRef = useRef(-1)
const tabsRef = useRef({})
const tabsElement = useRef(null)
const [ai_switch, setAI_switch] = useState<boolean>(true)
const [ai_switch, setAI_switch] = useState<boolean>(false)
const tabs = useRef(props.tabs)
tabs.current = props.tabs // we do this to pass the tabs list to the onReady callbacks

Loading…
Cancel
Save