-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate agent #5870
base: master
Are you sure you want to change the base?
Generate agent #5870
Changes from 2 commits
ab4e81b
655c06d
3a55986
eb94671
3528efb
01ecb20
833800f
3a53244
20fb2f5
4697ac8
278d6a5
0904e3c
8c421ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { parse } from "path"; | ||
|
||
const compilationParams = { | ||
optimize: false, | ||
evmVersion: null, | ||
language: 'Solidity', | ||
version: '0.8.28+commit.7893614a' | ||
} | ||
|
||
interface CompilationResult { | ||
compilationSucceeded: boolean | ||
errors: string | ||
} | ||
|
||
export class ContractAgent { | ||
plugin: any; | ||
readonly generationAttempts: number = 3 | ||
nAttempts: number = 0 | ||
generationThreadID: string= '' | ||
workspaceName: string = '' | ||
|
||
constructor(props) { | ||
this.plugin = props; | ||
} | ||
|
||
async writeContracts(payload, userPrompt) { | ||
try { | ||
console.log('Writing contracts', payload) | ||
const parsedFiles = payload | ||
this.generationThreadID = parsedFiles['threadID'] | ||
this.workspaceName = parsedFiles['projectName'] | ||
|
||
this.nAttempts += 1 | ||
if (this.nAttempts > this.generationAttempts) { | ||
console.error('Failed to generate the code') | ||
return "Failed to generate secure code on this prompt ````" + userPrompt + "````" | ||
} | ||
|
||
const contracts = {} | ||
for (const file of parsedFiles.files) { | ||
if (file.fileName.endsWith('.sol')) { | ||
const result:CompilationResult = await this.compilecontracts(file.fileName, file.content) | ||
console.log('compilation result', result) | ||
if (!result.compilationSucceeded) { | ||
// nasty recursion | ||
console.log('compilation failed') | ||
// const newPrompt = `I couldn't compile the contract ${file.fileName}. ${result.errors}. Please try again.` | ||
// await this.plugin.call('remixAI', 'generate', newPrompt, this.generationThreadID); // reuse the same thread | ||
} | ||
} | ||
} | ||
|
||
console.log('All source files are compiling') | ||
return "New workspace created: " + this.workspaceName + "\nUse the Hamburger menu to select it!" | ||
} catch (error) { | ||
console.log('Error writing contracts', error) | ||
this.deleteWorkspace(this.workspaceName ) | ||
return "Failed to generate secure code on this prompt ```" + userPrompt + "```" | ||
} | ||
|
||
} | ||
|
||
createWorkspace(workspaceName) { | ||
// first get the workspace names | ||
const ws = this.plugin.call('filePanel', 'getWorkspaces') | ||
|
||
if (ws.includes(workspaceName)) { | ||
const newWorkspaceName = workspaceName + '_1' | ||
ws.includes(newWorkspaceName) ? | ||
this.plugin.call('filePanel', 'createWorkspace', newWorkspaceName+'_1', true) | ||
: this.plugin.call('filePanel', 'createWorkspace', workspaceName, true) | ||
} | ||
this.plugin.call('filePanel', 'createWorkspace', workspaceName, true) | ||
} | ||
|
||
deleteWorkspace(workspaceName) { | ||
this.plugin.call('filePanel', 'deleteWorkspace', workspaceName) | ||
} | ||
|
||
async compilecontracts(fileName, fileContent): Promise<CompilationResult> { | ||
|
||
const contract = {} | ||
contract[fileName] = { content : fileContent } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you have to put all the files in there:
etc... so you should not loop over the files and compile them one by one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I already tried this, the issue might me the import name not including the folder |
||
console.log('compiling contract', contract) | ||
const result = await this.plugin.call('solidity' as any, 'compileWithParameters', contract, compilationParams) | ||
console.log('compilation result', result) | ||
const data = result.data | ||
const error = data.errors.find((error) => error.type !== 'Warning') | ||
if (data.errors && data.errors.length && error) { | ||
const msg = ` | ||
- Compilation errors: ${data.errors.map((e) => e.formattedMessage)}. | ||
` | ||
return { compilationSucceeded: false, errors: msg } | ||
|
||
} | ||
|
||
return { compilationSucceeded: true, errors: null } | ||
} | ||
|
||
extractImportPaths(text) { | ||
|
||
// Define the regex pattern to match import paths | ||
const regex = /import\s*\"([^\"]+)\"\s*;/g; | ||
const paths = []; | ||
let match; | ||
|
||
// Use the regex to find all matches in the text | ||
while ((match = regex.exec(text)) !== null) { | ||
// Push the captured path to the paths array | ||
paths.push(match[1]); | ||
} | ||
|
||
return paths; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't handle yet solidity import?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I handle imports by adding all files for compilation see line 33, which make sense, the generation must be complete ( from a compilation point of view)