Skip to content

Agronomist SDKs

Put Agronomist inside your own product. The React SDK embeds the chat and voice; the Python SDK drives it from your server or WhatsApp bot. Both talk to the same agronomist.

React SDK
@deepleaf/agronomist-sdk
Python SDK
agronomist-sdk 0.1.0
Model
agronomist
Registry
Shared with partners, public release coming

Availability

Coming soonNeither package is on the public npm or PyPI registry yet. Partners get the package files with their keys; the install lines below are what they will be once published.

React SDK

Drop the full Agronomist chat into a React or Next.js app: message thread, streaming answers, Scan, Type and Speak composer, answer cards and audio playback. Or go headless with useAgronomist() and render it your way.

terminalShell
# Not on npm yet. DeepLeaf shares the package with partners.
npm install @deepleaf/agronomist-sdk
advice-page.tsxReact
import { AgronomistProvider, AgronomistChat } from "@deepleaf/agronomist-sdk";
import "@deepleaf/agronomist-sdk/styles.css";

export default function AdvicePage({ token }: { token: string }) {
  // token: a short-lived access token your server issues. Keep API keys server-side.
  return (
    <AgronomistProvider config={{ wsUrl: "wss://<host>/ws", authMode: "header", accessToken: token }}>
      <AgronomistChat className="h-full" />
    </AgronomistProvider>
  );
}
What it renders: the composer and thread inside your app's frame
Atlas Agri
North blockTomato
You

When can I spray this week?

Spray window

Best window tomorrow 06:00 to 10:00.

Next days
  • Tue 13Good06:00–10:00
  • Wed 14AvoidRain
weather.forecast12 Oct, 05:40

Tomorrow morning. Wednesday is out because of the rain.

Batteries included
AgronomistProvider and AgronomistChat render the whole conversation.
Headless
useAgronomist and usePromptStream give you messages, status and streaming text.
Voice
Push-to-talk in the composer, and full-duplex calls with useVoiceSession.
Theming
Reads your CSS tokens. Light and dark follow your root element.
call-button.tsxReact
import { useVoiceSession } from "@deepleaf/agronomist-sdk";

function CallButton({ sendFrame }) {
  const { state, startCall, endCall } = useVoiceSession(sendFrame);
  return state.status === "idle"
    ? <button onClick={startCall}>Call Agronomist</button>
    : <button onClick={endCall}>End call ({state.duration}s)</button>;
}

Python SDK

A thin client for servers and WhatsApp bots. Pass your own farmer id on every call; no farmer account is ever created. The agent can also run in-chat field capture, corner by corner, through a location callback you supply.

terminalShell
# Not on PyPI yet. DeepLeaf shares the package with partners.
pip install agronomist-sdk
bot.pyPython
from agronomist import AgronomistClient

ag = AgronomistClient(api_key=DEEPLEAF_API_KEY)

# farmer_id is your own stable id. Same id, same farmer, same fields, same chat.
# Plant-photo diagnosis
print(ag.chat("wa:254700000000", "What is wrong with this plant?",
              image_url="data:image/jpeg;base64,..."))
What the farmer sees: the diagnosis card with its citations
You
Tomato leaf with early blight lesions

What is wrong with this plant?

Diagnosis
Tomato leaf with early blight lesions
Tomato

Early blightFungus

Alternaria solaniVery likely

Next actionRemove the lowest affected leaves today. Spray tomorrow between 06:00 and 10:00.

diagnose_photo · deepleaf-vision12 Oct, 06:11
Checked at 06:11 · from your photo
confidence
91%
path
photo → leaf lesions → field history

This looks like early blight, most likely from the wet spell. Tomorrow morning is a good window to spray.

bot.pyPython
# Same farmer, same field. The agent reads the forecast for that field.
print(ag.chat("wa:254700000000", "When can I spray this week?"))
What the farmer sees: the spray window card
You

When can I spray the tomatoes this week?

Spray window

Best window tomorrow 06:00 to 10:00. Rain likely from 14:00.

Wind
5 to 8 km/h until 10:00
Rain
40% from 14:00, 6 mm
Delta T
3.1 °C at 08:00
Next days
  • Tue 13Good06:00–10:00
  • Wed 14AvoidRain
  • Thu 15Fair07:00–09:00
weather.forecast · hourly12 Oct, 05:40

Spray tomorrow morning. Wednesday is out because of the rain.

Or any OpenAI client

The API speaks the Chat Completions wire format. Change the base URL and key, set the model to agronomist, and send a stable farmer id.

chat.pyPython
from openai import OpenAI

client = OpenAI(base_url="https://<host>/v1", api_key=DEEPLEAF_API_KEY)
stream = client.chat.completions.create(
    model="agronomist",
    messages=[{"role": "user", "content": "my tomato leaves have brown spots"}],
    user="your-farmer-12345",  # or the X-Farmer-Id header
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
What streams back: the thinking fold and each tool call
You

my tomato leaves have brown spots

Brown rings with a yellow halo, lower canopy first. Field is day 41, 18 mm of rain in three days.

Consistent with early blight. Need registered products before naming any.

Input
{"hours": 72}
Output
18 mm rain over 3 days. Dry 06:00 to 12:00 tomorrow, wind 5 to 8 km/h.

Likely early blight (Alternaria solani). Remove the lowest leaves today and spray tomorrow 06:00 to 10:00 with a product on the national register.

The essentials

Stable farmer id
X-Farmer-Id or the user field, up to 128 characters, scoped to your organisation. Do not rotate it.
Keys stay on servers
API keys are scoped to an organisation. In a browser, the React SDK takes a short-lived access token your server issues instead.
Embed tokens
Issue a short-lived token from your backend for each browser session. An API key never reaches a browser.
Webhooks
Morning briefings, problem alerts, scouting and spray reminders, signed with HMAC and carrying an idempotency key.

Webhooks

register.shcurl
curl -X POST https://<host>/v1/webhooks \
  -H "Authorization: Bearer $DEEPLEAF_API_KEY" \
  -d '{"url": "https://your-bot.example/deepleaf", "event_types": []}'
# Events: field.briefing, field.problematic, field.scouting_due, spray.reminder
# Each POST is signed: X-Agronomist-Signature: sha256=<hmac of the raw body>
What a field.briefing event becomes in the farmer's chat
This morning · North block
  • Scout zone 3DueLow vigour, 0.4 ha
  • Spray windowGood06:00–10:00
  • IrrigationSkip today, 18 mm fell
field.briefing12 Oct, 05:45
Proposal

Add spray to the calendar

Tue 13 Oct06:00–10:00

Nothing is written until you confirm.