Explain It Like I’m a Golden Retriever


Anvil Mini-App

Because sometimes the smartest thing you can do is say it like you’re talking to a very good dog.

What you’ll ship: a tiny Anvil app that rewrites any paragraph in three modes — Expert, Manager, and Dog — using an LLM via OpenRouter.
Why it’s good: zero GPUs, five minutes to wire up, infinite snickers.


TL;DR

  • Stack: Anvil (client + server Python), OpenRouter (LLM gateway).
  • Modes: Expert (dense), Manager (PowerPoint-safe), Dog (happy brain cell).
  • Security: API key in App Secrets, never client code.
  • Bonus: graceful local fallback when the API is rate-limited.

App Flow (What Happens)

flowchart TD
  A[User pastes text] --> B[Selects mode: Expert / Manager / Dog]
  B --> C[Click Submit]
  C --> D[Client validation]
  D -- ok --> E[anvil.server.call('explain_text')]
  E --> F[Server builds prompt]
  F --> G[POST to OpenRouter /chat/completions]
  G -- success --> H[Return rewritten text]
  G -- rate limit / error --> I[Local fallback rewrite]
  H --> J[Show output]
  I --> J[Show output + note about fallback]

UI Layout (Anvil Designer)

Add these components to your form (e.g., ExplainItForm):

  • input_textTextArea (user input)
  • mode_dropdownDropDown (Expert / Manager / Dog)
  • submit_buttonButton (event: click)
  • helper_labelLabel (optional hints)
  • output_textTextArea (read-only recommended)

Server Module (OpenRouter version)

Add this to a Server Module (e.g., ServerModule.py).
Set an App Secret called OPENROUTER_API_KEY with your key.

import re
import time
import anvil.server
import anvil.http
from anvil.secrets import get_secret

PROMPT_TEMPLATES = {
    "Expert":  "Rewrite the following text in precise technical language for a subject-matter expert:\n\n{text}",
    "Manager": "Rewrite the following text as a high-level executive summary, avoiding jargon. Highlight purpose, outcomes, timelines, and risks:\n\n{text}",
    "Dog":     "Rewrite the following text for a very enthusiastic Golden Retriever. Use short, simple sentences and a friendly tone:\n\n{text}",
}

OPENROUTER_API_KEY = get_secret("OPENROUTER_API_KEY")
OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
DEFAULT_MODEL = "mistralai/mistral-7b-instruct"  # Free-tier friendly at time of writing

def _rewrite_locally(text: str, mode: str) -> str:
    """Ultra-simple fallback so the demo never 404s your dignity."""
    t = (text or "").strip()
    if mode == "Expert":
        subs = {r"\bcan't\b":"cannot", r"\bwon't\b":"will not", r"\bn't\b":" not",
                r"\bI'm\b":"I am", r"\bwe're\b":"we are", r"\bit's\b":"it is"}
        for pat, rep in subs.items():
            t = re.sub(pat, rep, t, flags=re.I)
        return ("Technical restatement:\n"
                f"- Scope: {t}\n- Method: deterministic processes; minimize ambiguity.\n"
                "- Note: heuristic fallback (no model call).")
    if mode == "Manager":
        bullets = re.split(r"(?<=[.!?])\s+", t)[:4] or [t]
        bullets = [b for b in bullets if b]
        return "Executive summary:\n" + "\n".join(f"- {b.strip()}" for b in bullets)
    if mode == "Dog":
        s = re.sub(r"\b(anomal(y|ies))\b", "weird stuff", t, flags=re.I)
        s = re.sub(r"\bdetect(ion)?\b", "spot", s, flags=re.I)
        parts = [p.strip() for p in re.split(r"(?<=[.!?])\s+", s) if p.strip()]
        wag = " 🐶"
        return "Tail-wagging edition:\n" + " ".join(p + wag for p in parts[:6])
    return t

def _call_openrouter(prompt: str, model: str = DEFAULT_MODEL) -> str:
    headers = {
        "Authorization": f"Bearer {OPENROUTER_API_KEY}",
        "Content-Type": "application/json",
        "HTTP-Referer": "https://hirabarton.io",
        "X-Title": "Explain It Like I'm a Golden Retriever",
    }
    payload = {
        "model": model,
        "messages": [
            {"role": "system", "content": "You are a helpful rewriting assistant."},
            {"role": "user", "content": prompt},
        ],
        "temperature": 0.7,
    }
    resp = anvil.http.request(OPENROUTER_URL, method="POST", headers=headers, data=payload, json=True)
    return resp["choices"][0]["message"]["content"].strip()

@anvil.server.callable
def explain_text(text: str, mode: str, allow_fallback: bool = True) -> str:
    if mode not in PROMPT_TEMPLATES:
        raise ValueError("Invalid mode")
    text = (text or "").strip()
    if not text:
        raise ValueError("Empty input")

    prompt = PROMPT_TEMPLATES[mode].format(text=text)

    try:
        return _call_openrouter(prompt)
    except anvil.http.HttpError as e:
        # If rate-limited or model hiccups, keep the app useful
        if allow_fallback:
            local = _rewrite_locally(text, mode)
            detail = getattr(e, "content", "") or str(e)
            return f"{local}\n\n[Note: Used local fallback due to API error: {detail}]"
        raise

Client Form (event handlers)

from ._anvil_designer import ExplainItFormTemplate
from anvil import *
import anvil.server

class ExplainItForm(ExplainItFormTemplate):
  def __init__(self, **properties):
    self.init_components(**properties)

    self.mode_dropdown.items = [
      ("— Select mode —", None),
      ("Expert — precise & technical", "Expert"),
      ("Manager — executive summary", "Manager"),
      ("🐕 Dog — tail-wagging edition", "Dog"),
    ]
    self.mode_dropdown.selected_value = None
    if hasattr(self, "submit_button"):
      self.submit_button.enabled = False
    self.mode_dropdown.set_event_handler("change", self.mode_dropdown_change)

  def mode_dropdown_change(self, **event_args):
    helper = {
      "Expert":  "Dense, accurate, and possibly migraine-inducing.",
      "Manager": "High-level, digestible, suspiciously PowerPoint-ready.",
      "Dog":     "Simple words. Big wags.",
      None:      ""
    }
    self.helper_label.text = helper.get(self.mode_dropdown.selected_value, "")
    self.submit_button.enabled = bool(self.mode_dropdown.selected_value)

  def submit_button_click(self, **event_args):
    text = (self.input_text.text or "").strip()
    mode = self.mode_dropdown.selected_value
    if not text or not mode:
      self.output_text.text = "Please enter text and select a mode."
      return
    self.output_text.text = "Processing..."
    try:
      out = anvil.server.call("explain_text", text, mode)
      self.output_text.text = out
    except Exception as e:
      self.output_text.text = f"Error: {e}"

https://hirabarton.anvil.app