Inspiration
When disaster hits a neighborhood, the "who needs what, where" vs. "who has what to give" coordination almost always runs on the same fragile stack: a hand-updated spreadsheet, a maxed-out Signal group, and a Discord server, staffed by exhausted volunteers reading every single post themselves. This isn't hypothetical — it's exactly what Mutual Aid LA Network (MALAN) ran during the January 2025 Eaton/LA wildfires. Their public reporting describes a spreadsheet that got 100,000 hits in a single day, a Signal group that hit its 1,000-member cap, and donations piling up at some sites with "no plan to sort, store, or continue the work" while other needs went unmatched. Existing open-source tools in this space (Ruby for Good's mutual-aid platform, Crisis Cleanup) only digitize the spreadsheet — a human dispatcher still has to read every entry and manually decide every match. The actual bottleneck — triage, matching, deduplication, and follow-up — has never been automated.
Who it's for
Volunteer coordinators at neighborhood mutual-aid networks, disaster-response coalitions, and small community orgs (community fridges, tenant associations, faith-based relief efforts) who run "needs vs. offers" operations with volunteers instead of paid logistics staff. This is a tool for the group running the response, not a single household. It's our entry in the Good Neighbor Agents track.
What it does
Neighbor Dispatch is a Strands Agents SDK pipeline that takes the exact same messy free-text posts coordinators already collect ("need water in Altadena, family of 4, ASAP" / "have a generator to lend, Highland Park") and turns them into a living, matched, deduplicated, escalation-aware coordinator dashboard — with a human clicking Approve or Reject on every proposed match, always:
- Structured extraction — a Strands
Agent(swappable across Bedrock, Anthropic, or OpenAI, with a deterministic offline fallback so the whole system runs with zero API key) turns raw text into a category, urgency, zone, quantity, and contact. - Deterministic matching engine — pure Python geo-distance and category-taxonomy scoring ranks candidate need↔offer pairs, fully unit-tested independent of any model call.
- Duplicate detection — flags likely repeat posts by the same person or about the same item in the same area within a time window.
- SLA / escalation checks — an urgent need unmatched past a configurable window, or a stale offer, gets surfaced automatically instead of silently sitting in a chat scroll.
- Human approval, enforced in code, not just claimed — a match can only move from "pending" to "approved" through one single, tested code path in the dashboard; nothing is ever auto-committed.
- Match Advisor agent — an optional Strands
Agentwired with 5 real@toolfunctions (category match, geo distance, score, duplicate check, SLA check) lets a coordinator ask it free-form questions and watch it genuinely reason with tools, when a live model key is configured.
How we built it
Python, strands-agents (Strands Agents SDK) for the extraction and Match Advisor agents, Flask for the coordinator dashboard, plain JSON-file storage for the hackathon build (swappable for a real database), and pytest for a fully offline test suite (45 tests) that verifies every matching/dedup/escalation rule and the extraction fallback path with zero live model calls. An optional deployment path to Amazon Bedrock AgentCore is implemented (deploy/agentcore_app.py) and documented, though not required to run the demo.
Challenges we ran into
Making the system meaningfully testable and demoable without requiring a live LLM API key was the biggest design constraint — we built a deterministic offline extraction fallback and a scripted-model stand-in (src/scripted_model.py) so every judge can run the whole pipeline, including a realistic agent tool-calling loop, with zero credentials. We also deliberately made human approval a hard code-level gate rather than a UI convention, since a mutual-aid matching tool that could silently auto-commit a bad match would be worse than no tool at all.
Accomplishments that we're proud of
A fully offline, 45-test pytest suite covering extraction, matching, dedup, escalation, and the human-approval gate itself; a working end-to-end CLI demo (python demo.py) and Flask dashboard (python demo.py --serve); and a worked example (python demo.py --worked-example) that shows the real Strands agent event loop reasoning through a live coordinator question step by step, fully offline.
What we learned
How much of a "matching agent" problem is actually a deterministic-systems problem in disguise: the parts that most need to be correct and trustworthy (matching math, dedup, SLA breach detection, the approval gate) are best kept out of the LLM entirely, with the agent layered on top for extraction and free-form reasoning where judgment and language understanding genuinely help.
What's next for Neighbor Dispatch
Live Bedrock AgentCore deployment, a real (non-JSON-file) datastore, SMS/WhatsApp intake so posts never have to be manually copied out of Signal or Discord in the first place, and a live demo video and AWS Builder ID to complete the hackathon submission checklist.
Submission checklist status
- [x] Public GitHub repo with full source, tests, and setup instructions: https://github.com/kshivam4781/neighbor-dispatch
- [x] MIT license (visible in the repo's About section)
- [x] README
- [x] Architecture diagram (
docs/architecture.png/.svg/.md) - [x] 45/45 tests passing, full offline demo verified working
- [ ] Demo video — not yet recorded
- [ ] AWS Builder ID — not yet obtained
- [ ] Live AgentCore deployment — wrapper implemented and tested offline, not deployed to a live endpoint
This submission is saved as a draft until the demo video and AWS Builder ID are added.

Log in or sign up for Devpost to join the conversation.