--- 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](https://x.com/QuicklyLearnIt/status/2066334265336570107?s=20) 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 ```bash 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`): ```bash # .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) ```bash 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](https://github.com/ggml-org/llama.cpp) server (OpenAI-compatible) instead of the hosted HF Inference API, and **no `HF_TOKEN` is needed**. ```bash 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: ```bash 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 `…` 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.