AI agent Harness
# Batanat Agentic Harness
An agentic harness for energy-sector business development in Kenya. It does three things:
1. **Watches Gmail** and flags business opportunities.
2. **Scrapes government and parastatal procurement sites** for energy tenders, and reports.
3. **Reads Zoho CRM, and writes to it through an approval queue.**
It is one agent with three tool groups, not three agents. **What the agent can do depends on
what woke it up** — and that is enforced by handing the model a different tool schema per
trigger, not by a prompt instruction.
Live:
batanat.okandasteven.me
---
## Quick start
```bash
make setup # project-local venv, Python + Bun deps, .env from .env.example
make api #
localhost (docs at /docs when APP_ENV=local)
make web #
localhost
```
The API creates its Postgres database at startup and migrates with Alembic, so there is no
manual provisioning step.
To see it working with no credentials at all:
```bash
make demo # seeds a user, classified emails (one with a prompt injection), tenders,
# a run with a full audit trail, and a pending approval. No external calls.
```
Other commands:
```bash
make sources # probe every tender source live and print which ones work
make eval # precision and recall from the 👍/👎 feedback
make types # regenerate shared TS types + JSON Schema from the Pydantic contracts
make check # lint → test → typecheck (everything CI runs)
make reset-db # drop, re-migrate, re-seed
```
Dev credentials are `martin@batanat.com` / `batanat-dev`, shown on the login page in
development. The API refuses to start outside `APP_ENV=local` while that password is still set.
---
## Stack
| Layer | Choice |
|---|---|
| Frontend | TanStack Start + Router/Query, Bun, TypeScript, Tailwind v4, shadcn/ui |
| Backend | Python 3.12, FastAPI, LangGraph, Pydantic v2, uv |
| Model | Groq or OpenRouter (open weights, default); Anthropic also supported |
| Relational | Postgre …