Documentation Index
Fetch the complete documentation index at: https://mintlify.com/davidmpizarro/QuipuEco-Hackaton/llms.txt
Use this file to discover all available pages before exploring further.
POST /chat powers the QuipuEco voice agent — a conversational assistant that answers recycling questions in natural Spanish and, crucially, can drive the frontend to open the map or the impact dashboard on the user’s behalf. Unlike a generic chatbot, every request carries the current waste classification result as structured context, so the model always knows exactly what material the user is holding. The backend passes this context alongside the conversation history and an optional geolocation to Gemini gemini-3.1-flash-lite, which returns both a spoken response and an optional structured action instruction.
Request
Endpoint:POST http://localhost:8000/chat
Content-Type: application/json
Body Parameters
The user’s transcribed message text, captured by the Web Speech API in
AgenteVoz.jsx. Must be a non-empty string. Example:
"¿Dónde puedo reciclar esta botella?".The last up to 10 conversation turns. Sent as
historial.slice(-10) in the
frontend to bound request size. Each entry is an object with two fields:Omit or send an empty array [] when starting a fresh conversation.The full classification result object returned by
POST /clasificar, or
null if the user has not yet scanned any item. When present, the agent uses
this object to answer material-specific questions without the user needing to
re-state what they are holding. The frontend always sends the most recent
classification result:User latitude in decimal degrees, obtained from the browser’s
navigator.geolocation API. Optional — if omitted, the agent will not be
able to calculate distances or name the nearest collection point.
Example: -12.0445.User longitude in decimal degrees. Optional — sent together with
lat.
Example: -76.9678.Geolocation coordinates enable the backend’s Haversine distance algorithm to
calculate how far the user is from each collection point in Lima and name the
closest Tambo or Centro Verde in the response. Without
lat/lng, the agent
can still answer general recycling questions but will not provide
distance-specific information such as “El Tambo Alondras está a 300 metros.”Code Examples
Example Request Body
Response
Content-Type:application/json
A successful turn returns HTTP 200 with the following JSON object:
Response Fields
The agent’s text response, spoken aloud by the browser’s
SpeechSynthesis
API immediately after the request completes. Written in natural Spanish
optimised for TTS playback at rate: 0.95. Example: "El Tambo Alondras está a 300 metros de aquí, en la Av. Las Alondras 297, Santa Anita.".An optional navigation instruction for the frontend. When the agent
determines that the user’s request is best served by switching views, it sets
this field to one of two string values:
The material category string used to filter the map when
accion === "mapa".
Matches the canonical tipo values from /clasificar: "plastico",
"papel", "metal", "vidrio", "organico", "electronico",
"peligroso", or "no_reciclable". null when accion is not "mapa".Example: "plastico".When
accion === "mapa", the name of the specific collection point the agent
identified as the closest or most relevant. App.jsx uses this alongside
accion_data: if puntoCercano is set and accion_data matches the
current classification type, punto_cercano is forwarded to
VistaMapaPuntos as the puntoDestino prop instead of the category string.
null when no specific point was identified or when accion is not
"mapa".Example: "Tambo Alondras - Santa Anita".Example Responses
How Actions Are Handled in the Frontend
AgenteVoz.jsx processes the response in enviarMensaje(). The respuesta text is always spoken via TTS first. If an accion is present, the component stores a pending action in state and dispatches it after a 1.8-second delay — enough time for the agent’s voice response to begin playing before the view transitions:
onAccion callback is defined in App.jsx and routes to the correct view:
accion === "mapa"→ CallshandleVerMapa. Whenpunto_cercanois set andaccion_datamatches the current classification’stipo,punto_cercano(a string) is passed as thedestinoargument; otherwiseaccion_datais used.VistaMapaPuntosreceives the result as itspuntoDestinoprop: a string value is treated as a category filter for the collection-point list.accion === "dashboard"→ Switches the app to theImpactDashboardview.
Conversation Examples
The following table shows howaccion and accion_data vary with different user intents:
| User message | accion | accion_data | Notes |
|---|---|---|---|
"¿Dónde puedo reciclar esta botella?" | "mapa" | "plastico" | Requires contexto_residuo.tipo === "plastico" |
"Muéstrame los puntos de electrónicos" | "mapa" | "electronico" | Explicit category override |
"Muéstrame mi impacto" | "dashboard" | null | Stats view trigger |
"¿Cómo preparo el cartón?" | null | null | Instructional — text/voice only |
"¿Cuál es el Tambo más cercano?" | "mapa" | "plastico" | With lat/lng → sets punto_cercano |
"¿Qué es el plástico PET?" | null | null | General knowledge — no navigation |
Error Responses
Returned when
mensaje is missing or historial entries are malformed. The
detail array follows FastAPI’s standard validation format.Returned when the Gemini API call fails. The frontend catches this silently
and speaks a fallback message to the user: