Custom Actions
HyperAgent makes it easy to add custom actions for performing actions that might be too complex for a LLM to perform.
Here is an example to perform a search using exa. It takes 3 parameters
type:
perform_search
actionParams: schema defining what parameters the custom action would require.
run: A function taking in a context, and the parameters defined in the
actionParams
to perform the actual action, in this case search using exa
Code
import "dotenv/config";
import HyperAgent from "@hyperbrowser/agent";
import {
AgentActionDefinition,
ActionContext,
ActionOutput,
} from "@hyperbrowser/agent/types";
import chalk from "chalk";
import { ChatOpenAI } from "@langchain/openai";
import Exa from "exa-js";
import * as z from "zod";
const exaInstance = new Exa(process.env.EXA_API_KEY);
const searchSchema = z
.object({
search: z
.string()
.describe(
"The search query for something you want to search about. Keep the search query concise and to-the-point."
),
})
.describe("Search and return the results for a given query.");
export const RunSearchActionDefinition: AgentActionDefinition = {
type: "perform_search",
actionParams: searchSchema,
run: async function (
ctx: ActionContext,
params: z.infer<typeof searchSchema>
): Promise<ActionOutput> {
const results = (await exaInstance.search(params.search, {})).results
.map(
(res) =>
`title: ${res.title} || url: ${res.url} || relevance: ${res.score}`
)
.join("\n");
return {
success: true,
message: `Succesfully performed search for query ${params.search}. Got results: \n${results}`,
};
},
};
async function runEval() {
console.log(chalk.cyan.bold("\n===== Running Custom Tool Example ====="));
const llm = new ChatOpenAI({
apiKey: process.env.OPENAI_API_KEY,
model: "gpt-4o",
});
const agent = new HyperAgent({
llm: llm,
debug: true,
customActions: [RunSearchActionDefinition],
});
const result = await agent.executeTask(
`Make me a trip plan for Tokyo.
Steps:
- Peform search about the place and things to see there using the 'perform_search' tool.
- Analyze part of the urls provided, filtering results for relevance, and information and collecting a subset of urls that you think warrant further examination.
- For each page that you've
- Navigate to that url
- Extract information about trip recommendations
- You must do this in order. Navigate to a single page, and then perform extraction on that page. Do not perform multiple navigations one after another.
- Narrow down on places based on uniqueness, frequency of recommendation, and whatever else you feel is valuable.
- Return to me a list of places you recommend, and their details (if any)`,
{
debugOnAgentOutput: (agentOutput) => {
console.log("\n" + chalk.cyan.bold("===== AGENT OUTPUT ====="));
console.dir(agentOutput, { depth: null, colors: true });
console.log(chalk.cyan.bold("===============") + "\n");
},
onStep: (step) => {
console.log("\n" + chalk.cyan.bold(`===== STEP ${step.idx} =====`));
console.dir(step, { depth: null, colors: true });
console.log(chalk.cyan.bold("===============") + "\n");
},
}
);
await agent.closeAgent();
console.log(chalk.green.bold("\nResult:"));
console.log(chalk.white(result.output));
return result;
}
(async () => {
await runEval();
})().catch((error) => {
console.error(chalk.red("Error:"), error);
process.exit(1);
});
Last updated