Inspiration
California’s SB 1383 requires many food businesses to donate edible surplus food and keep records of it, yet most of that food is still thrown away. The reason is not that people don’t care. Donating at 9 PM is a pile of tradeoffs nobody has time for: the fastest courier costs money, the free volunteer might not show, the closest shelter already got food today while another has waited five days, and pasta has two hours before it isn’t safe.
What it does
Uplink has two sides: a customer site that a café manager can use in under a minute, and an ops dashboard that shows every message, vote, and veto between the agents, live.
The business can tell Uplink what’s left in three ways. They can say it: tapping the mic and saying “we’ve got two pepperoni pizzas, a dozen cookies, and five bananas” works, because ElevenLabs Scribe transcribes it and Claude matches it to the business’s own menu, filling in quantities and allergens. They can take a photo or pan a short video over the leftovers, and Claude vision names and counts the food. A video is reduced to four frames so nothing is counted twice, and menu items bring their known allergens with them. Or they can tap items from the business’s menu, and anything not on it can be added once and will be there next time. The business then confirms, and Uplink tracks the pickup through delivery and generates the SB 1383 donation record automatically.
Every shelter and driver has its own agent. Shelters accept, take part of the donation, or decline, and drivers either bid or refuse trips beyond their range. Three negotiators with competing goals then decide where the food goes, with no boss. Speed cares about arrival time and driver reliability, and won’t accept less than 10 minutes to spare or a driver under 50% reliable. Cost cares about what the trip costs, and won’t accept anything over $20 for one donation. Need cares about whoever has waited longest, and won’t feed a shelter that already ate today while another is still waiting.
The negotiators propose plans, vote with a reason, object or veto, and revise over up to three rounds. Each round the bar to accept drops, to 90%, then 78%, then 65% of their own best option, so they give ground slowly instead of folding. In our Majority with dissent demo, 25 servings of pasta from Jack O’Neill Restaurant at Dream Inn needed a shelter at 6 PM. Speed proposed Salvation Army via a paid courier. Cost proposed the free volunteer, Sam, saying it costs nothing. Need proposed Walnut Avenue Family & Women’s Center, which had waited 5 days for food and had room for 50 more servings. Speed objected to Sam, who is only 50% reliable with 35 minutes of margin, saying a no-show would spoil the food. By round three, Speed and Cost each moved toward Need’s shelter from opposite sides. The result was Walnut Avenue via a paid courier, a majority of 2 to 1, with Cost’s disagreement kept on record: “$15.36 when a volunteer route costs $0.00 and is also safe.”
Consensus isn’t always right, so a negotiation can end in one of six ways. It can reach consensus, a majority with dissent on record, or a fast decision when food is about to spoil. It can also stop to ask a person, when the only compromise crosses someone’s red line, when the goals are truly irreconcilable, or when the decision depends on an unconfirmed fact, such as whether there are peanuts. In that last case, the person gets a “decide by” deadline so the food never spoils while waiting for an answer.
Safety is never part of the negotiation. Code removes every plan that breaks a food-safety rule, covering the fridge, allergens, capacity, hours, and time to spoil, before any agent sees it.
Once the agents agree, a dispatcher agent speaks the request on the shelter’s phone page, in its own ElevenLabs voice. The shelter answers out loud, ElevenLabs Scribe turns the answer into text, and the agents read it as yes, part, or no. If the shelter’s page isn’t open, the food goes out without asking. Voice works in the other direction too: businesses can donate by voice.
When the world changes, the agents re-plan. If a shelter says it’s full, a driver cancels, or a new pantry joins mid-run, each agent says whether the news changed its mind, such as “That changes my pick…” or “Still Walnut Avenue…”. An agent that warned about an unreliable driver who then no-showed gains vote weight in future negotiations.
How we built it
- Agents on AGNTCY: Each of the 16 agents (7 shelters, 6 drivers, 3 negotiators) runs as its own service, in its own process, and talks over A2A on NATS using Cisco Outshift’s AGNTCY app-sdk. Each step of a donation is one A2A broadcast. An agent directory with heartbeats lets agents find each other, and a stopped agent drops out while the rest carry on. Every agent publishes an A2A AgentCard and an OASF record, served at /agntcy/records.
- The table only relays: The negotiation table passes messages and counts votes. It never picks a plan.
- Claude (Anthropic API): Claude does four jobs. It speaks for each negotiator, where each sees only the facts its goal cares about and votes against a numeric bar. It reads photos and videos of food, turns a spoken sentence into a menu order, and falls back to deterministic rules if a call fails or times out, so the demo never stalls.
- ElevenLabs: Flash v2.5 text-to-speech with a distinct voice per agent, plus Scribe speech-to-text for voice donations and spoken shelter answers.
- Live by design: The dashboard streams each proposal and objection as soon as an agent says it, and shows who’s still thinking. The simulated clock pauses while agents deliberate, so no food-safety time is lost to model latency.
- Stack: Python, Flask, AGNTCY app-sdk, A2A, NATS, Claude, ElevenLabs, Leaflet, YOLO for an optional counter camera, Qwen2.5-VL on an NVIDIA Brev GPU as a backup vision model, and vanilla HTML/CSS/JS. 56 automated tests.
Challenges we ran into
- Our agents always agreed. With rules alone, every agent lowered its bar each round, and every negotiation ended in consensus. Real disagreement appeared only once each agent had a red line it would not trade away.
- Then our Claude agents agreed even faster. With Claude speaking for each agent, Cost would cite the shelter’s 5-day wait and accept a paid courier in round 1, while Speed argued about price. The fix: each agent now sees only the facts it cares about and votes against a bar that drops each round. If Claude accepts something far below the bar, the rules overrule that vote. The result is real three-round negotiations that can end in a majority with dissent on record.
- A fallback that spoiled the food. Our first “nobody answered the coordinator” rule waited until 15 minutes before spoilage, when every option already needed 25. It now acts at the last moment an option can still arrive safely.
- Distributing without changing a single decision. Moving every agent into its own process, then onto A2A over NATS, had to produce exactly the same decisions. A test replays all 9 scenarios both ways: identical results, 1,107 A2A messages, 0 failed. = Model latency on stage. A full Claude debate takes several seconds. Instead of hiding that, we stream it, so the audience watches each agent speak while the next one is still thinking.
Accomplishments that we're proud of
- On 100 random scenarios the system had never seen, the negotiating team lost 82% less food than a nearest-shelter baseline and 49% less than the best agent working alone. It lost the least food (or tied) in 95 of 100 runs, reached 440 shelters vs 386 for the fairness agent alone, and was never worse than the baseline in any run.
- Each agent alone fails on its blind spot: Speed overspends on couriers, Cost trusts volunteers who don’t show, and Need accepts risky trips. Together, they veto each other’s blind spots.
- We disclose the cost: the team spends more than Cost alone ($2,115 vs $1,305), though 28% less than the baseline. It asks a person about once per scenario, because it refuses to force a bad compromise.
- The 16 agents on AGNTCY make identical decisions to the in-process version, and keep working when an agent is stopped live.
- A café manager can finish a customer flow by voice in one sentence.
What we learned
- Safety rules in code do most of the work against a naive approach. Negotiation earns its keep under uncertainty: no-shows, scarcity, and unconfirmed allergens.
- LLM agents cave unless you design against it. Giving each one only its own facts, and a number to vote against, kept them in character.
- Each agent is right about something the others ignore. The team’s value is that one can veto another’s blind spot.
- The protocol is separate from the decisions: the same agents decide the same way in one process, over HTTP, or over A2A/NATS.
What's next for Uplink
- Real phone calls: the dispatcher agent dialing shelters with ElevenLabs voices, and shelters answering by phone.
- Real shelters and drivers in Santa Cruz, with routing on real roads.
- Shared directory: publishing our OASF records to a shared AGNTCY Directory so other food-rescue agents can discover ours.
- Ablation study: measuring what each mechanism (red lines, concession, adaptive vote weight) contributes.
Built With
- a2a
- agntcy
- anthropic-claude
- css
- elevenlabs
- flask
- html
- leaflet.js
- nats
- nvidia-brev
- python
- vllm
- yolo-world
Log in or sign up for Devpost to join the conversation.