I'm not sure if I'll migrate my existing function calling code I've been using with Claude to this...
I've been using a hand rolled cross-platform way of calling functions for hard coded workflows and autonomous agents across GPT, Claude and Gemini. It works for any sufficiently capable LLM model. And with a much more pleasant, ergonomic programming model which doesn't require defining the function definition again separately to the implementation.
Before Devon was released I started building a AI Software Engineer after reading the Google "Self-Discover Reasoning Structures" paper. I was always put off looking at the LangChain API so decided to quickly build a simple API that fit my design style. Once a repo is checked out, and its decided what files to edit, I delegate the code editing step to Aider. The runAgent loop updates the system prompt with the tool definitions which are auto-generated. The available tools can be updated at runtime. The system prompt tells the agents to respond in a particular format which is parsed for the next function call. The code ends up looking like:
export async function main() {
initWorkflowContext(workflowLLMs);
const systemPrompt = readFileSync('ai-system', 'utf-8');
const userPrompt = readFileSync('ai-in', 'utf-8'); //'Complete the JIRA issue: ABC-123'
const tools = new Toolbox();
tools.addTool('Jira', new Jira());
tools.addTool('GoogleCloud', new GoogleCloud());
tools.addTool('UtilFunctions', new UtilFunctions());
tools.addTool('FileSystem', getFileSystem());
tools.addTool('GitLabServer',new GitLabServer();
tools.addTool('CodeEditor', new CodeEditor());
tools.addTool('TypescriptTools', new TypescriptTools());
await runAgent(tools, userPrompt, systemPrompt);
}
@funcClass(__filename)
export class Jira {
/**
* Gets the description of a JIRA issue
* @param {string} issueId the issue id (e.g XYZ-123)
* @returns {Promise<string>} the issue description
*/
@func
@cacheRetry({scope: 'global', ttlSeconds: 60*10, retryable: isAxiosErrorRetryable })
async getJiraDescription(issueId: string): Promise<string> {
const response = await this.instance.get(`/issue/${issueId}`);
return response.data.fields.description;
}
}
New tools/functions can be added by simply adding the @func decorator to a class method. The coding use case is just the beginning of what it could be used for.
I'm busy finishing up a few pieces and then I'll put it out as open source shortly!
Before Devon was released I started building a AI Software Engineer after reading the Google "Self-Discover Reasoning Structures" paper. I was always put off looking at the LangChain API so decided to quickly build a simple API that fit my design style. Once a repo is checked out, and its decided what files to edit, I delegate the code editing step to Aider. The runAgent loop updates the system prompt with the tool definitions which are auto-generated. The available tools can be updated at runtime. The system prompt tells the agents to respond in a particular format which is parsed for the next function call. The code ends up looking like:
New tools/functions can be added by simply adding the @func decorator to a class method. The coding use case is just the beginning of what it could be used for.I'm busy finishing up a few pieces and then I'll put it out as open source shortly!