Skip to content

Commit

Permalink
Code capability enhancement & bot crash fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Ninot1Quyi committed Nov 2, 2024
1 parent 17fa2b6 commit ecaf5e8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 14 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@
"scripts": {
"postinstall": "patch-package",
"start": "node main.js"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"eslint": "^9.13.0",
"globals": "^15.11.0"
}
}
2 changes: 1 addition & 1 deletion settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default
"show_bot_views": false, // show bot's view in browser at localhost:3000, 3001...

"allow_insecure_coding": false, // allows newAction command and model can write/run code on your computer. enable at own risk
"code_timeout_mins": 10, // minutes code is allowed to run. -1 for no timeout
"code_timeout_mins": 1, // minutes code is allowed to run. -1 for no timeout,set 1.Set 1 min to timely code adjustments

"max_messages": 15, // max number of messages to keep in context
"max_commands": -1, // max number of commands to use in a response. -1 for no limit
Expand Down
42 changes: 37 additions & 5 deletions src/agent/coder.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { writeFile, readFile, mkdirSync } from 'fs';
import { checkSafe } from '../utils/safety.js';
import settings from '../../settings.js';
import {ESLint} from "eslint";

export class Coder {
constructor(agent) {
Expand All @@ -20,7 +21,31 @@ export class Coder {

mkdirSync('.' + this.fp, { recursive: true });
}

async checkCode(code) {
const eslint = new ESLint();
const results = await eslint.lintText(code);
const codeLines = code.split('\n');
let result = '#### CODE ERROR INFO ###\n';
const exceptions = results.map(r => r.messages).flat();

if (exceptions.length > 0) {
exceptions.forEach((exc, index) => {
if (exc.line && exc.column ) {
const errorLine = codeLines[exc.line - 1]?.trim() || 'Unable to retrieve error line content';
result += `#ERROR ${index + 1}\n`;
result += `Message: ${exc.message}\n`;
result += `Location: Line ${exc.line}, Column ${exc.column}\n`;
result += `Related Code Line: ${errorLine}\n\n`;
}
});
result += 'The code contains exceptions and cannot continue execution.\n';
} else {
return null;//no error
}

return result ;
}
// write custom code to file and import it
async stageCode(code) {
code = this.sanitizeCode(code);
Expand Down Expand Up @@ -48,12 +73,11 @@ export class Coder {
this.file_counter++;

let write_result = await this.writeFilePromise('.' + this.fp + filename, src)

if (write_result) {
console.error('Error writing code execution file: ' + result);
return null;
}
return await import('../..' + this.fp + filename);
return {filename,src};
}

sanitizeCode(code) {
Expand Down Expand Up @@ -137,7 +161,14 @@ export class Coder {
continue;
}

const execution_file = await this.stageCode(code);
let {filename,src} = await this.stageCode(code);
const analysisResult = await this.checkCode(src);
if (analysisResult) {
const message = 'Error: Code syntax error. Please try again:'+'\n'+analysisResult+'\n'+await this.agent.prompter.getRelevantSkillDocs(analysisResult,3);
messages.push({ role: 'system', content: message });
continue;
}
const execution_file = await import('../..' +this.fp+filename);
if (!execution_file) {
agent_history.add('system', 'Failed to stage code, something is wrong.');
return {success: false, message: null, interrupted: false, timedout: false};
Expand Down Expand Up @@ -219,10 +250,11 @@ export class Coder {
this.executing = false;
clearTimeout(TIMEOUT);
this.cancelResume();
console.error("Code execution triggered catch: " + err);
await this.stop();

let message = this.formatOutput(this.agent.bot) + '!!Code threw exception!! Error: ' + err;
err = err.toString();
let relevant_skill_docs = await this.agent.prompter.getRelevantSkillDocs(err,5);
let message = this.formatOutput(this.agent.bot) + '!!Code threw exception!! Error: ' + err+'\n'+relevant_skill_docs;
let interrupted = this.agent.bot.interrupt_code;
this.clear();
if (!interrupted && !this.generating) this.agent.bot.emit('idle');
Expand Down
17 changes: 9 additions & 8 deletions src/agent/prompter.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ export class Prompter {
]);
}

async getRelevantSkillDocs(messages, select_num) {
let latest_message_content = messages.slice().reverse().find(msg => msg.role !== 'system')?.content || '';
let latest_message_embedding = await this.embedding_model.embed([latest_message_content]);
async getRelevantSkillDocs(message, select_num) {
let latest_message_embedding = await this.embedding_model.embed(message);

let skill_doc_similarities = Object.keys(this.skill_docs_embeddings)
.map(doc_key => ({
Expand All @@ -143,9 +142,9 @@ export class Prompter {
select_num = Math.min(Math.floor(select_num), length);
}
let selected_docs = skill_doc_similarities.slice(0, select_num);
let message = '\nThe following recommended functions are listed in descending order of task relevance.\nSkillDocs:\n';
message += selected_docs.map(doc => `${doc.doc_key}`).join('\n');
return message;
let relevant_skill_docs = '####RELEVENT DOCS INFO###\nThe following functions are listed in descending order of relevance.\nSkillDocs:\n';
relevant_skill_docs += selected_docs.map(doc => `${doc.doc_key}`).join('\n');
return relevant_skill_docs;
}

async replaceStrings(prompt, messages, examples=null, to_summarize=[], last_goals=null) {
Expand All @@ -161,8 +160,10 @@ export class Prompter {
}
if (prompt.includes('$COMMAND_DOCS'))
prompt = prompt.replaceAll('$COMMAND_DOCS', getCommandDocs());
if (prompt.includes('$CODE_DOCS'))
prompt = prompt.replaceAll('$CODE_DOCS', this.getRelevantSkillDocs(messages, 0));
if (prompt.includes('$CODE_DOCS')){
let latest_message_content = messages.slice().reverse().find(msg => msg.role !== 'system')?.content || '';
prompt = prompt.replaceAll('$CODE_DOCS', await this.getRelevantSkillDocs(latest_message_content, 5));
}
if (prompt.includes('$EXAMPLES') && examples !== null)
prompt = prompt.replaceAll('$EXAMPLES', await examples.createExampleMessage(messages));
if (prompt.includes('$MEMORY'))
Expand Down

0 comments on commit ecaf5e8

Please sign in to comment.