Some of the most useful AI applications do not start with a chatbot.
They start with a messy field note.
"My corn has yellow streaks on the lower leaves and dark brown spots. About a third of the plants are affected."
That is the kind of input a farmer, field technician, or local operator might send from a phone while standing beside the crop. The useful output is not a long essay. It is a structured advisory: what crop is involved, what kind of issue it might be, how severe it looks, what to do next, and whether a human expert should be pulled in.
This example builds that workflow on Telnyx Edge Compute Stateful Actors.
Code:
What the example builds
The app is a TypeScript Edge Compute example for agriculture triage.
It accepts either:
- a plain-language crop issue description
- a URL to a crop advisory or extension-style page
Then it calls Telnyx AI Inference and returns a structured advisory:
{
"id": "adv-msf1zxyc-0",
"farmer_description": "My corn has yellow streaks...",
"source": "text",
"crop_type": "corn",
"issue_type": "disease",
"severity": "medium",
"confidence": 0.7,
"recommendation": "Yellow streaks with dark brown spots are consistent with a fungal leaf blight. Apply a foliar fungicide and scout weekly.",
"escalate": false,
"generated_at": "2026-08-04T19:31:04Z"
}
If the model classifies a case as critical, the app flags it for escalation:
{
"issue_type": "pest",
"severity": "critical",
"escalate": true,
"escalated_to": "agronomist-on-call"
}
That is the part that makes this more interesting than a summarizer. The response is shaped for a workflow.
The API shape
The app exposes:
POST /advisoryto create a crop advisoryGET /advisoriesto list recent advisoriesGET /advisories/<id>to fetch one advisoryGET /statsto inspect cumulative issue and severity statsGET /health/livenessandGET /health/readinessfor health checks
The main route is POST /advisory.
You can send a description:
curl -X POST https://edge-agri-crop-advisory-<id>.telnyxcompute.com/advisory \
-H "Content-Type: application/json" \
-d '{"description":"Tomato leaves have holes all over them. I can see green caterpillars on the underside of the leaves."}'
Or you can send a URL:
curl -X POST https://edge-agri-crop-advisory-<id>.telnyxcompute.com/advisory \
-H "Content-Type: application/json" \
-d '{"url":"https://extension.umn.edu/news/something-about-aphids"}'
For URL input, the app fetches the page, strips HTML, and sends the extracted text to the model.
How it uses Telnyx AI Inference
The app calls:
POST /v2/ai/chat/completions
The current code path uses:
zai-org/GLM-5.2
The system prompt asks the model to act like an agricultural extension agronomist and return JSON only.
The expected fields are:
crop_typeissue_typeseverityconfidencerecommendation
The issue type must be one of:
disease | pest | nutrient | water | weather | unknown
The severity must be one of:
low | medium | high | critical
That structure matters because the app does more than print a model answer. It stores the advisory, updates stats, and flags critical cases for escalation.
Where Stateful Actors fit
The app uses a Stateful Actor called CropAdvisory.
Every advisory is stored in actor storage using ctx.storage. The same actor also keeps cumulative stats:
- total advisories
- advisories by issue type
- advisories by severity
- escalation count
- recent crop types
That gives the app memory without adding a database just to make the example useful.
You can create several advisories, then ask for stats:
curl https://edge-agri-crop-advisory-<id>.telnyxcompute.com/stats
Example:
{
"total_advisories": 8,
"by_issue_type": {
"disease": 3,
"pest": 2,
"water": 2,
"nutrient": 1
},
"by_severity": {
"low": 1,
"medium": 3,
"high": 2,
"critical": 2
},
"escalations": 2,
"recent_crop_types": ["corn", "soybean", "wheat"]
}
That is a small but useful operational loop: intake, classify, store, summarize, escalate.
Running the example
Clone the examples repo:
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/edge-agri-crop-advisory
Set your Telnyx API key:
telnyx-edge auth api-key set <YOUR_API_KEY>
telnyx-edge secrets add TELNYX_API_KEY "KEY0123..."
Install dependencies and deploy:
npm install
telnyx-edge ship
The deploy command gives you a URL like:
https://edge-agri-crop-advisory-<id>.telnyxcompute.com
Check health:
curl -sS --retry 30 --retry-delay 5 \
https://edge-agri-crop-advisory-<id>.telnyxcompute.com/health/liveness
Create an advisory:
curl -X POST https://edge-agri-crop-advisory-<id>.telnyxcompute.com/advisory \
-H "Content-Type: application/json" \
-d '{"description":"My corn has yellow streaks on bottom leaves with dark brown spots. About 30% of plants affected."}'
List recent advisories:
curl https://edge-agri-crop-advisory-<id>.telnyxcompute.com/advisories
Check stats:
curl https://edge-agri-crop-advisory-<id>.telnyxcompute.com/stats
What I would add before production
This should be treated as a triage workflow, not a replacement for professional agronomy advice.
For production, I would add:
- farmer or account identity
- crop stage and location
- photo input
- local weather context
- region-specific treatment guidance
- pesticide and safety warnings
- human agronomist review
- authentication and rate limiting
- durable exports to a CRM, ticket queue, or field service system
- SMS or webhook alerts for critical cases
The example is intentionally small, but the pattern is reusable.
Edge Compute handles the request.
Telnyx AI Inference structures the decision.
The Stateful Actor remembers the advisory history and stats.
And critical cases get a clear handoff point instead of disappearing into a model response.