|
const { StructuredTool } = require('langchain/tools'); |
|
const axios = require('axios'); |
|
const { z } = require('zod'); |
|
|
|
const headers = { |
|
'Content-Type': 'application/json', |
|
}; |
|
|
|
function getServerURL() { |
|
const url = process.env.CODESHERPA_SERVER_URL || ''; |
|
if (!url) { |
|
throw new Error('Missing CODESHERPA_SERVER_URL environment variable.'); |
|
} |
|
return url; |
|
} |
|
|
|
class RunCode extends StructuredTool { |
|
constructor() { |
|
super(); |
|
this.name = 'RunCode'; |
|
this.description = |
|
'Use this plugin to run code with the following parameters\ncode: your code\nlanguage: either Python, Rust, or C++.'; |
|
this.headers = headers; |
|
this.schema = z.object({ |
|
code: z.string().describe('The code to be executed in the REPL-like environment.'), |
|
language: z.string().describe('The programming language of the code to be executed.'), |
|
}); |
|
} |
|
|
|
async _call({ code, language = 'python' }) { |
|
|
|
const response = await axios({ |
|
url: `${this.url}/repl`, |
|
method: 'post', |
|
headers: this.headers, |
|
data: { code, language }, |
|
}); |
|
|
|
return response.data.result; |
|
} |
|
} |
|
|
|
class RunCommand extends StructuredTool { |
|
constructor() { |
|
super(); |
|
this.name = 'RunCommand'; |
|
this.description = |
|
'Runs the provided terminal command and returns the output or error message.'; |
|
this.headers = headers; |
|
this.schema = z.object({ |
|
command: z.string().describe('The terminal command to be executed.'), |
|
}); |
|
} |
|
|
|
async _call({ command }) { |
|
const response = await axios({ |
|
url: `${this.url}/command`, |
|
method: 'post', |
|
headers: this.headers, |
|
data: { |
|
command, |
|
}, |
|
}); |
|
return response.data.result; |
|
} |
|
} |
|
|
|
class CodeSherpa extends StructuredTool { |
|
constructor(fields) { |
|
super(); |
|
this.name = 'CodeSherpa'; |
|
this.url = fields.CODESHERPA_SERVER_URL || getServerURL(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.description = `This plugin allows interactive code and shell command execution. |
|
|
|
To run code, supply "code" and "language". Python has pre-installed packages: matplotlib, seaborn, pandas, numpy, scipy, openpyxl. Additional ones can be installed via pip. |
|
|
|
To run commands, provide "command" only. This allows interaction with the filesystem, script execution, and package installation using pip. Created or uploaded media files are embedded in responses using a specific URL.`; |
|
this.schema = z.object({ |
|
code: z |
|
.string() |
|
.optional() |
|
.describe( |
|
`The code to be executed in the REPL-like environment. You must save all media files created to \`${this.url}/static/images/\` and embed them in responses with markdown`, |
|
), |
|
language: z |
|
.string() |
|
.optional() |
|
.describe( |
|
'The programming language of the code to be executed, you must also include code.', |
|
), |
|
command: z |
|
.string() |
|
.optional() |
|
.describe( |
|
'The terminal command to be executed. Only provide this if you want to run a command instead of code.', |
|
), |
|
}); |
|
|
|
this.RunCode = new RunCode({ url: this.url }); |
|
this.RunCommand = new RunCommand({ url: this.url }); |
|
this.runCode = this.RunCode._call.bind(this); |
|
this.runCommand = this.RunCommand._call.bind(this); |
|
} |
|
|
|
async _call({ code, language, command }) { |
|
if (code?.length > 0) { |
|
return await this.runCode({ code, language }); |
|
} else if (command) { |
|
return await this.runCommand({ command }); |
|
} else { |
|
return 'Invalid parameters provided.'; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = CodeSherpa; |
|
|