# Project export: MindShift: AI for Bipolar Care

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2025
- Tagline: MindShift empowers those with bipolar disorder by tracking key biometric & conversational indicators, giving therapists and loved ones real-time insights to provide the most rapid cushion of support.
- Devpost: https://devpost.com/software/mindshift-wpy6re
- GitHub: https://github.com/vikram087/Treehacks25
- Video: https://www.youtube.com/embed/Y-ndH8Me5ZA?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 3 GitHub contributor(s) — Vikram Penumarti (15 commits), tone (13 commits), Michael-L-i-1 (10 commits)

## Devpost submission (written by the team)

### Inspiration

With the rise of smartwatches and an increasingly tech-savvy generation, physiological data tracking has gained significant attention. However, its application for bipolar patients—who could benefit the most—remains largely unexplored. MindShift aims to fill this critical gap by leveraging biometric data to enhance monitoring, early intervention, and personalized support.

### What it does

MindShift bridges the gap between bipolar patients and their therapists or support networks. Using biometric data from the Apple Watch, we monitor key physiological indicators like heart rate variability, sleep patterns, activity levels, and agitation—metrics that research has linked to extreme mood episodes. When significant shifts occur, MindShift detects them and initiates an adaptive conversation with the patient. Simultaneously, this data is synced to the Therapist Dashboard, providing real-time access to patient biometrics and behavioral assessments. The dashboard also generates AI-driven recommendations to guide patients back to stability and help therapists make informed decisions. By restoring social connection and emotional balance, MindShift strengthens the support system for those who need it most.

### How we built it

MindShift consists of two core components: the watch experience and the therapist interface. The watch experience utilizes the Terra API to collect real-time biometric data. Conversations with patients are facilitated using ElevenLabs and Gemini/Mistral AI for adaptive dialogue. Data is stored in ChromaDB and visualized in the React.JS therapist dashboard, which provides real-time alerts, detailed assessments, and AI-driven intervention suggestions in an intuitive interface.

### Challenges we ran into

We faced two major challenges: Integrating Terra API – Mapping real-time biometric data to meaningful mental health insights required custom data labeling and extensive testing. Deploying to a physical Apple Watch – Due to short-term Apple data policy restrictions, we had to simulate the full experience digitally rather than running it on a live device.

### Accomplishments we're proud of

We take immense pride in designing and implementing a fully connected backend and database infrastructure—a significant architectural challenge given the complexity of real-time data processing. Despite the constraints of a hackathon, we successfully built a robust system that combines biometric tracking, AI-powered dialogue, and therapist-facing insights.

### What we learned

Our team gained valuable experience in deploying edge AI solutions and navigating the challenges of integrating real-time physiological and behavioral data. Additionally, through extensive research on bipolar disorder, we deepened our understanding of how digital tools can complement traditional mental health care.

### What's next

