Skip to content

Commit

Permalink
Merge branch 'master' into workspace_completion
Browse files Browse the repository at this point in the history
  • Loading branch information
STetsing authored Jan 29, 2025
2 parents 5f4e10e + 2b9a1e3 commit abef016
Show file tree
Hide file tree
Showing 56 changed files with 414 additions and 204 deletions.
2 changes: 1 addition & 1 deletion .env → .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ gist_token=<token>
account_passphrase=<passphrase>
account_password=<password>
NODE_OPTIONS=--max-old-space-size=2048
# WALLET_CONNECT_PROJECT_ID=<walletconnect cloud PROJECT_ID>
WALLET_CONNECT_PROJECT_ID=<project_id>
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ soljson.js
*_group*.ts
stats.json
release
.env


# compiled output
Expand Down
13 changes: 8 additions & 5 deletions apps/remix-dapp/src/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@
"udapp.hash": "hash",
"udapp.signature": "signature",
"udapp.forkStateTitle": "Fork VM state",
"udapp.forkStateLabel": "State Name",
"udapp.forkStateLabel": "New environment name",
"udapp.forkVmStateDesc1":"Forking state will create a new environment with same state as selected environment",
"udapp.forkVmStateDesc2":"New environment will be pinned, which can be unpinned or deleted using Envionment Explorer",
"udapp.fork": "Fork",
"udapp.deleteVmStateTitle": "Delete VM state",
"udapp.deleteVmStateDesc1": "Deleting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.deleteVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.deleteVmStateDesc3": "Do you want to continue?",
"udapp.resetVmStateTitle": "Reset VM state",
"udapp.resetVmStateDesc1": "Resetting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.resetVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.resetVmStateDesc3": "Do you want to continue?",
"udapp.reset": "Reset",
"udapp.delete": "Delete",
"udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).",
"udapp.createNewAccount": "Create a new account",
Expand Down
2 changes: 1 addition & 1 deletion apps/remix-ide-e2e/src/tests/remixd.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ async function installFoundry(): Promise<void> {
server.stdout.on('data', function (data) {
console.log(data.toString())
if (
data.toString().includes("foundryup: done!")
data.toString().includes("foundryup: use - chisel 0.3.0")
) {
console.log('resolving')
resolve()
Expand Down
3 changes: 1 addition & 2 deletions apps/remix-ide-e2e/src/tests/terminal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ module.exports = {
.journalChildIncludes('inside getOwner', { shouldHaveOnlyOneOccurrence: true })
},

'Emit 2 similar events and check the filtering is done properly #group4': function (browser: NightwatchBrowser) {
'Emit 2 similar events and check the filtering is done properly #group11': function (browser: NightwatchBrowser) {
let addressRef: string
browser
.addFile('contracts/contract_with_event.sol', { content: contract_with_event })
Expand All @@ -204,7 +204,6 @@ module.exports = {
.clickLaunchIcon('solidity')
.click('*[data-id="compilerContainerCompileBtn"]')
.clickLaunchIcon('udapp')
.click('*[data-id="deployAndRunClearInstances"]')
.selectContract('Example')
.createContract('')
.getAddressAtPosition(0, (address) => {
Expand Down
8 changes: 4 additions & 4 deletions apps/remix-ide-e2e/src/tests/vm_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const tests = {
.click('*[data-id="delete-state-icon"]')
.waitForElementVisible(
{
selector: "//*[@data-shared='tooltipPopup' and contains(.,'State not available to delete')]",
selector: "//*[@data-shared='tooltipPopup' and contains(.,'State not available to reset')]",
locateStrategy: 'xpath'
}
)
Expand Down Expand Up @@ -65,7 +65,7 @@ const tests = {
// check toaster for forked state
.waitForElementVisible(
{
selector: '//*[@data-shared="tooltipPopup" and contains(.,"VM state \'forkedState_1\' forked")]',
selector: '//*[@data-shared="tooltipPopup" and contains(.,"New environment \'forkedState_1\' created with forked state.")]',
locateStrategy: 'xpath'
}
)
Expand Down Expand Up @@ -105,7 +105,7 @@ const tests = {
.setValue('input[data-id="modalDialogForkState"]', 'forkedState_2')
.modalFooterOKClick('udappNotify')
.waitForElementVisible('*[data-shared="tooltipPopup"]', 10000)
.assert.textContains('*[data-shared="tooltipPopup"]', `VM state 'forkedState_2' forked and selected as current environment.`)
.assert.textContains('*[data-shared="tooltipPopup"]', `New environment 'forkedState_2' created with forked state.`)
// check if 'forkedState_2' is selected as current environment
.assert.elementPresent('*[data-id="selected-provider-vm-fs-forkedState_2"]')
// check if 'forkedState_2' is present in environment explorer
Expand Down Expand Up @@ -140,7 +140,7 @@ const tests = {
.modalFooterOKClick('udappNotify')
.waitForElementVisible('*[data-shared="tooltipPopup"]', 10000)
// check if toaster is shown
.assert.textContains('*[data-shared="tooltipPopup"]', `VM state deleted successfully.`)
.assert.textContains('*[data-shared="tooltipPopup"]', `VM state reset successfully.`)
// check that there are no instances
.assert.textContains('*[data-id="deployedContractsBadge"]', '0')
// check if state file is deleted
Expand Down
2 changes: 1 addition & 1 deletion apps/remix-ide/src/app/files/fileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const profile = {
'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile',
'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath',
'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson', 'diff',
'hasGitSubmodules'
'hasGitSubmodules', 'getOpenedFiles'
],
kind: 'file-system'
}
Expand Down
64 changes: 30 additions & 34 deletions apps/remix-ide/src/app/plugins/remixAIPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ViewPlugin } from '@remixproject/engine-web'
import { Plugin } from '@remixproject/engine';
import { RemixAITab, ChatApi } from '@remix-ui/remix-ai'
import React, { useCallback } from 'react';
import { ICompletions, IModel, RemoteInferencer, IRemoteModel, IParams, GenerationParams, CodeExplainAgent } from '@remix/remix-ai-core';
import { ICompletions, IModel, RemoteInferencer, IRemoteModel, IParams, GenerationParams, CodeExplainAgent, SecurityAgent } from '@remix/remix-ai-core';
import { CustomRemixApi } from '@remix-api'
import { PluginViewWrapper } from '@remix-ui/helper'
import { CodeCompletionAgent } from '@remix/remix-ai-core';
Expand All @@ -18,9 +18,8 @@ const profile = {
displayName: 'RemixAI',
methods: ['code_generation', 'code_completion',
"solidity_answer", "code_explaining",
"code_insertion", "error_explaining",
"initialize", 'chatPipe', 'ProcessChatRequestBuffer',
'isChatRequestPending'],
"code_insertion", "error_explaining", "vulnerability_check",
"initialize", 'chatPipe', 'ProcessChatRequestBuffer', 'isChatRequestPending'],
events: [],
icon: 'assets/img/remix-logo-blue.png',
description: 'RemixAI provides AI services to Remix IDE.',
Expand All @@ -39,16 +38,17 @@ export class RemixAIPlugin extends ViewPlugin {
remoteInferencer:RemoteInferencer = null
isInferencing: boolean = false
chatRequestBuffer: chatRequestBufferT<any> = null
agent: CodeExplainAgent
codeExpAgent: CodeExplainAgent
securityAgent: SecurityAgent
useRemoteInferencer:boolean = false
dispatch: any
completionAgent: CodeCompletionAgent

constructor(inDesktop:boolean) {
super(profile)
this.isOnDesktop = inDesktop
this.agent = new CodeExplainAgent(this)
// user machine dont use resource for remote inferencing
this.codeExpAgent = new CodeExplainAgent(this)
// user machine dont use ressource for remote inferencing
}

onActivation(): void {
Expand All @@ -70,6 +70,9 @@ export class RemixAIPlugin extends ViewPlugin {
console.log('Indexing workspace')
this.completionAgent.indexWorkspace()
}, 60000)


this.securityAgent = new SecurityAgent(this)
}

async initialize(model1?:IModel, model2?:IModel, remoteModel?:IRemoteModel, useRemote?:boolean){
Expand Down Expand Up @@ -105,11 +108,6 @@ export class RemixAIPlugin extends ViewPlugin {
}

async code_generation(prompt: string): Promise<any> {
if (this.isInferencing) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: "RemixAI is already busy!" })
return
}

if (this.isOnDesktop && !this.useRemoteInferencer) {
return await this.call(this.remixDesktopPluginName, 'code_generation', prompt)
} else {
Expand All @@ -130,17 +128,8 @@ export class RemixAIPlugin extends ViewPlugin {
}

async solidity_answer(prompt: string, params: IParams=GenerationParams): Promise<any> {
if (this.isInferencing) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: "RemixAI is already busy!" })
return
}
if (prompt.trimStart().startsWith('gpt') || prompt.trimStart().startsWith('sol-gpt')) {
params.terminal_output = true
params.stream_result = false
params.return_stream_response = false
}
const newPrompt = await this.codeExpAgent.chatCommand(prompt)

const newPrompt = await this.agent.chatCommand(prompt)
let result
if (this.isOnDesktop && !this.useRemoteInferencer) {
result = await this.call(this.remixDesktopPluginName, 'solidity_answer', newPrompt)
Expand All @@ -154,11 +143,6 @@ export class RemixAIPlugin extends ViewPlugin {
}

async code_explaining(prompt: string, context: string, params: IParams=GenerationParams): Promise<any> {
if (this.isInferencing) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: "RemixAI is already busy!" })
return
}

let result
if (this.isOnDesktop && !this.useRemoteInferencer) {
result = await this.call(this.remixDesktopPluginName, 'code_explaining', prompt, context, params)
Expand All @@ -171,11 +155,6 @@ export class RemixAIPlugin extends ViewPlugin {
}

async error_explaining(prompt: string, context: string="", params: IParams=GenerationParams): Promise<any> {
if (this.isInferencing) {
this.call('terminal', 'log', { type: 'aitypewriterwarning', value: "RemixAI is already busy!" })
return
}

let result
if (this.isOnDesktop && !this.useRemoteInferencer) {
result = await this.call(this.remixDesktopPluginName, 'error_explaining', prompt)
Expand All @@ -186,6 +165,22 @@ export class RemixAIPlugin extends ViewPlugin {
return result
}

async vulnerability_check(prompt: string, params: IParams=GenerationParams): Promise<any> {
let result
if (this.isOnDesktop && !this.useRemoteInferencer) {
result = await this.call(this.remixDesktopPluginName, 'vulnerability_check', prompt)

} else {
result = await this.remoteInferencer.vulnerability_check(prompt, params)
}
if (result && params.terminal_output) this.call('terminal', 'log', { type: 'aitypewriterwarning', value: result })
return result
}

getVulnerabilityReport(file: string): any {
return this.securityAgent.getReport(file)
}

async code_insertion(msg_pfx: string, msg_sfx: string): Promise<any> {
if (this.completionAgent.indexer == null || this.completionAgent.indexer == undefined) await this.completionAgent.indexWorkspace()

Expand All @@ -210,11 +205,12 @@ export class RemixAIPlugin extends ViewPlugin {
if (fn === "code_explaining") ChatApi.composer.send("Explain the current code")
else if (fn === "error_explaining") ChatApi.composer.send("Explain the error")
else if (fn === "solidity_answer") ChatApi.composer.send("Answer the following question")
else console.log("chatRequestBuffer is not empty. First process the last request.")
else if (fn === "vulnerability_check") ChatApi.composer.send("Is there any vulnerability in the pasted code?")
else console.log("chatRequestBuffer function name not recognized.")
}
}
else {
console.log("chatRequestBuffer is not empty. First process the last request.")
console.log("chatRequestBuffer is not empty. First process the last request.", this.chatRequestBuffer)
}
_paq.push(['trackEvent', 'ai', 'remixAI_chat', 'askFromTerminal'])
}
Expand Down
16 changes: 15 additions & 1 deletion apps/remix-ide/src/app/providers/environment-explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ export class EnvironmentExplorer extends ViewPlugin {
}
}

async deleteForkedState (provider) {
const providerName = await this.call('blockchain', 'getProvider')
if (providerName !== provider.name) {
await this.call('fileManager', 'remove', `.states/forked_states/${provider.displayName}.json`)
await this.call('blockchain', 'removeProvider', provider.name)
this.call('notification', 'toast', `Environment "${provider.displayName}" deleted successfully.`)
} else this.call('notification', 'toast', 'Cannot delete the current selected environment')
}

renderComponent() {
this.dispatch({
...this.state
Expand All @@ -86,7 +95,12 @@ export class EnvironmentExplorer extends ViewPlugin {

updateComponent(state: EnvironmentExplorerState) {
return (<>
<EnvironmentExplorerUI pinStateCallback={this.pinStateCallback.bind(this)} profile={profile} state={state} />
<EnvironmentExplorerUI
pinStateCallback={this.pinStateCallback.bind(this)}
deleteForkedState={this.deleteForkedState.bind(this)}
profile={profile}
state={state}
/>
</>)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.EECellStyle {
min-height: 6rem;
min-height: 8rem;
max-width: 12rem;
min-width: 10rem;
min-width: 12rem;
}
1 change: 1 addition & 0 deletions apps/remix-ide/src/app/tabs/locale-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export class LocaleModule extends Plugin {
const next = localeCode || this.active // Name
if (next === this.active) return // --> exit out of this method
_paq.push(['trackEvent', 'localeModule', 'switchTo', next])

const nextLocale = this.locales[next] // Locale
if (!this.forced) this._deps.config.set('settings/locale', next)

Expand Down
1 change: 1 addition & 0 deletions apps/remix-ide/src/app/tabs/locales/en/editor.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"editor.explainFunctionByAI": "```\n{content}\n```\nExplain the function {currentFunction}",
"editor.explainFunctionByAISol": "```\n{content}\n```\nExplain the function {currentFunction}",
"editor.ExplainPipeMessage": "```\n {content}\n```\nExplain the snipped above",
"editor.PastedCodeSafety": "```\n {content}\n```\n\nReply in a short manner: Does this code contain major security vulnerabilities leading to a scam or loss of funds?",
"editor.executeFreeFunction": "Run a free function",
"editor.executeFreeFunction2": "Run the free function \"{name}\"",
"editor.toastText1": "This can only execute free function",
Expand Down
13 changes: 8 additions & 5 deletions apps/remix-ide/src/app/tabs/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@
"udapp.hash": "hash",
"udapp.signature": "signature",
"udapp.forkStateTitle": "Fork VM state",
"udapp.forkStateLabel": "State Name",
"udapp.forkStateLabel": "New environment name",
"udapp.forkVmStateDesc1":"Forking state will create a new environment with same state as selected environment",
"udapp.forkVmStateDesc2":"After forking, new environment will be pinned and selected automatically. It can be unpinned or deleted using Envionment Explorer",
"udapp.fork": "Fork",
"udapp.deleteVmStateTitle": "Delete VM state",
"udapp.deleteVmStateDesc1": "Deleting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.deleteVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.deleteVmStateDesc3": "Do you want to continue?",
"udapp.resetVmStateTitle": "Reset VM state",
"udapp.resetVmStateDesc1": "Resetting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.resetVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.resetVmStateDesc3": "Do you want to continue?",
"udapp.reset": "Reset",
"udapp.delete": "Delete",
"udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).",
"udapp.createNewAccount": "Create new account",
Expand Down
6 changes: 2 additions & 4 deletions apps/remix-ide/src/app/tabs/script-runner-ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export class ScriptRunnerUIPlugin extends ViewPlugin {
})

this.plugin.on('fileManager', 'fileSaved', async (file: string) => {

if (file === configFileName && this.enableCustomScriptRunner) {
await this.loadCustomConfig()
this.renderComponent()
Expand Down Expand Up @@ -114,7 +113,8 @@ export class ScriptRunnerUIPlugin extends ViewPlugin {
activateCustomScriptRunner={this.activateCustomScriptRunner.bind(this)}
saveCustomConfig={this.saveCustomConfig.bind(this)}
openCustomConfig={this.openCustomConfig.bind(this)}
loadScriptRunner={this.selectScriptRunner.bind(this)} />
loadScriptRunner={this.selectScriptRunner.bind(this)}
/>
)
}

Expand Down Expand Up @@ -184,7 +184,6 @@ export class ScriptRunnerUIPlugin extends ViewPlugin {
this.setIsLoading(config.name, false)
this.renderComponent()
return result

}

async execute(script: string, filePath: string) {
Expand Down Expand Up @@ -289,7 +288,6 @@ export class ScriptRunnerUIPlugin extends ViewPlugin {
}
}
}

}

async openCustomConfig() {
Expand Down
2 changes: 1 addition & 1 deletion apps/remix-ide/src/app/tabs/theme-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class ThemeModule extends Plugin {
}
const next = themeName || this.active // Name
if (next === this.active) return // --> exit out of this method
_paq.push(['trackEvent', 'themeModule', 'switchTo', next])
_paq.push(['trackEvent', 'themeModule', 'switchThemeTo', next])
const nextTheme = this.themes[next] // Theme
if (!this.forced) this._deps.config.set('settings/theme', next)
document.getElementById('theme-link') ? document.getElementById('theme-link').remove() : null
Expand Down
3 changes: 2 additions & 1 deletion apps/remix-ide/src/blockchain/blockchain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class Blockchain extends Plugin {
_paq.push(['trackEvent', 'blockchain', 'providerPinned', name])
this.emit('providersChanged')
this.changeExecutionContext({ context: name }, null, null, null)
this.call('notification', 'toast', `VM state '${providerName}' forked and selected as current environment.`)
this.call('notification', 'toast', `New environment '${providerName}' created with forked state.`)
})

this.on('environmentExplorer', 'providerUnpinned', (name, provider) => {
Expand Down Expand Up @@ -687,6 +687,7 @@ export class Blockchain extends Plugin {
}

removeProvider(name) {
if (this.pinnedProviders.includes(name)) this.emit('shouldRemoveProviderFromUdapp', name, this.getProviderObjByName(name))
this.executionContext.removeProvider(name)
this.emit('providersChanged')
}
Expand Down
Loading

0 comments on commit abef016

Please sign in to comment.