Skip to content
HomeProjectsHighlightsBlogPlaygroundRésuméAbout

Neighborly

by Michael Rusu & team

We built a mutual-aid platform that helps a community see where help is needed. Offers, requests, organizations, and volunteer activity become a shared picture of local needs, with agents supporting coordination.

Code Devpost Video
Community

ShellHacks 2025
Community coordination · Agent systems

Explore the project ↓
The problemMy contributionArchitectureFinding shortagesAgent coordinationResultsDemo

The problem

Someone has groceries to share. Someone nearby needs a ride. A local organization is short on supplies. Each post makes sense on its own, but the community needs a way to see the gaps and connect available help with requests.

Neighborly brings offers, requests, and volunteer events into one interface. Its coordination layer organizes those records, identifies categories under pressure, and develops suggestions that can appear in the community feed.

My contribution

I helped build the agent-supported community workflow and connect the React/Tailwind product, Supabase data layer, and Google ADK services. The work focused on making community records available to the analysis and bringing the resulting needs back into the product.

Architecture

Community records enter React and Supabase, then organization synchronization, event analysis, supply-demand balancing, and volunteer matching produce priority needs and help suggestions.
Figure 1. Community records feed an ordered agent cycle. PNGEditable Excalidraw Download figure

The repository defines an orchestrator with four operational agents: organization synchronization, event analysis, supply-demand balancing, and volunteer matching. A cycle runs them in sequence and collects a result record for each step.

Synchronization and event analysis establish context for the balancing step. Volunteer matching depends on the balancer. Each result carries a status, output, execution time, and timestamp. Successful dependency outputs are passed into later steps.

The React interface and Supabase-backed records provide the product surface around this workflow. Google ADK supplies the agent infrastructure, while Python methods implement explicit counting and sequencing rules.

Finding shortages

The balancer groups posts by category and counts offers and requests. In this revision, the counting method uses the is_free field to separate the two groups. It requires at least three requests before declaring a shortage.

With offers present, the shortage ratio is the excess of requests over offers divided by the offer count. A ratio greater than 0.3 triggers a shortage. When offers are zero, the ratio is unbounded and the minimum-request condition still applies.

Fixed fictional counts compare requests and offers: food and clothing trigger shortages, transport and supplies stay within the source thresholds.
Figure 2. Fixed community counts exercise the shortage rule. PNGEditable Excalidraw Download figure

The example contains fictional posts. Food has six requests and two offers; clothing has three requests and zero offers. Both trigger the source rule. Supplies has thirteen requests and ten offers, placing it exactly at the threshold and leaving the shortage flag clear.

Python · shortage calculation · excerptSource ↗
requests = [p for p in category_posts_list if not p.get('is_free', True)]
offers = [p for p in category_posts_list if p.get('is_free', True)]

request_count = len(requests)
offer_count = len(offers)

shortage_ratio = (request_count - offer_count) / max(offer_count, 1) if offer_count > 0 else float('inf')
is_shortage = (request_count >= self.minimum_requests and 
              shortage_ratio > self.shortage_threshold)

A separate severity score divides the unmet request count by the number of requests. The alert builder uses that score and the most frequent request location to create a priority-need record.

Agent coordination

The orchestrator checks each step’s dependencies before running it. A missing result or a status other than completed causes the dependent step to be skipped. The cycle continues collecting statuses so its final record shows what happened across the workflow.

The successful agent order is organization sync, event analysis, supply-demand, and volunteer matching. When sync fails, event analysis completes while its dependent balancing and matching steps are skipped.
Figure 3. Dependency checks shape the execution sequence. PNGEditable Excalidraw Download figure
Python · dependency handlingSource ↗
def _check_dependencies(self, dependencies: List[str], results: List[AgentResult]) -> bool:
    for dep in dependencies:
        dep_result = next((r for r in results if r.agent_name == dep), None)
        if not dep_result or dep_result.status != AgentStatus.COMPLETED:
            return False
    return True

Volunteer matching combines skill, location, and availability scores with weights of 0.5, 0.3, and 0.2. Candidate matches are ranked and capped at three suggestions per request. The source uses explicit thresholds to decide which suggestions proceed to help-offer creation.

The safety experiment

The repository also contains a separate risk-classification training script. It combines TF-IDF text features with numerical profile features and trains a PyTorch classifier on simulated safety data. The four-agent orchestrator does not invoke this training script. This experiment sits alongside the coordination workflow in the project.

Results

Neighborly was developed for ShellHacks 2025 as a mutual-aid prototype connecting community posts, priority needs, and suggested help. The demonstration shows the interface built by the team.

The case-study fixtures exercise shortage counts, zero-offer handling, the strict threshold boundary, and completed, failed, missing, and skipped dependencies. They use fictional records and isolated source methods. The neighborhood animation illustrates fixed routes through a fictional community.

Demo

Watch the Neighborly demo on YouTube.

with by michael