This is a collection of LLM agents that are being used in HASH. The agents are defined in the app/agents/ directory and are organized as modules. The top-level module is able to run the different agents.
- Python 3.x > 3.11 (the version used in HASH is 3.11)
<PYTHON_CMD> here should be the command you use to run Python.
This varies on platform, to check you're running the correct version, run <PYTHON_CMD> --version.
Some potential candidates for PYTHON_CMD
pythonpython3python<VERSION>(e.g.python3.11)py3py
- Install poetry:
- Please refer to the poetry documentation for installation instructions
- Acquire and set the OpenAI API key, either:
- Set the
OPENAI_API_KEYenvironment variable in.env.local(this folder or any parent folder), or - Set the
OPENAI_API_KEYenvironment variable in your shell
- Set the
- Install dependencies:
poetry install
- Generate the Python typings for the agents:
yarn codegen
- Ensure the OpenAI API key is available
- If the requirements has been changed:
poetry install
- If the typings for the agents have been changed:
yarn codegen
To run the agent orchestrator, pass the agent name alongside the input you want to pass to the agent:
poetry run python -m app.agents <AGENT_NAME> <INPUT>A server is available to run the agents. To run the server, use the following command:
yarn devThe server will read the HASH_AGENT_RUNNER_HOST and HASH_AGENT_RUNNER_PORT environment variables to determine the host and port to run on. If these are not set, the server will run on localhost:5000.
The server will be run as external service. Please refer to the HASH Readme for more information on how to run the external services.
You can configure the logging level with the HASH_AGENT_RUNNER_LOG_LEVEL environment variable.
This can be set either in the .env.local or within the environment when you run the module.
The possible values are those accepted by Python's logging library.
If the environment variable is not set, it will default to DEBUG in a development environment and WARNING in a production environment.
All logs will be output to a $HASH_AGENT_RUNNER_LOG_FOLDER/run-TIMESTAMP.log file, where TIMESTAMP is the time the module was started. If the environment variable is not set, the logs will be output to the logs directory.
Whenever you're making changes to the
io_types.tsfile for an agent, be sure to re-run theyarn codegencommand to ensure the python typings are up to date.
To add a new agent, you need to create a new module in the app/agents/ directory. For this, it's recommended to copy the template module and rename it to the name of your agent.
You should have an io_types.ts file in this newly copied directory, this folder contains your Input and Output types. These types are the shape of the data your agent expects to receive and the shape of the data your agent will return to callers in JSON format. Be sure to keep the type names as other parts of the system expect them to exist. You can make the types the empty object {} if no input or output is required.
To avoid going through the top-level module it's possible to directly invoke the agent module, e.g.:
poetry run python -m app.agents.my_agentsWhen the server is running as an external service, the agents directory is mounted, so it's possible to add new agents or modify agents without restarting the server.
Once you've added your new agent, you will be able to trivially call them from the frontend and backend using their directory names and defined input types.
In the frontend, you can run an agent by using the useAgentRunner hook from apps/hash-frontend/src/components/hooks/use-agent-runner.ts and calling it with the agent name and input.
In the backend, we provide a agentRunner DataSouce which exposes a runAgent function that will call the agent runner server using the agent name and input.
Both approaches are fully typed and use the provided type information to ensure each agent call is properly typed/type narrowed.
Example frontend page using the agent runner:
const Page = () => {
const [prompt, setPrompt] = useState("What is 23 times 2?");
const [expression, setExpression] = useState(prompt);
const [output, setOutput] = useState("");
const [callAgentRunner, { loading }] = useAgentRunner("template");
useEffect(() => {
void callAgentRunner({ expression }).then((data) => {
if (data) {
setOutput(data.result.toString());
}
});
}, [callAgentRunner, expression]);
return (
<Container sx={{ paddingTop: 5 }}>
<Typography variant="h3">Test the math agent!</Typography>
<input
type="text"
value={prompt}
onChange={(event) => setPrompt(event.target.value)}
/>
<Button
onClick={() => {
setExpression(prompt);
}}
>
Create
</Button>
{loading ? <p>Loading...</p> : <p>{output}</p>}
</Container>
);
};