pxiaoer commited on
Commit
d3febbf
Β·
1 Parent(s): 407c4a7
Files changed (3) hide show
  1. README.md +225 -4
  2. app.py +463 -0
  3. 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: false
10
  license: apache-2.0
11
- short_description: Your focus buddy with a paw-sitive vibe
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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