commute-copilot / app.py
allanmartinez's picture
Commute Copilot: LangChain agent from the Sep 11 lab
a775f16 verified
Raw History Blame Contribute Delete
3.38 kB
"""Gradio front end for Commute Copilot (this is the Hugging Face Space entry point)."""
import os
import gradio as gr
from commute_copilot import CommuteConfig, ask, build_config
from commute_copilot.config import LINES, line_stations
DEFAULT = CommuteConfig()
EXAMPLES = [
"I need to head downtown. When should I leave, and do I need a jacket?",
"Is anything wrong with the trains right now?",
"Should I bring an umbrella this afternoon?",
]
def station_choices(route: str):
try:
return [(name, stop_id) for stop_id, name, _, _ in line_stations(route)]
except Exception:
return [(DEFAULT.stop_name, DEFAULT.stop_id)] if route == DEFAULT.route else []
def on_line_change(route):
choices = station_choices(route)
value = DEFAULT.stop_id if route == DEFAULT.route else (choices[0][1] if choices else None)
return gr.Dropdown(choices=choices, value=value)
def respond(message, history, route, stop_id, walk_minutes, mode):
if not os.environ.get("OPENROUTER_API_KEY"):
return ("OPENROUTER_API_KEY is not set. On Hugging Face, add it under Settings -> "
"Variables and secrets, then restart the Space.", "")
try:
cfg = (DEFAULT if (route, stop_id, int(walk_minutes)) == (DEFAULT.route, DEFAULT.stop_id,
DEFAULT.walk_minutes)
else build_config(route, stop_id, walk_minutes))
except Exception as e:
return f"Could not load that station from the MBTA ({e}).", ""
try:
result = ask(message, cfg, mode="multi" if mode.startswith("3") else "single",
history=history)
except Exception as e:
# Most often a 429 from the free OpenRouter tier (20/min, 50/day)
return f"The model call failed: {type(e).__name__}: {e}", ""
answer = result.answer
if result.invented_times:
answer += ("\n\n⚠️ Guardrail 3: these times did not come from live data, so treat "
f"them as unverified: {', '.join(result.invented_times)}")
return answer, result.summary()
with gr.Blocks(title="Commute Copilot") as demo:
gr.Markdown(
"# 🚇 Commute Copilot\n"
"Tells you **when to walk out the door** for the next MBTA train and **whether the "
"weather changes the plan**. Uses live MBTA predictions, MBTA service alerts and "
"Open-Meteo forecasts. Built with LangChain and LangGraph.")
with gr.Row():
line = gr.Dropdown(LINES, value=DEFAULT.route, label="Line")
station = gr.Dropdown(station_choices(DEFAULT.route), value=DEFAULT.stop_id, label="Station")
walk = gr.Slider(0, 30, value=DEFAULT.walk_minutes, step=1, label="Walk to platform (min)")
mode = gr.Radio(["Single agent", "3-agent graph"], value="Single agent", label="Architecture")
line.change(on_line_change, line, station)
details = gr.Textbox(label="Run details: ReAct trace, tokens, guardrails", lines=14,
render=False)
gr.ChatInterface(
respond,
additional_inputs=[line, station, walk, mode],
additional_outputs=[details],
examples=[[q] for q in EXAMPLES],
cache_examples=False,
)
with gr.Accordion("Run details", open=False):
details.render()
if __name__ == "__main__":
demo.launch()