Furrow is a voice-first farm operations assistant delivered over iMessage and SMS. Farmers text or voice-note their daily activity — spray applications, purchases, field observations — and Furrow turns that into structured logs, compliance checks, market research, and proactive daily briefings.
Conversational logging — farmers send messy voice notes, photos, or plain text. Furrow transcribes audio, analyzes crop/receipt images, extracts structured farm log entries, checks chemical REI/PHI compliance, and replies in natural conversational bubbles with action confirmations.
Proactive briefings — Furrow sends daily briefings covering weather impact, commodity price movement, budget burn, soil sensor readings, upcoming deadlines, and a recommended next action. Farmers can drill down on any item by replying.
Research tools — real-time web research via Exa for USDA market reports, drought/climate outlooks, and global factors (fertilizer prices, trade policy, supply chain disruptions) that affect farm economics.
Specialist agents — Gmail and Google Calendar integration via Composio, image generation via Gemini, and vision analysis via GPT-4o run as parallel specialist pipelines triggered by intent classification.
Messages enter through Sendblue (iMessage/SMS), hit the FastAPI backend, and fan out through a 3-tier routing stack:
Farmer (iMessage/SMS)
|
v
Sendblue webhook --> FastAPI
|
v
IntentRouter (classifies intent, picks specialists)
|
+--> Reflex tier : gpt-4o-mini for greetings/small talk (~1s)
+--> Composer tier : parallel specialists + Kimi K2.5 reply composer, gpt-4o fallback
+--> Hermes tier : Docker agent for complex multi-step tasks
|
v
BubbleDispatcher (humanized delays, rate limiting, iMessage reactions)
|
v
Farmer receives 1-3 conversational bubbles
3-tier routing keeps latency low for simple messages while handling complex requests through specialist pipelines or the full agentic loop.
Proactive monitoring runs on a cron (every 15 min market hours, hourly off-hours):
MonitorService (cron sweep)
|
+--> Poll data feeds (soil sensors, weather, commodity prices)
+--> Check per-farmer thresholds (price moves, moisture drops, frost, equipment)
|
[threshold breach?]
|
+--> P1 alerts → reasoning agent evaluates "text now or batch?"
| +--> TEXT NOW → Sendblue → farmer gets SMS
| +--> BATCH → folded into next daily briefing
|
+--> P2/P3 → batched into daily briefing (no interruption)
- Backend: FastAPI + Python 3.10+
- Database: PostgreSQL via SQLAlchemy + asyncpg
- Messaging: Sendblue (iMessage/SMS/RCS)
- LLM providers: Featherless (Kimi K2.5), Groq (Whisper), OpenAI (gpt-4o, gpt-4o-mini), Gemini (gemini-2.5-flash for image generation)
- Research: Exa (AI-native web search)
- Integrations: Composio (Gmail, Google Calendar), Gemini (image gen), AgentMail
- Agent runtime: Hermes agent (Docker), OpenAI Agents SDK
- Artifact hosting: Vercel (interactive report widgets)
- Python 3.10+
- uv (Python package manager)
- Node.js 22+
- PostgreSQL (local or hosted)
- Docker & Docker Compose (for containerized setup)
- tmux (for local dev scripts)
Copy the example env file and fill in your keys:
cp server/.env.example server/.envRequired for core functionality:
| Variable | Purpose |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
SENDBLUE_API_KEY |
Sendblue iMessage gateway |
SENDBLUE_API_SECRET |
Sendblue iMessage gateway |
SENDBLUE_FROM_NUMBER |
Assigned phone line |
FEATHERLESS_API_KEY |
Kimi K2.5 via Featherless |
GROQ_API_KEY |
Whisper transcription |
OPENAI_API_KEY |
gpt-4o / gpt-4o-mini + vision + agentic tasks |
Optional for extended features:
| Variable | Purpose |
|---|---|
EXA_API_KEY |
Real-time market/weather/global research |
GEMINI_API_KEY |
Image generation |
COMPOSIO_API_KEY |
Gmail + Calendar integration |
AGENTMAIL_API_KEY |
Email agent |
VERCEL_TOKEN |
Artifact/report hosting on Vercel |
HERMES_API_TOKEN |
Auth token for Hermes agent container |
Spins up all five services in one command:
| Container | Port | Description |
|---|---|---|
db |
5432 | PostgreSQL 16 |
hermes |
9100 | Hermes agent container |
server |
8000 | FastAPI backend |
client |
8080 | Vite + React frontend |
tunnel |
— | Cloudflare tunnel (exposes server publicly) |
./scripts/start.sh dockerStop everything:
./scripts/stop.sh dockerThe server container automatically connects to the db container and routes agentic requests to hermes. Source code is volume-mounted so hot reload works for both server/ and client/.
Runs the frontend and backend in a split tmux session (requires a local Postgres instance and optionally the Hermes container running separately):
./scripts/start.shThis opens a tmux session called furrow with two panes:
- Top: FastAPI backend on port 8000
- Bottom: Vite dev server on port 8080
Detach with Ctrl-B d, reattach with tmux attach -t furrow.
Stop:
./scripts/stop.shTo run the Hermes agent container alongside:
cd sandbox && docker compose up -d# Backend
cd server
uv venv && source .venv/bin/activate
uv pip install -e .
AUTO_CREATE_TABLES=true uvicorn src.main:app --reload --port 8000
# Frontend (separate terminal)
cd client
npm install
npm run devThe API is available at http://localhost:8000. Health check at GET /health.
Frontend at http://localhost:8080.
# Install and authenticate the Sendblue CLI
npm install -g @sendblue/cli
sendblue login
# Get your credentials and assigned line
sendblue show-keys
sendblue linesSet the receive webhook to point at your server:
curl -X PUT http://localhost:8000/api/sendblue/webhooks \
-H "Content-Type: application/json" \
-d '{"payload": {"receive": "https://your-domain.com/webhooks/sendblue"}}'| Method | Path | Description |
|---|---|---|
| POST | /webhooks/sendblue |
Ingest inbound iMessage/SMS webhooks |
| POST | /api/sendblue/send-message |
Send a message |
| POST | /api/croptalk/confirm |
Confirm/reject a drafted farm log |
| POST | /api/croptalk/calendar-action |
Schedule REI/PHI compliance reminders |
| Method | Path | Description |
|---|---|---|
| POST | /cron/farmpulse/daily |
Generate a daily briefing |
| POST | /cron/farmpulse/scheduler-trigger |
Batch briefing scheduler |
| POST | /cron/monitor/sweep |
High-frequency sensor/price monitoring sweep |
| POST | /api/farmpulse/drilldown |
Follow-up on a briefing item |
| Method | Path | Description |
|---|---|---|
| POST | /api/composio/authorize |
Start OAuth flow (Gmail/Calendar) |
| POST | /api/composio/agents/run |
Run a Composio-backed agent |
| POST | /api/media/generate-image |
Generate image via Gemini |
| POST | /api/artifacts/interactive-report |
Render mobile-friendly report widget |
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /r/{short_id} |
Resolve shortlink redirect |
| POST | /api/shortlinks |
Create a shortlink |
| POST | /api/seed |
Seed demo farmer data |
furrow/
│
│ How it fits together
│ ─────────────────────────────────────────────────────────────────────
│ Farmer texts/calls → Sendblue webhook → server/ (FastAPI)
│ server/ classifies intent, runs specialists, composes reply
│ Heavy multi-step tasks are forwarded to sandbox/ (Hermes agent)
│ client/ is a React dashboard for onboarding and viewing farm data
│ scripts/ wires everything together for local dev and Docker
│
├── scripts/ ← dev tooling — not part of the runtime
│ ├── start.sh # launch tmux session (local) or docker compose
│ ├── stop.sh # tear down tmux session or containers
│ └── docker-compose.yml # db + server + client + hermes + tunnel
│
├── client/ ← React dashboard (Vite + shadcn/ui)
│ │ farmers onboard here; ops team monitors feeds
│ └── src/
│ ├── pages/
│ │ ├── Index.tsx # main farm dashboard — briefings, logs, sensors
│ │ ├── Onboard.tsx # farmer profile setup (fields, crops, alerts)
│ │ └── Connect.tsx # OAuth connections (Gmail, Calendar)
│ ├── components/ # reusable UI: activity feed, alerts, compliance,
│ │ # automations, farm log, farmer context, modals
│ └── lib/
│ └── furrow-api.ts # typed API client used by every page
│
├── server/ ← FastAPI backend — the brain of the system
│ └── src/
│ ├── api/
│ │ ├── routes.py # all HTTP endpoints (webhooks, cron, REST)
│ │ └── hermes_routes.py # proxy routes into the Hermes sandbox
│ ├── core/
│ │ └── settings.py # env-var config (DATABASE_URL, API keys, flags)
│ ├── db/
│ │ ├── models.py # SQLAlchemy ORM: Farmer, Field, FarmLog, etc.
│ │ ├── session.py # async engine + session factory
│ │ └── repositories.py # all DB read/write logic
│ ├── schemas/ # Pydantic models — request/response contracts
│ ├── adapters/
│ │ ├── sendblue_adapter.py # raw Sendblue HTTP calls
│ │ └── data_feeds_adapter.py # soil sensors, weather, commodity feeds
│ ├── tasks/
│ │ └── queue.py # background task queue (cron sweeps, briefings)
│ └── services/ ← all business logic lives here
│ ├── orchestrator_service.py # 3-tier routing: reflex/composer/hermes
│ ├── intent_router.py # classifies intent, picks specialists
│ ├── reflex_chat_service.py # fast-path: gpt-4o-mini for small talk
│ ├── reply_composer.py # Kimi K2.5 natural reply generation
│ ├── bubble_dispatcher.py # humanized delivery, typing delays
│ ├── sendblue_service.py # send iMessage/SMS via Sendblue
│ ├── hermes_bridge_service.py # forward tasks to Hermes sandbox
│ ├── briefing_service.py # daily farm briefing generation
│ ├── monitor_service.py # cron sweep: sensors/prices → alerts
│ ├── farmer_store.py # enriched farmer context builder
│ ├── compliance_service.py # REI/PHI chemical safety rules
│ ├── memory_service.py # per-farmer conversation memory
│ ├── exa_research_service.py # real-time web research via Exa
│ ├── vision_service.py # crop photo / receipt image analysis
│ ├── voice_service.py # Groq Whisper audio transcription
│ ├── video_analysis_service.py # Gemini video analysis (drone, field)
│ ├── artifact_service.py # interactive report widget rendering
│ ├── onboarding_service.py # SMS-driven farmer profile setup
│ ├── extraction_service.py # structured data extraction from text
│ ├── contact_sharing_service.py # contact card sharing over iMessage
│ ├── image_gen_service.py # Gemini image generation
│ ├── featherless_client.py # Featherless API client (Kimi K2.5)
│ ├── openai_client.py # OpenAI API client
│ ├── agent_tools.py # tool definitions for the agentic loop
│ └── specialists/ # on-demand parallel specialist agents
│ ├── calendar.py # Google Calendar scheduling
│ ├── email.py # Gmail triage and drafting
│ ├── vision.py # deep image/video analysis
│ ├── sensor_triage.py # soil/equipment alert evaluation
│ ├── image_gen.py # Gemini image generation
│ └── stubs.py # no-op stubs for disabled specialists
│
└── sandbox/ ← Hermes agent container (Docker-only)
│ isolated runtime for multi-step agentic tasks
│ server/ talks to it over HTTP on port 9100
├── hermes_server.py # HTTP wrapper: /exec runs a skill, /health ping
├── entrypoint.sh # injects env vars, starts uvicorn
├── tunnel.sh # Cloudflare tunnel helper
└── skills/ # pre-baked tools the Hermes agent can call
├── farm-orchestrator/ # top-level farm task planner
├── farm-report-maker/ # generates PDF/HTML farm reports
├── agent-browser/ # headless browser for web tasks
├── exa-research/ # market + weather research via Exa
├── doc-parser/ # invoice / receipt / form extraction
├── gemini-image-generator/ # image gen via Gemini
├── agentmail/ # email send/receive agent
├── composio/ # Gmail + Calendar via Composio
├── sendblue/ # send SMS/iMessage from inside agent
├── furrow-data/ # read farmer/field data from the DB
└── proactive-soul/ # decides when to proactively text the farmer
This project was built at Bitcamp 2026. See individual service files for ownership annotations.