for MindShift Moving forward, we aim to collaborate with bipolar patients and therapists to refine our system based on real-world needs. We’re also exploring additional behavioral and physiological indicators that could further enhance detection and intervention—potentially contributing to a deeper understanding of bipolar disorder as a whole.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 35 recognized source files, 146 KB.
- CSS (language) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Swift (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- Google Gemini (technology) — claimed on Devpost, not found in the code
- Mistral AI (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (61 of 61)

```
.gitignore
AppleWatch/.DS_Store
AppleWatch/.gitignore
AppleWatch/TreeHacks25App.xcodeproj/project.pbxproj
AppleWatch/TreeHacks25App.xcodeproj/project.xcworkspace/contents.xcworkspacedata
AppleWatch/TreeHacks25App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
AppleWatch/TreeHacks25App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
AppleWatch/TreeHacks25App.xcodeproj/project.xcworkspace/xcuserdata/ajapps.xcuserdatad/UserInterfaceState.xcuserstate
AppleWatch/TreeHacks25App.xcodeproj/project.xcworkspace/xcuserdata/michaelli.xcuserdatad/UserInterfaceState.xcuserstate
AppleWatch/TreeHacks25App.xcodeproj/xcuserdata/ajapps.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
AppleWatch/TreeHacks25App.xcodeproj/xcuserdata/ajapps.xcuserdatad/xcschemes/xcschememanagement.plist
AppleWatch/TreeHacks25App.xcodeproj/xcuserdata/michaelli.xcuserdatad/xcschemes/xcschememanagement.plist
AppleWatch/TreeHacks25AppTests/TreeHacks25AppTests.swift
AppleWatch/TreeHacks25AppUITests/TreeHacks25AppUITests.swift
AppleWatch/TreeHacks25AppUITests/TreeHacks25AppUITestsLaunchTests.swift
AppleWatch/WatchAppCompanion Watch App/Assets.xcassets/AccentColor.colorset/Contents.json
AppleWatch/WatchAppCompanion Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json
AppleWatch/WatchAppCompanion Watch App/Assets.xcassets/Contents.json
AppleWatch/WatchAppCompanion Watch App/BiomarkerMonitor.swift
AppleWatch/WatchAppCompanion Watch App/ContentView.swift
AppleWatch/WatchAppCompanion Watch App/LegacyBiomarkerMonitor.swift
AppleWatch/WatchAppCompanion Watch App/Preview Content/Preview Assets.xcassets/Contents.json
AppleWatch/WatchAppCompanion Watch App/WatchAppCompanion Watch App.entitlements
AppleWatch/WatchAppCompanion Watch App/WatchAppCompanionApp.swift
AppleWatch/WatchAppCompanion Watch AppTests/WatchAppCompanion_Watch_AppTests.swift
AppleWatch/WatchAppCompanion Watch AppUITests/WatchAppCompanion_Watch_AppUITests.swift
AppleWatch/WatchAppCompanion Watch AppUITests/WatchAppCompanion_Watch_AppUITestsLaunchTests.swift
AppleWatch/WatchAppCompanion-Watch-App-Info.plist
README.md
Server/.gitignore
Server/activity_metrics.json
Server/ai_analysis.py
Server/behavioral_assessment.json
Server/behavioral.py
Server/heart_rate.json
Server/README.md
Server/requirements.txt
Server/server.py
Server/sleep_metrics.json
Server/test.py
WebApp/README.md
WebApp/Treehacks25/.gitignore
WebApp/Treehacks25/index.html
WebApp/Treehacks25/package.json
WebApp/Treehacks25/postcss.config.js
WebApp/Treehacks25/README.md
WebApp/Treehacks25/src/assessment.jsx
WebApp/Treehacks25/src/components/BiometricGraph.jsx
WebApp/Treehacks25/src/components/ChatBot.jsx
WebApp/Treehacks25/src/components/Loader.jsx
WebApp/Treehacks25/src/components/NavBar.jsx
WebApp/Treehacks25/src/components/NavDropdown.jsx
WebApp/Treehacks25/src/components/PatientRecords.jsx
WebApp/Treehacks25/src/dashboard.jsx
WebApp/Treehacks25/src/homepage.jsx
WebApp/Treehacks25/src/index.css
WebApp/Treehacks25/src/main.jsx
WebApp/Treehacks25/src/patient-profile.jsx
WebApp/Treehacks25/src/routing.jsx
WebApp/Treehacks25/tailwind.config.js
WebApp/Treehacks25/vite.config.js
```

### Dependencies

- Server/requirements.txt: chromadb@==0.6.3, Flask@==3.1.0, Flask-Cors@==5.0.0, openai-whisper@==20240930, python-dotenv@==1.0.1, twilio@===9.4.5, zoomus@==1.2.1
- WebApp/Treehacks25/package.json: @types/react@^19.0.8, @types/react-dom@^19.0.3, @vitejs/plugin-react@^4.3.2, autoprefixer@^10.4.20, dompurify@^3.2.4, globals@^15.14.0, html-react-parser@^5.2.2, lucide-react@^0.475.0, postcss@^8.5.2, react@^19.0.0, react-chartjs-2@^5.3.0, react-dom@^19.0.0, react-router-dom@^7.1.5, tailwindcss@^3.4.17, vite@^6.1.0

### Recent commits (newest first)

- crisis
- Fixgit pull origin main
- Stable remove twilio.
- Merge branch 'main' of github.com:vikram087/Treehacks25
- dashes
- Initial question is now audio
- stable.lgtm.
- merging
- Add twillio support with biometric stream.
- fix syntax
- Add support for activity and sleep data in chromadb
- Add chromadb support to hrv, jerk post endpoint.
- Add flask support for biometric data post.
- Added SMS
- Merge remote changes while preserving AppleWatch updates
- Fix repo stuff lol mb
- server cxhanfes
- Small frontend tweaks
- ui changes
- Merge branch 'main' of github.com:vikram087/Treehacks25

## Key source files (fetched from GitHub, selected and truncated for size)

### Server/requirements.txt

```
Flask==3.1.0
Flask-Cors==5.0.0
chromadb==0.6.3
python-dotenv==1.0.1
zoomus==1.2.1
openai-whisper==20240930
twilio===9.4.5
```

### WebApp/Treehacks25/package.json

```
{
  "name": "treehacks25",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "dompurify": "^3.2.4",
    "html-react-parser": "^5.2.2",
    "lucide-react": "^0.475.0",
    "react": "^19.0.0",
    "react-chartjs-2": "^5.3.0",
    "react-dom": "^19.0.0",
    "react-router-dom": "^7.1.5"
  },
  "devDependencies": {
    "@types/react": "^19.0.8",
    "@types/react-dom": "^19.0.3",
    "@vitejs/plugin-react": "^4.3.2",
    "autoprefixer": "^10.4.20",
    "globals": "^15.14.0",
    "postcss": "^8.5.2",
    "tailwindcss": "^3.4.17",
    "vite": "^6.1.0"
  }
}

```

### Server/server.py

```python
import base64
import json
import os
import uuid
from datetime import datetime
from io import BytesIO
from typing import Optional

import chromadb
import google.generativeai as genai
import requests
import whisper
from dotenv import load_dotenv
from flask import Flask, Response, jsonify, request
from flask_cors import CORS
from twilio.rest import Client
from ai_analysis import generate_crisis_plan


whispr_model = whisper.load_model("base")

app = Flask(__name__)
CORS(app)

load_dotenv("./.env")

CHROMA_API_KEY = os.getenv("CHROMA_API_KEY")
CHROMA_TENANT = os.getenv("CHROMA_TENANT")
MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY")
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completion s"
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
ELEVENLABS_VOICE_ID = os.getenv(
    "ELEVENLABS_VOICE_ID", "21m00Tcm4TlvDq8ikWAM"
)  # default voice ID

TWILIO_SID = os.getenv("TWILIO_SID")
TWILIO_AUTH_TOKEN = os.getenv("TWILIO_AUTH_TOKEN")
TWILIO_PHONE_NUMBER = os.getenv("TWILIO_PHONE_NUMBER")
TWILIO_CLIENT = Client(TWILIO_SID, TWILIO_AUTH_TOKEN)

chroma_client = chromadb.HttpClient(
    ssl=True,
    host="api.trychroma.com",
    tenant=CHROMA_TENANT,
    database="Treehacks25",
    headers={"x-chroma-token": CHROMA_API_KEY},
)


@app.route("/api/health", methods=["GET"])
def health() -> tuple[Response, int]:
    return jsonify({"message": "Success"}), 200

# Generating the crisis plan and saving to ChromaDB
@app.route("/api/generate-crisis-plan", methods=["POST"])
def generate_crisis():
    try:
        data = request.get_json()
        if "biometric_data" not in data or "behavioral_summary" not in data:
            return jsonify({"error": "Missing biometric_data or behavioral_summary"}), 400


        biometric_data = data["biometric_data"]
        behavioral_summary = data["behavioral_summary"]

        # Generate Crisis Plan
        crisis_plan = generate_crisis_plan(biometric_data, behavioral_summary)

        # Ensure AI response is valid JSON
        if isinstance(crisis_plan, str):
            crisis_plan = crisis_plan.strip("```json").strip("```")
            try:
                crisis_plan = json.loads(crisis_plan)
            except json.JSONDecodeError:
                return jsonify({"error": "Invalid AI-generated JSON response"}), 500

        # Store in ChromaDB
        # collection = chroma_client.get_or_create_collection(name="patient_records")
        # document_id = f"crisis_plan_{biometric_data['userEmail']}_{datetime.now().isoformat()}"

        # collection.add(
        #     ids=[document_id],
        #     documents=[json.dumps(crisis_plan)],
        #     metadatas=[{"userEmail": biometric_data["userEmail"], "timestamp": datetime.now().isoformat()}],
        # )

        return jsonify({"success": True, "crisis_plan": crisis_plan}), 200

    except Exception as e:
        return jsonify({"error": str(e)}), 500

def transcribe(audio_file) -> str:
    try:
        # Save the file temporarily
        temp_filename = f"{uuid.uuid4()}.wav"
        audio_file.save(temp_filename)

        # Perform transcription
        result = whispr_model.transcribe(temp_filename)

        # Remove temporary file
        os.remove(temp_filename)

        return result["text"]

    except Exception as e:
        print(e)
        return ""


def get_qa_analysis(qa: list[dict]) -> Optional[str]:
    try:
        if len(qa) == 0:
            print("qa is length 0")
            return None

        conversation = ""
        for convo in qa:
            if not convo or not isinstance(convo, dict):
                continue

            question = convo.get("question", "")
            answer = convo.get("answer", "")
            conversation += f"Q: {question}\nA: {answer}\n"

        headers = {
            "Authorization": f"Bearer {MISTRAL_API_KEY}",
            "Content-Type": "application/json",
        }

        payload = {
            "model": "mistral-small-latest",
            "messages": [
                {
                    "role": "system",
                    "content": "You are a helpful medical assistant. Summarize the patient interview. Provide responses in HTML only without markdown or additional formatting.",
                },
                {
                    "role": "user",
                    "content": f"Here is a patient interview Q&A:\n{conversation}\n\nPlease summarize it clearly and concisely.\n\nPlease summarize it clearly and concisely in HTML.",
                },
            ],
            "temperature": 0.7,
            "max_tokens": 300,
            "top_p": 1,
            "frequency_penalty": 0,
            "presence_penalty": 0,
        }

        response = requests.post(MISTRAL_API_URL, headers=headers, json=payload)
        response_data = response.json()

        if "choices" in response_data and len(response_data["choices"]) > 0:
            summary = response_data["choices"][0]["message"]["content"]
            return summary.strip("```").replace("\n", "").strip("html")
        else:
            return None

    except Exception as e:
        print(e)
        return None


def create_or_upload_user(email: str, name: str) -> tuple[str, int]:
    try:
        if not email or not name:
            return "", 404

        docs = fetch_collection("patients")

        collection = chroma_client.get_or_create_collection(name="patients")

        for doc in docs:
            print("DOOOOOOC:::::::::", doc)
            print("  ")
            print("  ")
            print("  ")
            # if email == doc["document"]["email"] and name == doc["document"]["name"]:
            if email == doc["document"].get("email", "jodoe@gmail.com") and name == doc[
                "document"
            ].get("name", "John Doe"):
                return doc["id"], 200

        new_id = f"{uuid.uuid4()}"
        collection.add(
            ids=[new_id],
            documents=[json.dumps({"name": name, "email": email})],
        
[truncated — 21671 more characters]
```

### WebApp/Treehacks25/src/main.jsx

```javascript
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./routing";

createRoot(document.getElementById("root")).render(
	<StrictMode>
		<App />
	</StrictMode>,
);

```

### Server/behavioral.py

```python
import google.generativeai as genai
from dotenv import load_dotenv
import os

# Load environment variables
load_dotenv()

# Configure Gemini API
GEMINI_API_KEY = os.getenv('GEMINI_API_KEY')
genai.configure(api_key=GEMINI_API_KEY)

def adaptive_test():
    # ==============================================
    #  ALTER MODEL HERE
    # ==============================================
    model = genai.GenerativeModel('gemini-2.0-flash')

    # ==============================================
    # QUESTIONS AND PROMPTS
    # ==============================================

    topics_to_ask = """
    1. Mood and Emotions
    2. Eating and Diet
    3. Sleep and Fatigue
    4. Exercise and Fitness
    5. Relationships and Social Interaction
    """

    instructions = f"""
    You are an AI behavioral psychologist facilitating a structured yet natural conversation 
    with the user, who may have bipolar disorder. Your goal is to ask thoughtful questions 
    across key life areas while ensuring a smooth and engaging dialogue.

    ----- TOPICS -----
    {topics_to_ask}

    ----- DIRECTIONS -----
    
   1. **Introduction**  
       - If this is the start of the conversation (i.e., history is empty), introduce yourself 
         as an AI behavioral psychologist.  
       - Ask the user to describe their **current mood and emotions**.  

    2. **Discussion & Follow-Ups**  
       - Engage in a structured conversation covering each topic in the **TOPICS** section.  
       - For each theme, ask **at most two follow-up questions** to explore user responses further.  
       - Ensure follow-ups feel natural and human-like.  

    3. **Progressing Through Topics**  
       - Once enough information is gathered on a topic, transition to the next.  
       - Topics can be covered in any order based on conversation flow.  

    4. **Ending the Conversation**  
       - Once all topics have been covered, **thank the user** for their time.  
       - Do **not** ask any further questions after completing all topics.  
       - Explicitly mark the end of the conversation with: **[CONVERSATION ENDED]**  
    """
    
    # ==============================================
    # CONVERSATION
    # ==============================================
    
    chat_history = []
    user_input = ""
    while True:
        
        prompt = f"""

        ----- INSTRUCTIONS -----

        {instructions}

        ----- CURRENT CONVERSATION -----

        history: {chat_history}
        
        user: {user_input}

        ----- TASK -----

        Please response to the user according to the instructions and current conversation.
        Give a short question response to the user as your sole output. Remember, only ask
        up to 2 follow up questions per theme and end the conversation once all topics have been
        covered.
        """ 
        # Generate response
        response = model.generate_content(prompt)
        
        # Store the conversation
        chat_history.append({"role": "user", "text": user_input})
        chat_history.append({"role": "assistant", "text": response.text})

        print(chat_history)
        
        # Print the response
        if "[CONVERSATION ENDED]" in response.text:
            print("\nAssistant:", response.text.replace("[CONVERSATION ENDED]", ""))
            break
        else:
            print("\nAssistant:", response.text)

        # Get user input
        user_input = input("\nYou: ")

if __name__ == "__main__":
    adaptive_test() 
```

### Server/test.py

```python
import base64
import json
import os
import time

import requests
from dotenv import load_dotenv

load_dotenv("./.env")

MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY")
MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions"
API_URL = "http://localhost:8080"

# Test health route
response = requests.get(f"{API_URL}/api/health")
print("Health Check:", response.status_code, response.json())

NAME = "Jensen Huang"
EMAIL = "huang@dennys.com"
NUM_DOCS = 1
AUDIO_PATH = "./test_audio.wav"


def save_base64_audio(audio_base64: str, filename: str):
    """Decode base64-encoded audio and save to a local file."""
    audio_data = base64.b64decode(audio_base64)
    with open(filename, "wb") as f:
        f.write(audio_data)
    return filename


def respond(question):
    try:
        if not question:
            print("question is empty")
            return None

        headers = {
            "Authorization": f"Bearer {MISTRAL_API_KEY}",
            "Content-Type": "application/json",
        }

        payload = {
            "model": "mistral-small-latest",
            "messages": [
                {
                    "role": "system",
                    "content": "You are a person with bipolar disease, respond to questions from a mental health professional.",
                },
                {
                    "role": "user",
                    "content": f"Here is a professional interviewer asking a question: {question}, please respond to it. Keep your answers as brief as possible.",
                },
            ],
            "temperature": 0.7,
            "max_tokens": 300,
            "top_p": 1,
            "frequency_penalty": 0,
            "presence_penalty": 0,
        }

        response = requests.post(MISTRAL_API_URL, headers=headers, json=payload)
        response_data = response.json()

        if "choices" in response_data and len(response_data["choices"]) > 0:
            summary = response_data["choices"][0]["message"]["content"]
            return summary
        else:
            return None

    except Exception as e:
        print(e)
        return None


data = {
    "num": "0",
    "history": "[]",
    "question": "",
    "question_text": "Hello, I'm an AI behavioral psychologist. To start, could you describe your current mood and emotions?",
    "end": "false",
    "metadata": json.dumps({"name": NAME, "email": EMAIL}),
}

for i in range(NUM_DOCS):
    while True:
        with open(AUDIO_PATH, "rb") as audio_file:
            try:
                files = {"answer_audio": audio_file.read()}

                response = requests.post(
                    f"{API_URL}/assessment",
                    data=data,
                    files=files,
                )
                res = response.json()
                print("SERVER RESPONSE:", res, "\n\n")

                # local_file = save_base64_audio(
                #     res["question"], "./test_audio_output.wav"
                # )

                data = {
                    "num": str(res["num"]),
                    "history": json.dumps(res["history"]),
                    "question": res["question"],
                    "question_text": res["question_text"],
                    "end": str(res["end"]).lower(),
                    "metadata": json.dumps(res["metadata"]),
                }
                num = res["num"]
            except Exception as e:
                print("Response exception:", e)
                time.sleep(3)
                continue

            if "[CONVERSATION ENDED]" in res["question_text"] or num >= 2:
                print("END IS TRUE", "\n\n")
                data["end"] = "true"
                response = requests.post(
                    f"{API_URL}/assessment",
                    data=data,
                    files=files,
                )
                print("FINAL RESPONSE:", response.json(), "\n\n")
                break

            answer = respond(res["question_text"])

```

### Server/ai_analysis.py

```python
import os
import requests
import json
import chromadb
import re  # Added to clean AI response
from datetime import datetime
from dotenv import load_dotenv

# Load environment variables
load_dotenv("./.env")

# Set Mistral AI API credentials
MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY")
MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions"

# ChromaDB Configuration
CHROMA_API_KEY = os.getenv("CHROMA_API_KEY")
CHROMA_TENANT = os.getenv("CHROMA_TENANT")

# Validate API keys
if not MISTRAL_API_KEY:
    raise ValueError("MISTRAL_API_KEY is missing from .env")
if not CHROMA_API_KEY:
    raise ValueError("CHROMA_API_KEY is missing from .env")

try:
    chroma_client = chromadb.HttpClient(
        ssl=True,
        host="api.trychroma.com",
        tenant=CHROMA_TENANT,
        database="Treehacks25",
        headers={"x-chroma-token": CHROMA_API_KEY},
    )
except Exception as e:
    print("Error initializing ChromaDB:", e)

# Function to generate a crisis plan using Mistral AI
def generate_crisis_plan(biometric_data, behavioral_summary):
    """
    Uses Mistral AI to generate a structured AI-driven crisis plan.

    :param biometric_data: Dictionary containing Apple Watch health data.
    :param behavioral_summary: AI-generated summary of the patient's mental state.
    :return: AI-generated recommendations in JSON format.
    """

    headers = {
        "Authorization": f"Bearer {MISTRAL_API_KEY}",
        "Content-Type": "application/json",
    }

    prompt = f"""
You are an AI-powered mental health assistant helping therapists assess bipolar patients.
Based on the provided biometric data (Apple Watch) and behavioral assessment summary, generate 
a **detailed** personalized crisis plan. The recommendations must be **specific, quantifiable, and actionable**.

--- Patient Biometric Data ---
{json.dumps(biometric_data, indent=2)}

--- Behavioral Assessment Summary ---
{behavioral_summary}

--- Task ---
1. **Current State Analysis**: 
   - Determine if the patient is experiencing **Mania, Hypomania, Depression, Mixed Episode, or Rapid Cycling** based on provided data.
   - Assign a **confidence level (percentage)** to this classification. 
   - If uncertain, specify what additional data would be needed for better accuracy.

2. **AI-Generated Crisis Plan**: Provide structured, detailed, and specific recommendations tailored to the patient’s current state.
   - **Physical Activity**: If increased activity is recommended, specify **duration, frequency, and type** (e.g., "Engage in 30-45 minutes of moderate exercise, such as walking or swimming, at least 4 times per week").
   - **Sleep Adjustments**: If a structured sleep routine is suggested, define **specific changes** (e.g., "Reduce bedtime by 1 hour", "Increase total sleep time by 2 hours", "Establish a consistent bedtime of 10 PM").
   - **Social Engagement**:
     - If mild symptoms, recommend **specific interactions** (e.g., "Attend a social gathering once per week" or "Call a close friend twice a week").
     - If symptoms are **concerning**, recommend scheduling **more frequent therapy sessions** (e.g., "Schedule an emergency therapy session within 48 hours").
     - If symptoms are **severe**, notify the emergency contact (e.g., "Ask emergency contact to check in on the patient daily").
   - **Medication Review**:
     - If symptoms persist despite medication, recommend **checking for side effects** (e.g., "Patient may be experiencing side effects from lithium; consider dosage review").
     - If non-compliance is detected, **suggest steps** (e.g., "Patient has skipped doses in the past week. Consider medication adherence counseling").
   - **Risk Alerts**:
     - If **agitation levels** are high, suggest grounding techniques and **reducing stimulation** (e.g., "Reduce screen time before bed, practice mindfulness for 15 minutes").
     - If **sleep deprivation is severe**, recommend **urgent intervention** (e.g., "Significant sleep loss detected for 3 consecutive days—consult psychiatrist within 24 hours").
     - If **suicidal ideation or high-risk behavior is detected**, **immediate action required** (e.g., "Notify emergency contact and activate crisis protocol").

3. **Intervention Suggestions**: 
   - Provide **specific therapist actions** to stabilize the patient.
   - List **monitoring strategies** (e.g., "Track mood daily in app", "Increase Apple Watch check-ins to every 2 hours").
   - Suggest structured **coping mechanisms** based on current symptoms (e.g., "If experiencing racing thoughts, use guided breathing exercises for 10 minutes").

4. **Urgency Level**: 
   - **Low**: No immediate action required; mild fluctuations in mood.
   - **Moderate**: Symptoms present but manageable with lifestyle adjustments.
   - **High**: Patient requires **immediate therapist intervention**; high risk of escalation.
   - **Immediate / Suicidal**: **Activate emergency response**; patient is in critical danger and requires immediate support.

Respond in a **structured JSON format** without additional explanations.
    """

    payload = {
        "model": "mistral-small-latest",
        "messages": [
            {"role": "system", "content": "You are a helpful AI therapist assistant."},
            {"role": "user", "content": prompt},
        ],
        "temperature": 0.7,
        "max_tokens": 500,
        "top_p": 1,
        "frequency_penalty": 0,
        "presence_penalty": 0,
    }

    try:
        response = requests.post(MISTRAL_API_URL, headers=headers, json=payload)
        response_data = response.json()

        print("Full API Response:", response_data)  # Debugging print

        if "choices" in response_data and response_data["choices"]:
            ai_output = response_data["choices"][0]["message"]["content"]

            # **Fix: Clean AI response**
            ai_output = re.sub(r"```json\n|\n```", "", ai_output)

            try:
                return json.loads(ai_output)  # Ensure valid JSON
            except 
[truncated — 1426 more characters]
```

### WebApp/Treehacks25/postcss.config.js

```javascript
export default {
	plugins: {
		tailwindcss: {},
		autoprefixer: {},
	},
};

```

### WebApp/Treehacks25/vite.config.js

```javascript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
	plugins: [react()],
});

```

### WebApp/Treehacks25/tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
export default {
	content: ["./src/**/*.{js,jsx,ts,tsx}"],
	theme: {
		extend: {},
	},
	plugins: [],
};

```

[22 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]