inside-out / README.md
peteryej's picture
Fix Space config: merge duplicate README frontmatter blocks
d1e8e99
|
Raw
History Blame Contribute Delete
6.66 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: Inside Out
emoji: πŸ’¬
colorFrom: yellow
colorTo: purple
sdk: gradio
sdk_version: 6.16.0
app_file: app.py
pinned: false
license: apache-2.0
short_description: Let your emotions speak for you
tags:
  - track:wood
  - sponsor:openai
  - sponsor:nvidia
  - achievement:offgrid
  - achievement:offbrand
  - achievement:llama
  - achievement:sharing
  - achievement:fieldnotes

Inside Out β€” Chat with Your Emotions 🌟

A warm little Gradio app, inspired by Pixar's Inside Out, where a cast of emotion agents chime in on whatever is on your mind. It isn't an advice bot β€” it's a gentle mirror that helps you notice and name what you're really feeling.

πŸ“£ Featured on X: @QuicklyLearnIt

You type a message. A handful of emotions light up and respond, each in their own distinct voice, followed by a soft reflection inviting you to notice which feeling rings most true. You can also tap any emotion chip at the top to invite that one to speak up directly.

The cast

Powered by multiple agents β€” one per emotion (from Inside Out and Inside Out 2):

✨ Joy Β· πŸ’™ Sadness Β· 😨 Fear Β· πŸ”₯ Anger Β· 🀒 Disgust Β· 🧑 Anxiety Β· πŸ’š Envy Β· πŸ˜” Boredom Β· 😳 Embarrassment

For each message, an orchestrator agent decides which 2–4 emotions would naturally speak up, those emotion agents respond in parallel, and a final reflection agent helps you make sense of the mix. The emotion chips along the top double as buttons: tap one and that single emotion chimes in on the conversation so far.

Try saying…

Not sure where to start? These exercise different emotional mixes:

  • "I have a big exam tomorrow and I haven't studied enough."
  • "My best friend got the promotion I was hoping for and I don't know how to feel."
  • "I just sent an email to my whole team with an embarrassing typo in it."
  • "I moved to a new city and I feel really lonely here."
  • "I finally finished a project I've been working on for months!"
  • "Lately everything just feels gray and pointless."
  • "My roommate keeps leaving dirty dishes everywhere and I'm so done."
  • "I got into the program I applied for but now I'm terrified I'll fail."
  • "Is it normal to feel happy and sad at the same time?"
  • "I have talked about the issue with my wife a few time and we can't reach an agreement. i don't know what to do now."

Run it

pip install -r requirements.txt
python app.py            # open http://localhost:7860

Configuration is read from the environment, and a local .env file is loaded automatically if present (via python-dotenv):

# .env  (real shell environment variables take precedence)
HF_TOKEN=hf_...                 # enables model-generated replies
GOOGLE_CLIENT_ID=...            # optional, enables Google sign-in
GOOGLE_CLIENT_SECRET=...
GOOGLE_ALLOWED_DOMAIN=example.com   # optional, restrict to one Workspace domain
SESSION_SECRET=change-me
SHOW_LOGIN=true                 # optional, shows the login sidebar
  • HF_TOKEN lets the model (set by HF_MODEL in app.py, currently google/gemma-4-26B-A4B-it) generate the emotion responses. Without it the app still runs in a lightweight offline demo mode (keyword-based responses), so you can always see the experience. Pick a regular instruct model β€” a reasoning/"thinking" model returns its answer in a separate reasoning field and leaves content empty, which falls back to demo lines. On startup the app logs HF_TOKEN present: True/False (boolean only, never the value) so you can confirm the token reached the app β€” handy in Space logs.
  • Google sign-in is required when GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set; otherwise the app runs as an open local demo.

Hot reload (dev)

DEV=1 python app.py      # uvicorn watches the source and reloads on save

Local serving with llama.cpp

Set LOCAL_SERVING=true to run entirely on your own machine β€” the app then talks to a local llama.cpp server (OpenAI-compatible) instead of the hosted HF Inference API, and no HF_TOKEN is needed.

LOCAL_SERVING=true python app.py

On startup the app auto-discovers a local GGUF for HF_MODEL under ~/models (override with LOCAL_MODELS_DIR, or pin an exact file with LOCAL_MODEL_PATH) and launches llama-server for you β€” no separate terminal needed. It reuses an already-running server if one is up, and shuts its own down on exit. A 30B-A3B / 26B-A4B model at ~4-bit fits a 24 GB GPU.

Prefer to run the server yourself? Just start it first and the app will reuse it:

llama-server -m /path/to/model.gguf --jinja --reasoning-budget 0 \
             -ngl 99 -c 8192 --port 8088
  • Reasoning models: USE_REASONING defaults to false, which serves the model with --reasoning-budget 0 so it answers directly. Many models (Gemma 4, Nemotron, Qwen3…) otherwise default to a "thinking" mode that leaves content empty and falls back to demo lines. Set USE_REASONING=true to let the model think β€” the agent layer then strips the <think>…</think> chain-of-thought from replies (and uses larger token budgets so the answer is reached).
  • Override the endpoint with LOCAL_LLM_BASE_URL (default http://localhost:8088/v1), the llama.cpp binary with LLAMA_SERVER_BIN, and the reported model name with LOCAL_LLM_MODEL. The startup log shows serving=local-llama.cpp | reasoning=off so you can confirm the active backend.

How it works

File Purpose
app.py Gradio UI β€” theme/CSS, emotion chip-buttons, chat + chime callbacks, FastAPI mount and optional Google OAuth.
agents.py Orchestrator, per-emotion agents (run in parallel), and the closing reflection.
emotions.py Each emotion's display name, persona, color, and emoji.

The Gradio UI is mounted onto a FastAPI app via gr.mount_gradio_app, which is where the custom theme/CSS and the Google OAuth routes are wired in. Model calls go through Hugging Face's chat-completion API; recent conversation (up to the last 100 turns) is fed back to the agents as readable context.

A gentle note

This is a playful tool for self-reflection, not a substitute for professional mental-health support. If you're struggling, please reach out to someone you trust or a qualified professional.