Inspiration
The idea came from a real experience involving my sister in Greenville, New York. A friend left an RV at her house for what was meant to be a couple of months. Eighteen months later, when the owner was finally ready to move it, my sister was asked to arrange repairs before another friend collected it.
What sounded like a straightforward favor became a frustrating search. They struggled to identify the right kind of RV technician, explain the symptoms, and coordinate between the owner, the person storing the RV, and the person collecting it. In the end, they never found the right contractor.
The problem was not simply a missing directory. The process expected an ordinary customer to diagnose an RV's interconnected electrical, plumbing, appliance, chassis, and climate-control systems before asking for help. RV Assist Autopilot starts from a different premise: explain the problem once in ordinary language, then let a durable agent coordinate the work.
What it does
RV Assist Autopilot is an autonomous dispatcher for mobile RV repair. It does not stop after returning a list of technicians.
It accepts a repair description, qualifies the problem and urgency, applies deterministic safety checks, searches an eligible technician directory, rejects unverified or specialty-mismatched candidates, and ranks the remaining candidates with explainable factors. It records synthetic outreach to the best candidate, waits asynchronously for a response, and automatically replans after a decline or deadline. A mock external job can be created only after a technician acceptance and customer confirmation are both recorded.
The interactive console includes four synthetic scenarios:
- An urgent Phoenix air-conditioning failure with pets aboard.
- A stuck awning routed to a general mobile technician.
- A suspected propane leak that stops before outreach.
- Customer text containing instruction injection that is contained rather than obeyed.
Every workflow has an auditable evidence view containing its state transitions, latency, retries, fallback status, Google ADK and Gemini evidence, required tool invocation, synthetic delivery records, and final outcome.
How we built it
- Google ADK orchestrates the request-qualification agent.
- Gemini 3.6 Flash on Vertex AI interprets the live request and affects its routing decision.
- The agent must invoke
calculate_safety_baseline, a narrow deterministic tool. - Cloud Run hosts the private TypeScript API, interactive console, and event endpoints.
- Firestore stores durable workflow state with optimistic version checks.
- Cloud Tasks schedules exact technician-response deadlines.
- Pub/Sub accepts resumable external workflow events.
- Artifact Registry and Google Cloud Build produce immutable
linux/amd64application images. - Terraform defines the Google Cloud resources and least-privilege service identities.
- Vitest and three evaluation suites gate ordinary behavior, autonomy, safety, instruction-injection containment, and external-adapter trust.
The architecture separates probabilistic language understanding from consequential actions. Gemini produces schema-constrained qualification evidence, but application code independently restores safety flags, enforces an urgency floor, verifies technician eligibility, controls state transitions, and blocks job creation until the required confirmations exist. Missing tool use, invalid output, model failure, or timeout activates a deterministic fallback instead of losing the workflow.
The technician score uses explicit inputs: specialty fit, same-day availability, response reliability, rating, and synthetic distance. Eligibility is enforced before ranking, so a high score cannot make an unverified or mismatched candidate contactable.
Challenges we ran into
Building an agent that can wait
Dispatch cannot finish inside one HTTP request. A technician may respond later, decline, or never respond. Durable Firestore state, scheduled Cloud Tasks deadlines, explicit transitions, idempotency keys, and stale-event handling were necessary to resume safely without duplicating outreach or jobs.
Balancing autonomy and safety
Escalating everything looks safe but provides little value. Acting on every request is unsafe. We created named escalation reasons, a shared safety-flag taxonomy, a routable general-repair category, deterministic eligibility checks, and separate autonomy and adversarial gates so improving one property cannot silently damage the other.
Treating external data as untrusted
The workflow does not assume an adapter's technician results are safe. It re-checks verification, service area, specialty, and availability before outreach. A poisoned-directory evaluation confirms that an unverified or mismatched technician cannot be dispatched.
Making model evidence useful without exposing hidden reasoning
The persisted trace contains the agent framework, requested and resolved model, required tool calls, latency, token count, a concise decision summary, evidence, and fallback reason. It never requests or displays private chain-of-thought.
Accomplishments that we're proud of
The deployed demonstration completes the entire coordination loop: qualify an urgent Phoenix request through Google ADK and Gemini, contact a first synthetic technician, replan after a decline, record a second technician's acceptance, obtain customer confirmation, and create an idempotent mock external job.
The current candidate passes 63 automated tests. Its 10-scenario offline evaluation reports 100% category, urgency, escalation, matching, and recovery scores with zero unsafe actions. The 51-scenario autonomy suite reports 100% autonomous completion where action is permitted and 100% required-stop accuracy. The 22-scenario adversarial suite reports zero unsafe actions, zero forbidden safety-flag violations, and zero unverified or specialty-mismatched dispatches.
The service is deployed by immutable image digest, and its Terraform configuration has zero drift.
What we learned
Useful agency is less about producing a brilliant answer and more about managing state, uncertainty, time, tools, and failure.
Gemini is valuable for interpreting ambiguous language. Deterministic code is better for permissions, eligibility, idempotency, state transitions, and non-bypassable safety rules. Combining the two created a system that is flexible without making consequential decisions opaque.
Evaluation also changed the product. Adversarial cases exposed masked hazards, overly broad text matching, instruction steering, and poisoned adapter results. Each failure became an application-level guard and regression scenario.
Data and prior-work disclosure
The demonstration uses only synthetic customer requests, technician profiles, availability, responses, outreach records, and jobs. It does not contact real technicians or customers and does not create real marketplace jobs.
NicheWave and its RV Assist marketplace existed before this hackathon. They are not included in this repository and were not created as part of this submission. This repository contains only the new RV Assist Autopilot agent, workflow, adapters, tests, evaluations, documentation, and Google Cloud infrastructure created during the submission period beginning 2026-08-17. Autopilot treats NicheWave/RV Assist solely as an external dependency through the NicheWaveAdapter interface. The independently runnable demonstration uses a mock adapter; it does not import NicheWave source code or access its database.
What's next
- Validate the workflow with consented Phoenix RV technicians and real repair scenarios.
- Add an approved outreach provider behind the existing adapter boundary.
- Learn ranking weights from assignment outcomes.
- Add customer-visible status and technician arrival estimates.
- Expand intake only after consent, privacy, and multimodal evaluation requirements are defined.
Our north-star outcome is simple: one request in, the right confirmed technician out, with every decision explainable.
Repository and local demo
- Repository:
https://github.com/kibukamusoke/rv-assist-autopilot - Local:
cp .env.example .env && npm ci && npm run check && npm run demo:workflow - Interactive console: run the HTTP service and open
/console.
Built With
- cloud-run
- cloud-tasks
- firestore
- gemini-3.6-flash
- google-adk
- google-cloud-build
- pub-sub
- terraform
- typescript
- vertex-ai
Log in or sign up for Devpost to join the conversation.