agentRx — Devpost Submission (Good Neighbor Agents)
agentRx is a community refill board: one coordinator watches the drugs a neighborhood depends on, sweeps them for due re-checks, and does the pharmacy phone legwork nobody has time for — with a human approving every call.
Inspiration
Every month, coordinators at senior centers, clinics, and mutual-aid groups burn hours on the same chore: calling pharmacy after pharmacy to ask "do you have this in stock, what's the cash price, when can we pick it up?" Miss that chore and seniors miss refills. We built the neighbor that never gets tired of that chore: an agent that keeps a shared shortage board for the whole org, does the calling, and returns structured answers a human can act on — goal-driven phone work, not robocalls.
What it does
agentRx is a refill coordinator for a community org. Type a drug once
(atorvastatin 20mg x30), pick a radius, approve the pharmacy list — and
only then does it place real calls to all of them in parallel. Each call asks
for availability, cash price, and pickup time, and fills a result schema
(in_stock, cash_price_usd, pickup_time). You get back:
- a cheapest-first comparison table with per-call transcripts,
- a plain-language verdict ("Good news! Demo Pharmacy has paracetamol in
stock at $46.39") plus a follow-up prompt with tappable
tel:links, - refill reminders, an email summary, and a shortage board that watches drugs on a per-drug cadence ("we run out every 5 days") and flags due watches for re-check.
The consent gate in action — pharmacies found, nothing dialed until a human approves:

The shortage board — each watched drug carries its own re-check schedule, and the sweep surfaces due watches as call plans (never auto-calls):

How we built it
A supervisor coordinator with sub-agents finder / caller / board via
Strands Agent.as_tool(), sharing 9 domain @tool functions
(find_pharmacies, place_stock_call, get_call_result, set_reminder,
watch_drug, board, …):
- Google Places finds reputable open pharmacies; the org coordinator approves the list in chat. The agent graph itself is deliberately never allowed to place calls — the supervisor proposes call plans, the human approves. The same graph runs on Bedrock live or a deterministic offline model through the identical Strands event loop ($0 demo, 57 tests).
- Approved calls go out through
/v1/callsAPI with a strict result schema; results fan back in and the aggregator sorts cheapest in-stock first. - The web UI is a dark Leaflet map + paper chat (light mode included) with a
MOCK badge and inline Agent:/Pharmacy: transcripts. The board drawer shows
each watch's cadence (
every N days),next_check, and stale flag; a per-row editor re-schedules without leaving the drawer. run_board_sweep()is the background pass — stale watches + due reminders become call-plan proposals forPOST /api/sweep/ EventBridge. It never places calls.- A full mock mode ($0 spend) mirrors the live path so the whole flow is demoable and testable.
Challenges we ran into
Three real ones:
- Our validator rejected drug searches without a strength (
paracetamol→ "invalid input", zero calls placed) — strength had to become optional. - Every call failure was swallowed silently into "all calls failed," so we added end-to-end logging (request, status, truncated body, per-pharmacy cause surfaced in the UI).
Accomplishments that we're proud of
- Consent-gated calling done right: no call is ever placed until a human approves the list — including plans proposed by the AI coordinator itself. The screenshot above is the proof: "no calls placed yet" until approval.
- Per-drug re-check schedules: every watch carries its own cadence
(
check_every_days, 1–90, default 7) driving staleness,next_check, and the sweep — set from chat ("every 5 days"), the drawer add-row, or the per-row editor. - Parallel calls with structured results that actually drive UI: sorting, verdicts, transcripts, board snapshots.
- A demo mode with real trade-offs: varied prices, pickup times, distances, delivery flags — the comparison table tells a story on camera.
- Spend discipline: 20-call budget protected by a double-tap guard, fail-fast validation, and mock-first development.
- Accessibility touches: light mode, tappable
tel:follow-up links, one-tap watchlist.
What we learned
Voice AI's hard edge isn't the conversation — it's coverage: the region/language matrix decides what you can ship, and the API will tell you (422 + reason) if you log enough to listen. We also learned that handoff UX is the product for calling agents: when calls fail or stock is out, the specific reason and the next step matter more than the table. And that a deterministic mock isn't a shortcut — it's what lets you demo, test, and iterate without burning call budget. Finally: schedules must drive proposals, never auto-dials — the moment a cadence can place calls unattended, you've broken the consent story the whole project rests on.
What's next for agentRx
- A pilot with one community org running the board weekly — real stale rates will tune the default cadences.
- Caregiver SMS summaries when a watched drug comes back in stock.
Built with: Strands + Bedrock coordinator, Google Places, FastAPI, Leaflet.
Built With
- amazon-web-services
- bedrock
- eventbridge
- strands
Log in or sign up for Devpost to join the conversation.