Spaces:
Sleeping
Sleeping
init
Browse files- README.md +225 -4
- app.py +463 -0
- requirements.txt +4 -0
README.md
CHANGED
|
@@ -1,14 +1,235 @@
|
|
| 1 |
---
|
| 2 |
title: PomoCat
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: red
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 5.33.1
|
| 8 |
app_file: app.py
|
| 9 |
-
pinned:
|
| 10 |
license: apache-2.0
|
| 11 |
-
short_description:
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: PomoCat
|
| 3 |
+
emoji: π±
|
| 4 |
colorFrom: red
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 5.33.1
|
| 8 |
app_file: app.py
|
| 9 |
+
pinned: yes
|
| 10 |
license: apache-2.0
|
| 11 |
+
short_description: AI-powered Pomodoro assistant that makes focus fun and engaging
|
| 12 |
---
|
| 13 |
|
| 14 |
+
# π± PomoCat β Your AI Focus Buddy with a Paw-sitive Vibe
|
| 15 |
+
|
| 16 |
+
**PomoCat** is an intelligent Pomodoro technique assistant built with Gradio and MCP (Model Context Protocol). It combines traditional 25-minute focused work sessions with AI-driven personalized encouragement to help you build healthy work rhythms.
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
## β¨ Key Features
|
| 21 |
+
|
| 22 |
+
### π― Core Pomodoro Functionality
|
| 23 |
+
- **Smart Work Session Management**: 25-minute focused work timer
|
| 24 |
+
- **Enforced Break Protection**: Must work at least 20 minutes before breaks are allowed
|
| 25 |
+
- **Session State Tracking**: Real-time tracking of work time, break status, and progress statistics
|
| 26 |
+
- **Multi-Session Support**: Pause, resume, and reset session capabilities
|
| 27 |
+
|
| 28 |
+
### π€ AI-Driven Personalized Encouragement
|
| 29 |
+
- **Claude API Integration**: Uses Anthropic Claude API for intelligent encouragement
|
| 30 |
+
- **Context-Aware Responses**: Provides targeted support based on user input emotions and needs
|
| 31 |
+
- **Smart Fallback**: Automatically switches to keyword-based responses when API is unavailable
|
| 32 |
+
- **Multi-Scenario Support**: Handles stress, fatigue, challenges, procrastination, and other work states
|
| 33 |
+
|
| 34 |
+
### π§ Technical Features
|
| 35 |
+
- **MCP Compatible**: Supports Model Context Protocol for AI workflow integration
|
| 36 |
+
- **Web Interface**: Modern Gradio-based user interface
|
| 37 |
+
- **RESTful API**: Complete API endpoints for external application integration
|
| 38 |
+
- **State Persistence**: Session state management and progress tracking
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## π Quick Start
|
| 43 |
+
|
| 44 |
+
### Basic Commands
|
| 45 |
+
|
| 46 |
+
| User Input | Function |
|
| 47 |
+
|------------|----------|
|
| 48 |
+
| `"start working"` / `"start pomodoro"` | Start 25-minute focused work timer |
|
| 49 |
+
| `"take a break"` / `"rest"` | Start break mode (requires 20+ minutes of work) |
|
| 50 |
+
| `"resume work"` / `"back to work"` | End break and resume working |
|
| 51 |
+
| `"stop"` / `"end session"` | Completely end current session |
|
| 52 |
+
| `"status"` / `"check progress"` | View current work progress and statistics |
|
| 53 |
+
| `"help"` / `"commands"` | Show all available commands |
|
| 54 |
+
| Any other text | Get AI personalized encouragement and support |
|
| 55 |
+
|
| 56 |
+
### Usage Examples
|
| 57 |
+
|
| 58 |
+
```bash
|
| 59 |
+
# Start PomoCat
|
| 60 |
+
python app.py
|
| 61 |
+
|
| 62 |
+
# Access web interface
|
| 63 |
+
http://localhost:7860
|
| 64 |
+
|
| 65 |
+
# Start work session
|
| 66 |
+
"start working" β πΊ Focus timer started! Focus time: 25 minutes...
|
| 67 |
+
|
| 68 |
+
# Try to break too early
|
| 69 |
+
"take a break" β πΎ You need to work at least 20 minutes before taking a break!
|
| 70 |
+
|
| 71 |
+
# Successful break
|
| 72 |
+
(After 20 minutes of work) "take a break" β π» Perfect! You've focused for 20 minutes!
|
| 73 |
+
|
| 74 |
+
# Seek encouragement
|
| 75 |
+
"I'm feeling overwhelmed" β πΈ I can sense you're feeling a bit overwhelmed, but remember...
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
## π§ Installation & Configuration
|
| 80 |
+
|
| 81 |
+
### Requirements
|
| 82 |
+
- Python 3.8+
|
| 83 |
+
- Gradio 5.32.1+
|
| 84 |
+
- Optional: Anthropic API key (for AI features)
|
| 85 |
+
|
| 86 |
+
### Installation Steps
|
| 87 |
+
|
| 88 |
+
```bash
|
| 89 |
+
# Clone the project
|
| 90 |
+
git clone <repository-url>
|
| 91 |
+
cd PomoCat
|
| 92 |
+
|
| 93 |
+
# Install dependencies
|
| 94 |
+
pip install -r requirements.txt
|
| 95 |
+
|
| 96 |
+
# Set up AI functionality (optional)
|
| 97 |
+
export ANTHROPIC_API_KEY="your-api-key-here"
|
| 98 |
+
|
| 99 |
+
# Start the application
|
| 100 |
+
python app.py
|
| 101 |
+
```
|
| 102 |
+
|
| 103 |
+
### Configuration Options
|
| 104 |
+
|
| 105 |
+
```bash
|
| 106 |
+
# Custom port and host
|
| 107 |
+
python app.py --port 8080 --host 127.0.0.1
|
| 108 |
+
|
| 109 |
+
# View all options
|
| 110 |
+
python app.py --help
|
| 111 |
+
```
|
| 112 |
+
|
| 113 |
+
---
|
| 114 |
+
|
| 115 |
+
## π Deployment & Integration
|
| 116 |
+
|
| 117 |
+
### Hugging Face Spaces Deployment
|
| 118 |
+
Project is configured for Hugging Face Spaces compatibility:
|
| 119 |
+
- Automatic detection and deployment to HF Spaces
|
| 120 |
+
- Support for gradio[mcp] extension
|
| 121 |
+
- Zero-configuration deployment
|
| 122 |
+
|
| 123 |
+
### MCP Protocol Integration
|
| 124 |
+
Integrate as MCP tool into AI workflows:
|
| 125 |
+
|
| 126 |
+
```python
|
| 127 |
+
# MCP context request example
|
| 128 |
+
{
|
| 129 |
+
"task_id": "pomo-session-123",
|
| 130 |
+
"input": {
|
| 131 |
+
"user_query": "I want to take a break",
|
| 132 |
+
"history": [
|
| 133 |
+
{"role": "user", "content": "start working"},
|
| 134 |
+
{"role": "tool", "content": "Timer started! Focus for 25 minutes!"}
|
| 135 |
+
]
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
# MCP response example
|
| 140 |
+
{
|
| 141 |
+
"context": [
|
| 142 |
+
{
|
| 143 |
+
"type": "text",
|
| 144 |
+
"name": "break_mode",
|
| 145 |
+
"content": "πΊπΊπΊ Take a deep breath. Your break time has started!"
|
| 146 |
+
}
|
| 147 |
+
]
|
| 148 |
+
}
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
### API Integration
|
| 152 |
+
RESTful endpoints can be directly integrated into other applications:
|
| 153 |
+
|
| 154 |
+
```python
|
| 155 |
+
import requests
|
| 156 |
+
|
| 157 |
+
# Start work session
|
| 158 |
+
response = requests.post("/api/pomodoro",
|
| 159 |
+
json={"query": "start working"})
|
| 160 |
+
|
| 161 |
+
# Check status
|
| 162 |
+
status = requests.get("/api/status")
|
| 163 |
+
```
|
| 164 |
+
|
| 165 |
+
---
|
| 166 |
+
|
| 167 |
+
## π¨ User Interface
|
| 168 |
+
|
| 169 |
+
### Web Interface Features
|
| 170 |
+
- **Modern Design**: Clean and intuitive Gradio interface
|
| 171 |
+
- **Real-time Feedback**: Instant display of session status and AI responses
|
| 172 |
+
- **Example Interactions**: Preset common commands for quick start
|
| 173 |
+
- **Responsive Layout**: Adapts to desktop and mobile devices
|
| 174 |
+
|
| 175 |
+
### Interface Components
|
| 176 |
+
- Text Input Box: Natural language command input
|
| 177 |
+
- Quick Buttons: Status check, session reset, help
|
| 178 |
+
- Response Area: Multi-line text display for AI responses
|
| 179 |
+
- Example Area: Quick selection of common commands
|
| 180 |
+
|
| 181 |
+
---
|
| 182 |
+
|
| 183 |
+
## π§ AI Intelligence Features
|
| 184 |
+
|
| 185 |
+
### Context-Aware Responses
|
| 186 |
+
PomoCat can recognize and respond to various work contexts:
|
| 187 |
+
|
| 188 |
+
| Context Type | Keyword Examples | AI Response Characteristics |
|
| 189 |
+
|--------------|------------------|----------------------------|
|
| 190 |
+
| Stress/Anxiety | "stress", "overwhelm", "anxious" | Provide calming advice and breakdown strategies |
|
| 191 |
+
| Fatigue | "tired", "exhausted", "drained" | Suggest appropriate rest and recovery |
|
| 192 |
+
| Challenges | "difficult", "hard", "challenging" | Encourage persistence and provide solution ideas |
|
| 193 |
+
| Lack of Motivation | "motivation", "inspire", "encourage" | Positive encouragement and confidence building |
|
| 194 |
+
| Procrastination | "procrastinate", "delay", "avoid" | Provide practical advice for small starts |
|
| 195 |
+
|
| 196 |
+
### Smart Fallback Mechanism
|
| 197 |
+
- **Primary Mode**: Claude API provides deep personalized responses
|
| 198 |
+
- **Fallback Mode**: Intelligent keyword-based matching responses
|
| 199 |
+
- **Seamless Switching**: Automatic fallback when API unavailable, ensuring service continuity
|
| 200 |
+
|
| 201 |
+
---
|
| 202 |
+
|
| 203 |
+
## π Usage Statistics & Analytics
|
| 204 |
+
|
| 205 |
+
### Session Tracking
|
| 206 |
+
- Work session count
|
| 207 |
+
- Accumulated work time statistics
|
| 208 |
+
- Average session length analysis
|
| 209 |
+
- Break frequency monitoring
|
| 210 |
+
|
| 211 |
+
### Progress Visualization
|
| 212 |
+
- Real-time work time display
|
| 213 |
+
- Session completion indicators
|
| 214 |
+
- Historical statistics overview
|
| 215 |
+
- Work efficiency trends
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
## π License
|
| 220 |
+
|
| 221 |
+
This project is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) file for details.
|
| 222 |
+
|
| 223 |
+
---
|
| 224 |
+
|
| 225 |
+
## π Acknowledgments
|
| 226 |
+
|
| 227 |
+
- Gradio team for excellent web interface framework
|
| 228 |
+
- Anthropic for powerful Claude AI API
|
| 229 |
+
- Francesco Cirillo, inventor of the Pomodoro Technique
|
| 230 |
+
- All contributors and users for their support
|
| 231 |
+
|
| 232 |
+
---
|
| 233 |
+
|
| 234 |
+
*π± Let PomoCat accompany every focused work session! πΎ*
|
| 235 |
+
|
app.py
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
PomoCat - Your focus buddy with a paw-sitive vibe
|
| 4 |
+
A Gradio-powered MCP server for managing pomodoro sessions with AI encouragement
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import gradio as gr
|
| 8 |
+
import os
|
| 9 |
+
import argparse
|
| 10 |
+
from datetime import datetime, timedelta
|
| 11 |
+
from typing import Dict, Any, List, Optional
|
| 12 |
+
import json
|
| 13 |
+
from dataclasses import dataclass
|
| 14 |
+
|
| 15 |
+
# LLM API imports
|
| 16 |
+
try:
|
| 17 |
+
from anthropic import Anthropic
|
| 18 |
+
ANTHROPIC_AVAILABLE = True
|
| 19 |
+
except ImportError:
|
| 20 |
+
ANTHROPIC_AVAILABLE = False
|
| 21 |
+
print("β οΈ Anthropic library not available. AI encouragement will use fallback responses.")
|
| 22 |
+
|
| 23 |
+
@dataclass
|
| 24 |
+
class PomoCatState:
|
| 25 |
+
"""State management for PomoCat sessions"""
|
| 26 |
+
is_working: bool = False
|
| 27 |
+
is_on_break: bool = False
|
| 28 |
+
current_session_start: Optional[datetime] = None
|
| 29 |
+
total_work_time: int = 0 # in minutes
|
| 30 |
+
session_count: int = 0
|
| 31 |
+
last_break_time: Optional[datetime] = None
|
| 32 |
+
work_start_time: Optional[datetime] = None
|
| 33 |
+
|
| 34 |
+
def to_dict(self) -> Dict[str, Any]:
|
| 35 |
+
"""Convert state to dictionary for JSON serialization"""
|
| 36 |
+
return {
|
| 37 |
+
"is_working": self.is_working,
|
| 38 |
+
"is_on_break": self.is_on_break,
|
| 39 |
+
"current_session_start": self.current_session_start.isoformat() if self.current_session_start else None,
|
| 40 |
+
"total_work_time": self.total_work_time,
|
| 41 |
+
"session_count": self.session_count,
|
| 42 |
+
"last_break_time": self.last_break_time.isoformat() if self.last_break_time else None,
|
| 43 |
+
"work_start_time": self.work_start_time.isoformat() if self.work_start_time else None
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
# Global state instance
|
| 47 |
+
pomocat_state = PomoCatState()
|
| 48 |
+
|
| 49 |
+
def pomodoro_manager(user_query: str) -> str:
|
| 50 |
+
"""
|
| 51 |
+
Manage pomodoro work sessions and provide AI encouragement.
|
| 52 |
+
|
| 53 |
+
This function handles all pomodoro-related commands including starting work sessions,
|
| 54 |
+
taking breaks, checking status, and providing AI-powered motivational support.
|
| 55 |
+
It enforces a minimum 20-minute work requirement before allowing breaks.
|
| 56 |
+
|
| 57 |
+
Args:
|
| 58 |
+
user_query (str): User command or message. Commands include:
|
| 59 |
+
- "start working" / "start pomodoro" - Begin a 25-minute focus session
|
| 60 |
+
- "take a break" / "rest" - Take a break (requires 20+ minutes of work)
|
| 61 |
+
- "resume work" / "back to work" - End break and resume working
|
| 62 |
+
- "stop" / "end session" - End current session completely
|
| 63 |
+
- "status" / "check progress" - Get current session status
|
| 64 |
+
- "help" / "commands" - Show available commands
|
| 65 |
+
- Any other text - Get AI encouragement and motivation
|
| 66 |
+
|
| 67 |
+
Returns:
|
| 68 |
+
str: Response message with session status, encouragement, or command results
|
| 69 |
+
"""
|
| 70 |
+
global pomocat_state
|
| 71 |
+
|
| 72 |
+
query = user_query.lower().strip()
|
| 73 |
+
|
| 74 |
+
# Handle different commands
|
| 75 |
+
if any(keyword in query for keyword in ["start work", "start pomodoro", "begin work", "start focus"]):
|
| 76 |
+
return start_work_session()
|
| 77 |
+
|
| 78 |
+
elif any(keyword in query for keyword in ["take a break", "start break", "break time", "rest"]):
|
| 79 |
+
return start_break_mode()
|
| 80 |
+
|
| 81 |
+
elif any(keyword in query for keyword in ["resume work", "back to work", "end break", "continue work"]):
|
| 82 |
+
return resume_work()
|
| 83 |
+
|
| 84 |
+
elif any(keyword in query for keyword in ["stop", "end session", "quit", "finish"]):
|
| 85 |
+
return stop_session()
|
| 86 |
+
|
| 87 |
+
elif any(keyword in query for keyword in ["status", "check progress", "how am i doing", "progress"]):
|
| 88 |
+
return get_session_status()
|
| 89 |
+
|
| 90 |
+
elif any(keyword in query for keyword in ["help", "commands", "what can you do"]):
|
| 91 |
+
return get_help_text()
|
| 92 |
+
|
| 93 |
+
else:
|
| 94 |
+
# AI encouragement for any other input
|
| 95 |
+
return provide_ai_encouragement(user_query)
|
| 96 |
+
|
| 97 |
+
def get_session_status() -> str:
|
| 98 |
+
"""
|
| 99 |
+
Get current pomodoro session status and detailed progress statistics.
|
| 100 |
+
|
| 101 |
+
This function provides comprehensive information about the current session including:
|
| 102 |
+
work time elapsed, break status, total accumulated work time, and current activity.
|
| 103 |
+
|
| 104 |
+
Returns:
|
| 105 |
+
str: Detailed session status including work time, break duration, and progress info
|
| 106 |
+
"""
|
| 107 |
+
global pomocat_state
|
| 108 |
+
|
| 109 |
+
if not pomocat_state.is_working and not pomocat_state.is_on_break:
|
| 110 |
+
return "πΈ No active session. Ready to start working? Use 'start working' to begin! πΎ"
|
| 111 |
+
|
| 112 |
+
current_work_time = calculate_work_time() if pomocat_state.is_working else 0
|
| 113 |
+
total_time = pomocat_state.total_work_time + current_work_time
|
| 114 |
+
|
| 115 |
+
if pomocat_state.is_working:
|
| 116 |
+
return f"πΊ Currently working! \nπΎ Current session: {current_work_time} minutes \nβ° Total work time: {total_time} minutes \nπͺ Keep up the great focus! You're doing fantastic! β¨"
|
| 117 |
+
elif pomocat_state.is_on_break:
|
| 118 |
+
break_duration = (datetime.now() - pomocat_state.last_break_time).seconds // 60 if pomocat_state.last_break_time else 0
|
| 119 |
+
return f"πΊοΏ½οΏ½πΊ Currently on break! \nπΎ Break duration: {break_duration} minutes \nβ° Total work time: {total_time} minutes \nπΈ Enjoy your rest! Use 'resume work' when ready to continue! π"
|
| 120 |
+
|
| 121 |
+
def reset_session() -> str:
|
| 122 |
+
"""
|
| 123 |
+
Reset the current pomodoro session completely and clear all progress.
|
| 124 |
+
|
| 125 |
+
This function resets all session data including work time, break status,
|
| 126 |
+
timers, and accumulated statistics. Use this to start completely fresh.
|
| 127 |
+
|
| 128 |
+
Returns:
|
| 129 |
+
str: Confirmation message that the session has been successfully reset
|
| 130 |
+
"""
|
| 131 |
+
global pomocat_state
|
| 132 |
+
pomocat_state = PomoCatState()
|
| 133 |
+
return "πΊ Session reset! All timers and progress cleared. Ready for a fresh start? πΎβ¨"
|
| 134 |
+
|
| 135 |
+
def start_work_session() -> str:
|
| 136 |
+
"""Start a new work session"""
|
| 137 |
+
global pomocat_state
|
| 138 |
+
|
| 139 |
+
if pomocat_state.is_working:
|
| 140 |
+
elapsed = calculate_work_time()
|
| 141 |
+
return f"πΊ You're already working! Keep it up! Current session: {elapsed} minutes"
|
| 142 |
+
|
| 143 |
+
pomocat_state.is_working = True
|
| 144 |
+
pomocat_state.is_on_break = False
|
| 145 |
+
pomocat_state.current_session_start = datetime.now()
|
| 146 |
+
pomocat_state.work_start_time = datetime.now()
|
| 147 |
+
|
| 148 |
+
return "πΊ Awesome! Pomodoro timer started! Focus time: 25 minutes... \nπΎ *purrs encouragingly* You've got this! Stay focused and let's make some progress together! πͺβ¨"
|
| 149 |
+
|
| 150 |
+
def start_break_mode() -> str:
|
| 151 |
+
"""Start break mode with time validation"""
|
| 152 |
+
global pomocat_state
|
| 153 |
+
|
| 154 |
+
if not pomocat_state.is_working:
|
| 155 |
+
return "πΈ You're not currently working! Use 'start working' to begin a pomodoro session first. πΎ"
|
| 156 |
+
|
| 157 |
+
# Calculate elapsed work time
|
| 158 |
+
elapsed_minutes = calculate_work_time()
|
| 159 |
+
|
| 160 |
+
if elapsed_minutes < 20:
|
| 161 |
+
remaining = 20 - elapsed_minutes
|
| 162 |
+
return f"πΎ Meow! You need to work at least 20 minutes before taking a break! You've worked for {elapsed_minutes} minutes, keep going for {remaining} more minutes! πͺ \nπ± *encouraging purr* You're doing great - just a little bit more focus time! π"
|
| 163 |
+
|
| 164 |
+
# Allow break
|
| 165 |
+
pomocat_state.is_on_break = True
|
| 166 |
+
pomocat_state.is_working = False
|
| 167 |
+
pomocat_state.last_break_time = datetime.now()
|
| 168 |
+
|
| 169 |
+
if elapsed_minutes >= 25:
|
| 170 |
+
return f"π» Perfect! You've completed {elapsed_minutes} minutes of focused work! Time for a well-deserved break! π \nπΊπΊπΊ *stretches paws* Enjoy your break! You've earned it! πΎβ¨"
|
| 171 |
+
else:
|
| 172 |
+
return f"πΈ Good job! You've worked for {elapsed_minutes} minutes. While you haven't completed the full 25-minute session, you've earned a break! \nπΊπΊπΊ *gentle purr* Take a moment to rest, then we can tackle more work together! π"
|
| 173 |
+
|
| 174 |
+
def resume_work() -> str:
|
| 175 |
+
"""Resume work session"""
|
| 176 |
+
global pomocat_state
|
| 177 |
+
|
| 178 |
+
if not pomocat_state.is_on_break:
|
| 179 |
+
if pomocat_state.is_working:
|
| 180 |
+
return "πΊ You're already working! Keep up the great focus! πΎ"
|
| 181 |
+
else:
|
| 182 |
+
return "πΈ You're not on a break. Use 'start working' to begin a new pomodoro session! πΎ"
|
| 183 |
+
|
| 184 |
+
pomocat_state.is_working = True
|
| 185 |
+
pomocat_state.is_on_break = False
|
| 186 |
+
pomocat_state.work_start_time = datetime.now() # Reset work start time for new session
|
| 187 |
+
|
| 188 |
+
return "π» Welcome back! Focus mode resumed. Let's tackle this together! π \nπΎ *determined purr* Time to get back into the flow! You're doing amazing! πͺβ¨"
|
| 189 |
+
|
| 190 |
+
def stop_session() -> str:
|
| 191 |
+
"""Stop the current session"""
|
| 192 |
+
global pomocat_state
|
| 193 |
+
|
| 194 |
+
if not pomocat_state.is_working and not pomocat_state.is_on_break:
|
| 195 |
+
return "πΈ No active session to stop. You're all set! πΎ"
|
| 196 |
+
|
| 197 |
+
elapsed = calculate_work_time() if pomocat_state.is_working else 0
|
| 198 |
+
total_time = pomocat_state.total_work_time + elapsed
|
| 199 |
+
|
| 200 |
+
# Reset state
|
| 201 |
+
pomocat_state = PomoCatState()
|
| 202 |
+
|
| 203 |
+
return f"πΊ Session ended! Great work today! \nπΎ Total focused time: {total_time} minutes. You should be proud of your effort! π \nπ» *content purr* Take care and see you next time! π"
|
| 204 |
+
|
| 205 |
+
def provide_ai_encouragement(user_input: str) -> str:
|
| 206 |
+
"""
|
| 207 |
+
Provide AI-powered encouragement based on user input using Claude API.
|
| 208 |
+
|
| 209 |
+
Analyzes the user's message and provides personalized, cat-themed
|
| 210 |
+
motivational responses to help with focus and productivity.
|
| 211 |
+
|
| 212 |
+
Args:
|
| 213 |
+
user_input: The user's message or question about motivation, challenges, or feelings
|
| 214 |
+
|
| 215 |
+
Returns:
|
| 216 |
+
Encouraging cat-themed response tailored to the user's emotional state
|
| 217 |
+
"""
|
| 218 |
+
|
| 219 |
+
# Get current session context for more personalized responses
|
| 220 |
+
global pomocat_state
|
| 221 |
+
current_work_time = calculate_work_time() if pomocat_state.is_working else 0
|
| 222 |
+
total_time = pomocat_state.total_work_time + current_work_time
|
| 223 |
+
|
| 224 |
+
session_context = ""
|
| 225 |
+
if pomocat_state.is_working:
|
| 226 |
+
session_context = f"The user is currently in a work session ({current_work_time} minutes so far, {total_time} total minutes today)."
|
| 227 |
+
elif pomocat_state.is_on_break:
|
| 228 |
+
session_context = f"The user is currently on a break (total work time today: {total_time} minutes)."
|
| 229 |
+
else:
|
| 230 |
+
session_context = f"The user has no active session (total work time today: {total_time} minutes)."
|
| 231 |
+
|
| 232 |
+
# Try to use Claude API if available
|
| 233 |
+
api_key = os.getenv('ANTHROPIC_API_KEY')
|
| 234 |
+
if ANTHROPIC_AVAILABLE and api_key:
|
| 235 |
+
try:
|
| 236 |
+
client = Anthropic(api_key=api_key)
|
| 237 |
+
|
| 238 |
+
prompt = f"""You are PomoCat, a friendly and encouraging productivity assistant with a cat theme.
|
| 239 |
+
Your role is to provide supportive, motivational responses to help users with their work and focus.
|
| 240 |
+
|
| 241 |
+
Context: {session_context}
|
| 242 |
+
|
| 243 |
+
User message: "{user_input}"
|
| 244 |
+
|
| 245 |
+
Please respond with:
|
| 246 |
+
- Cat-themed language and emojis (πΊπΈπ»πΎetc.)
|
| 247 |
+
- Warm, encouraging tone
|
| 248 |
+
- Practical advice when appropriate
|
| 249 |
+
- Keep responses conversational and supportive
|
| 250 |
+
- 2-3 sentences maximum
|
| 251 |
+
- Use cat behavior metaphors when helpful
|
| 252 |
+
|
| 253 |
+
Respond as PomoCat would:"""
|
| 254 |
+
|
| 255 |
+
response = client.messages.create(
|
| 256 |
+
model="claude-sonnet-4-20250514",
|
| 257 |
+
max_tokens=200,
|
| 258 |
+
temperature=0.7,
|
| 259 |
+
messages=[{"role": "user", "content": prompt}]
|
| 260 |
+
)
|
| 261 |
+
|
| 262 |
+
return response.content[0].text.strip()
|
| 263 |
+
|
| 264 |
+
except Exception as e:
|
| 265 |
+
print(f"β οΈ Claude API error: {e}")
|
| 266 |
+
print(f" API Key present: {'Yes' if api_key else 'No'}")
|
| 267 |
+
print(f" Using fallback responses instead...")
|
| 268 |
+
# Fall back to keyword-based responses
|
| 269 |
+
else:
|
| 270 |
+
if not ANTHROPIC_AVAILABLE:
|
| 271 |
+
print("β οΈ Anthropic library not available")
|
| 272 |
+
elif not api_key:
|
| 273 |
+
print("β οΈ ANTHROPIC_API_KEY environment variable not set")
|
| 274 |
+
|
| 275 |
+
# Fallback to keyword-based responses when API is not available
|
| 276 |
+
return get_fallback_encouragement(user_input)
|
| 277 |
+
|
| 278 |
+
def get_fallback_encouragement(user_input: str) -> str:
|
| 279 |
+
"""Fallback encouragement responses when AI API is not available"""
|
| 280 |
+
input_lower = user_input.lower()
|
| 281 |
+
|
| 282 |
+
if any(word in input_lower for word in ["stress", "overwhelm", "anxious", "worried", "pressure"]):
|
| 283 |
+
return "πΈ *purrs softly* I can sense you're feeling a bit overwhelmed, but remember that even the biggest projects are just a series of small, focused steps! πΎ Take a deep breath with me - you're more capable than you know! πͺβ¨"
|
| 284 |
+
|
| 285 |
+
elif any(word in input_lower for word in ["tired", "exhausted", "drained", "fatigue"]):
|
| 286 |
+
return "π΄ *yawns sympathetically* It sounds like you need some rest! Remember, even cats need their naps to stay sharp! π± Maybe take a short break, stretch those muscles, and come back refreshed! π€β¨"
|
| 287 |
+
|
| 288 |
+
elif any(word in input_lower for word in ["difficult", "hard", "challenging", "tough", "struggle"]):
|
| 289 |
+
return "πΌ *sits up alertly* Challenges are just opportunities in disguise! Every difficult moment is making you stronger! πΎ Break it down into smaller pieces - even the mightiest cat catches mice one at a time! π¦πͺ"
|
| 290 |
+
|
| 291 |
+
elif any(word in input_lower for word in ["motivation", "inspire", "encourage", "boost"]):
|
| 292 |
+
return "π» *purrs enthusiastically* You're already taking the right steps by being here! Every small action is progress! π Remember, I believe in you completely - you have everything you need inside you already! πΎπ"
|
| 293 |
+
|
| 294 |
+
elif any(word in input_lower for word in ["success", "complete", "finish", "achieve", "done", "accomplish"]):
|
| 295 |
+
return "π» *happy purr* That's amazing! I'm so proud of you! π Celebrating your wins is just as important as the work itself! πΎ You're building incredible momentum - keep this energy going! β¨π"
|
| 296 |
+
|
| 297 |
+
elif any(word in input_lower for word in ["procrastinate", "delay", "avoid", "postpone"]):
|
| 298 |
+
return "πΊ *gentle head bump* We all have those moments! The secret is to start with just one tiny step - even 5 minutes of work is better than none! πΎ I'll be right here cheering you on! Sometimes the hardest part is just beginning! πͺβ¨"
|
| 299 |
+
|
| 300 |
+
elif any(word in input_lower for word in ["focus", "concentrate", "attention", "distract"]):
|
| 301 |
+
return "πΈ *alert ears* Focus is like a muscle - it gets stronger with practice! πΎ Try the pomodoro technique: 25 minutes of focused work, then a short break! Even cats know when to hunt and when to rest! π―β¨"
|
| 302 |
+
|
| 303 |
+
else:
|
| 304 |
+
# General encouraging response
|
| 305 |
+
return "πΊ *purrs warmly* I'm here to support you through your work journey! πΎ Whatever you're working on, remember that progress is progress, no matter how small! πͺ You've got this! β¨"
|
| 306 |
+
|
| 307 |
+
def calculate_work_time() -> int:
|
| 308 |
+
"""Calculate elapsed work time in minutes"""
|
| 309 |
+
global pomocat_state
|
| 310 |
+
if not pomocat_state.work_start_time:
|
| 311 |
+
return 0
|
| 312 |
+
return int((datetime.now() - pomocat_state.work_start_time).total_seconds() / 60)
|
| 313 |
+
|
| 314 |
+
def get_help_text() -> str:
|
| 315 |
+
"""Get help text with available commands"""
|
| 316 |
+
return """πΊ PomoCat Commands Help πΎ
|
| 317 |
+
|
| 318 |
+
Work Session Commands:
|
| 319 |
+
β’ "start working" / "start pomodoro" - Begin a 25-minute focus session
|
| 320 |
+
β’ "take a break" / "rest" - Take a break (minimum 20 minutes work required)
|
| 321 |
+
β’ "resume work" / "back to work" - End break and resume working
|
| 322 |
+
β’ "stop" / "end session" - End current session completely
|
| 323 |
+
|
| 324 |
+
Status Commands:
|
| 325 |
+
β’ "status" / "check progress" - See current session status
|
| 326 |
+
β’ "help" / "commands" - Show this help message
|
| 327 |
+
|
| 328 |
+
πΎ Special Features:
|
| 329 |
+
β’ Must work at least 20 minutes before breaks are allowed
|
| 330 |
+
β’ AI encouragement for any questions or concerns
|
| 331 |
+
β’ Session tracking and progress monitoring
|
| 332 |
+
|
| 333 |
+
π» Just chat with me about anything - I'm here to encourage and support you! π
|
| 334 |
+
"""
|
| 335 |
+
|
| 336 |
+
# Create Gradio interface with MCP support
|
| 337 |
+
def create_gradio_interface():
|
| 338 |
+
"""Create the main Gradio interface for PomoCat with MCP support"""
|
| 339 |
+
|
| 340 |
+
with gr.Blocks(
|
| 341 |
+
title="π± PomoCat - Your Focus Buddy"
|
| 342 |
+
) as demo:
|
| 343 |
+
|
| 344 |
+
gr.Markdown("""
|
| 345 |
+
# π± PomoCat - Your Focus Buddy with a Paw-sitive Vibe
|
| 346 |
+
|
| 347 |
+
Welcome to PomoCat! I'm here to help you stay focused with the Pomodoro technique.
|
| 348 |
+
|
| 349 |
+
**π― Key Features:**
|
| 350 |
+
- 25-minute focused work sessions
|
| 351 |
+
- 20-minute minimum work time before breaks
|
| 352 |
+
- AI-powered encouragement and support
|
| 353 |
+
- Session tracking and progress monitoring
|
| 354 |
+
|
| 355 |
+
**π§ Available APIs:**
|
| 356 |
+
- `pomodoro_manager(user_query)` - Main interface: start/stop sessions, AI encouragement
|
| 357 |
+
- `get_session_status()` - Get detailed session status and progress statistics
|
| 358 |
+
- `reset_session()` - Reset current session and clear all progress
|
| 359 |
+
|
| 360 |
+
**π€ AI Features:**
|
| 361 |
+
- Real AI-powered encouragement using Claude API
|
| 362 |
+
- Set ANTHROPIC_API_KEY environment variable for full AI features
|
| 363 |
+
- Fallback to smart keyword-based responses if API not configured
|
| 364 |
+
|
| 365 |
+
**π Quick Start:**
|
| 366 |
+
Just type commands like "start working", "take a break", or ask me anything for encouragement!
|
| 367 |
+
""")
|
| 368 |
+
|
| 369 |
+
with gr.Row():
|
| 370 |
+
with gr.Column(scale=2):
|
| 371 |
+
user_input = gr.Textbox(
|
| 372 |
+
label="π¬ Chat with PomoCat",
|
| 373 |
+
placeholder="Type 'start working' to begin, or ask me anything for encouragement...",
|
| 374 |
+
lines=2
|
| 375 |
+
)
|
| 376 |
+
|
| 377 |
+
submit_btn = gr.Button("Send πΎ", variant="primary")
|
| 378 |
+
|
| 379 |
+
with gr.Column(scale=1):
|
| 380 |
+
status_btn = gr.Button("Check Status π")
|
| 381 |
+
reset_btn = gr.Button("Reset Session π")
|
| 382 |
+
help_btn = gr.Button("Help π‘")
|
| 383 |
+
|
| 384 |
+
output = gr.Textbox(
|
| 385 |
+
label="π± PomoCat Response",
|
| 386 |
+
lines=8,
|
| 387 |
+
max_lines=20,
|
| 388 |
+
interactive=False
|
| 389 |
+
)
|
| 390 |
+
|
| 391 |
+
# Event handlers
|
| 392 |
+
submit_btn.click(
|
| 393 |
+
fn=pomodoro_manager,
|
| 394 |
+
inputs=[user_input],
|
| 395 |
+
outputs=[output]
|
| 396 |
+
)
|
| 397 |
+
|
| 398 |
+
user_input.submit(
|
| 399 |
+
fn=pomodoro_manager,
|
| 400 |
+
inputs=[user_input],
|
| 401 |
+
outputs=[output]
|
| 402 |
+
)
|
| 403 |
+
|
| 404 |
+
status_btn.click(
|
| 405 |
+
fn=get_session_status,
|
| 406 |
+
outputs=[output]
|
| 407 |
+
)
|
| 408 |
+
|
| 409 |
+
reset_btn.click(
|
| 410 |
+
fn=reset_session,
|
| 411 |
+
outputs=[output]
|
| 412 |
+
)
|
| 413 |
+
|
| 414 |
+
help_btn.click(
|
| 415 |
+
fn=get_help_text,
|
| 416 |
+
outputs=[output]
|
| 417 |
+
)
|
| 418 |
+
|
| 419 |
+
# Example interactions
|
| 420 |
+
gr.Examples(
|
| 421 |
+
examples=[
|
| 422 |
+
["start working"],
|
| 423 |
+
["take a break"],
|
| 424 |
+
["status"],
|
| 425 |
+
["I'm feeling overwhelmed with my project"],
|
| 426 |
+
["How can I stay motivated?"],
|
| 427 |
+
["resume work"],
|
| 428 |
+
["stop"]
|
| 429 |
+
],
|
| 430 |
+
inputs=[user_input],
|
| 431 |
+
outputs=[output],
|
| 432 |
+
fn=pomodoro_manager
|
| 433 |
+
)
|
| 434 |
+
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
|
| 438 |
+
return demo
|
| 439 |
+
|
| 440 |
+
if __name__ == "__main__":
|
| 441 |
+
# Parse command line arguments
|
| 442 |
+
parser = argparse.ArgumentParser(description="π± PomoCat - Your Focus Buddy with a Paw-sitive Vibe")
|
| 443 |
+
parser.add_argument("--port", type=int, default=7860, help="Port to run the server on (default: 7860)")
|
| 444 |
+
parser.add_argument("--host", default="0.0.0.0", help="Host to bind the server to (default: 0.0.0.0)")
|
| 445 |
+
args = parser.parse_args()
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
print(f"π± Starting PomoCat...")
|
| 449 |
+
print(f"π‘ Server: http://{args.host}:{args.port}")
|
| 450 |
+
|
| 451 |
+
# Note: MCP functionality depends on Gradio version compatibility
|
| 452 |
+
|
| 453 |
+
# Create and launch the Gradio interface
|
| 454 |
+
demo = create_gradio_interface()
|
| 455 |
+
|
| 456 |
+
# Launch the interface
|
| 457 |
+
demo.launch(
|
| 458 |
+
share=False,
|
| 459 |
+
server_name=args.host,
|
| 460 |
+
server_port=args.port,
|
| 461 |
+
show_error=True,
|
| 462 |
+
mcp_server=True
|
| 463 |
+
)
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio[mcp]>=5.32.1
|
| 2 |
+
# Core dependencies for PomoCat functionality
|
| 3 |
+
python-dateutil>=2.8.0
|
| 4 |
+
anthropic>=0.7.0
|