pgits Claude commited on
Commit
630eb84
·
1 Parent(s): 56dfc87

Add comprehensive logging and debugging utilities

Browse files

Enhanced debugging capabilities for SSH Dev Mode:
- Dual logging (stdout + file) to /tmp/app.log
- DEBUG level logging with detailed component tracking
- Interactive debugging with breakpoints (debug_breakpoint)
- Chat flow debugging script with step-by-step analysis
- Reduced uvicorn/health check noise in logs
- Always-visible debug_print for critical debugging

SSH Debug Tools:
- python3 scripts/debug_chat.py (interactive debugging)
- debug_breakpoint(message, locals()) in code
- Enhanced startup diagnostics

v1.0.5 - Production debugging ready

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

Files changed (5) hide show
  1. LinkedIn.md +95 -0
  2. app.py +35 -19
  3. app/api/main.py +23 -4
  4. app/core/logging_config.py +212 -0
  5. scripts/debug_chat.py +187 -0
LinkedIn.md ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 VoiceCal.ai v1.0.0 - Clean Architecture Migration
2
+
3
+ ## Migration Success: From Nested Chaos to Clean Deployment
4
+
5
+ Today I successfully migrated **ChatCal.ai to VoiceCal.ai v1.0.0** with a completely clean repository structure for HuggingFace Spaces deployment.
6
+
7
+ ### The Problem We Solved
8
+ - **Nested directory confusion**: `/chatcal-ai/chatcal-ai/app/` causing path issues
9
+ - **Git workflow inconsistencies**: File upload vs. proper version control
10
+ - **Docker caching issues**: HuggingFace showing stale Dockerfiles
11
+ - **Deployment complexity**: Multiple path adjustments breaking deployments
12
+
13
+ ### The Solution: Fresh Start Architecture
14
+
15
+ #### Before (Problematic):
16
+ ```
17
+ /chatCal.ai/chatcal-ai/ (repo root)
18
+ ├── chatcal-ai/ (actual app nested)
19
+ ├── speech2text/ (unrelated)
20
+ ├── CLAUDE.md (unrelated)
21
+ └── legacy files...
22
+ ```
23
+
24
+ #### After (Clean):
25
+ ```
26
+ /voiceCal-ai-v1/ (repo root = HF Space name)
27
+ ├── app/ (FastAPI directly at root)
28
+ ├── Dockerfile (standard deployment)
29
+ ├── app.py (simple entry point)
30
+ ├── requirements.txt
31
+ └── pyproject.toml
32
+ ```
33
+
34
+ ### Technical Improvements
35
+
36
+ #### 🏗️ **Architecture**
37
+ - **Standard Docker structure**: No more nested path confusion
38
+ - **Direct file access**: All imports work without path manipulation
39
+ - **Clean git workflow**: Proper semantic versioning (v1.0.0)
40
+
41
+ #### 🔧 **Development**
42
+ - **Debugging tools**: wget, git, curl, procps, htop, nano, vim, net-tools, lsof, strace
43
+ - **Clean Dockerfile**: No more tee command causing container exit
44
+ - **Proper logging**: Both stdout and `/tmp/app.log` for SSH debugging
45
+
46
+ #### 🎯 **Deployment**
47
+ - **Fresh HuggingFace Space**: `pgits/voiceCal-ai-v1`
48
+ - **No legacy caching**: Clean start eliminates previous issues
49
+ - **Consistent versioning**: Semantic version matches deployment
50
+
51
+ ### Migration Process
52
+
53
+ 1. ✅ **Created clean directory structure** matching HF Space name
54
+ 2. ✅ **Copied essential files** (app/, Dockerfile, requirements.txt, etc.)
55
+ 3. ✅ **Updated all path references** for standard deployment
56
+ 4. ✅ **Initialized fresh git repo** with proper main branch
57
+ 5. ✅ **Ready for fresh HF Space** deployment
58
+
59
+ ### Key Lessons Learned
60
+
61
+ #### 🎯 **Project Structure Matters**
62
+ - Directory naming should match deployment target
63
+ - Avoid nested structures that complicate Docker deployments
64
+ - Keep unrelated files separate from deployment artifacts
65
+
66
+ #### 🔄 **Git Workflow Discipline**
67
+ - Always use proper git workflow vs. ad-hoc file uploads
68
+ - Semantic versioning prevents deployment confusion
69
+ - Clean commit history aids debugging
70
+
71
+ #### 🐳 **Docker Best Practices**
72
+ - Standard WORKDIR structure
73
+ - Include debugging tools for production troubleshooting
74
+ - Avoid complex shell commands in CMD that can cause exit issues
75
+
76
+ ### Next Steps
77
+
78
+ Now ready to create fresh HuggingFace Space `pgits/voiceCal-ai-v1` with:
79
+ - ✅ Clean repository structure
80
+ - ✅ Standard Docker deployment
81
+ - ✅ All debugging tools included
82
+ - ✅ Proper git workflow established
83
+ - ✅ Semantic versioning (v1.0.0)
84
+
85
+ **Migration Summary:**
86
+ - **Old**: Nested complexity, path confusion, deployment issues
87
+ - **New**: Clean structure, standard paths, reliable deployment
88
+
89
+ This migration eliminates the file inconsistencies and deployment issues we were experiencing, setting up a professional foundation for future development.
90
+
91
+ ---
92
+
93
+ #VoiceAI #HuggingFace #Docker #SoftwareEngineering #CleanArchitecture #FastAPI #Deployment #GitWorkflow
94
+
95
+ **VoiceCal.ai v1.0.0** - Professional voice-first calendar booking with Google Calendar integration, STT/TTS, and Groq LLM backend.
app.py CHANGED
@@ -19,25 +19,41 @@ os.environ.setdefault("APP_PORT", "7860") # HF Spaces default port
19
  from app.api.main import app
20
 
21
  if __name__ == "__main__":
22
- import logging
 
 
 
 
 
 
23
 
24
- # Configure logging
25
- logging.basicConfig(
26
- level=logging.INFO,
27
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
28
- handlers=[
29
- logging.FileHandler('/tmp/app.log'),
30
- logging.StreamHandler()
31
- ]
32
- )
33
 
34
  port = int(os.environ.get("PORT", os.environ.get("APP_PORT", 7860)))
35
- print(f"===== Application Startup at {datetime.now()} =====")
36
- print(f"🚀 Starting ChatCal.ai on port {port}")
37
-
38
- uvicorn.run(
39
- app,
40
- host="0.0.0.0",
41
- port=port,
42
- log_level="info"
43
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  from app.api.main import app
20
 
21
  if __name__ == "__main__":
22
+ # Setup enhanced dual logging (stdout + file)
23
+ from app.core.logging_config import setup_enhanced_logging, setup_breakpoint_debugging
24
+
25
+ # Enable DEBUG level for comprehensive logging
26
+ log_level = os.environ.get("LOG_LEVEL", "DEBUG")
27
+ log_file = setup_enhanced_logging(log_level=log_level, log_file="/tmp/app.log")
28
+ setup_breakpoint_debugging()
29
 
30
+ import logging
31
+ logger = logging.getLogger("app.startup")
 
 
 
 
 
 
 
32
 
33
  port = int(os.environ.get("PORT", os.environ.get("APP_PORT", 7860)))
34
+
35
+ logger.info(f"🚀 Starting ChatCal.ai VoiceCal-ai-v1 on port {port}")
36
+ logger.info(f"🔧 Session Backend: {os.environ.get('SESSION_BACKEND', 'unknown')}")
37
+ logger.info(f"🌍 Environment: {os.environ.get('APP_ENV', 'unknown')}")
38
+ logger.info(f"📁 Log file: {log_file}")
39
+ logger.info(f"🐛 SSH debugging available via Dev Mode")
40
+
41
+ # Additional startup diagnostics
42
+ logger.debug("🔍 Environment check:")
43
+ required_vars = ["GROQ_API_KEY", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "SECRET_KEY"]
44
+ for var in required_vars:
45
+ value = os.environ.get(var, "NOT_SET")
46
+ masked = value[:10] + "..." if len(value) > 10 and value != "NOT_SET" else value
47
+ logger.debug(f" {var}: {masked}")
48
+
49
+ try:
50
+ uvicorn.run(
51
+ app,
52
+ host="0.0.0.0",
53
+ port=port,
54
+ log_level="warning", # Reduce uvicorn noise, our dual logger handles app logs
55
+ access_log=False # Reduce access log spam
56
+ )
57
+ except Exception as e:
58
+ logger.critical(f"💥 Application startup failed: {e}")
59
+ raise
app/api/main.py CHANGED
@@ -306,22 +306,41 @@ async def get_conversation_history(session_id: str):
306
  @app.post("/chat", response_model=ChatResponse)
307
  async def chat(request: ChatRequest):
308
  """Chat with the AI assistant."""
 
 
 
 
 
 
 
309
  try:
310
  # Create session if not provided
311
  if not request.session_id:
 
312
  request.session_id = session_manager.create_session()
313
-
 
314
  # Get or create conversation
 
315
  conversation = session_manager.get_or_create_conversation(request.session_id)
316
  if not conversation:
 
317
  raise HTTPException(status_code=404, detail="Session not found")
318
-
 
 
319
  # Get response from agent
320
  response = conversation.get_response(request.message)
321
-
 
322
  # Store conversation history
 
323
  session_manager.store_conversation_history(request.session_id)
324
-
 
 
 
 
325
  return ChatResponse(
326
  response=response,
327
  session_id=request.session_id,
 
306
  @app.post("/chat", response_model=ChatResponse)
307
  async def chat(request: ChatRequest):
308
  """Chat with the AI assistant."""
309
+ from app.core.logging_config import log_chat_request, log_chat_response, debug_print
310
+
311
+ # Enhanced logging for chat requests
312
+ session_id = request.session_id or "new_session"
313
+ log_chat_request(session_id, request.message)
314
+ debug_print(f"CHAT START - Session: {session_id[:8]}...", {"message_length": len(request.message)})
315
+
316
  try:
317
  # Create session if not provided
318
  if not request.session_id:
319
+ debug_print("Creating new session")
320
  request.session_id = session_manager.create_session()
321
+ debug_print(f"New session created: {request.session_id}")
322
+
323
  # Get or create conversation
324
+ debug_print("Getting conversation manager")
325
  conversation = session_manager.get_or_create_conversation(request.session_id)
326
  if not conversation:
327
+ debug_print("ERROR: Conversation not found", {"session_id": request.session_id})
328
  raise HTTPException(status_code=404, detail="Session not found")
329
+
330
+ debug_print("Conversation found, getting response from agent")
331
+
332
  # Get response from agent
333
  response = conversation.get_response(request.message)
334
+ debug_print("Agent response received", {"response_length": len(response)})
335
+
336
  # Store conversation history
337
+ debug_print("Storing conversation history")
338
  session_manager.store_conversation_history(request.session_id)
339
+
340
+ # Log successful response
341
+ log_chat_response(request.session_id, response)
342
+ debug_print("CHAT SUCCESS - Response ready")
343
+
344
  return ChatResponse(
345
  response=response,
346
  session_id=request.session_id,
app/core/logging_config.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Enhanced logging configuration for VoiceCal.ai debugging
3
+
4
+ Provides dual logging to both stdout and file with detailed formatting.
5
+ Includes debugging utilities for SSH breakpoint sessions.
6
+ """
7
+
8
+ import logging
9
+ import sys
10
+ from datetime import datetime
11
+ from pathlib import Path
12
+
13
+
14
+ class DualOutputHandler(logging.Handler):
15
+ """Custom handler that writes to both stdout and file simultaneously."""
16
+
17
+ def __init__(self, log_file_path: str):
18
+ super().__init__()
19
+ self.log_file_path = log_file_path
20
+
21
+ # Ensure log directory exists
22
+ Path(log_file_path).parent.mkdir(parents=True, exist_ok=True)
23
+
24
+ # Create formatter
25
+ formatter = logging.Formatter(
26
+ '%(asctime)s | %(levelname)-8s | %(name)-20s | %(message)s',
27
+ datefmt='%Y-%m-%d %H:%M:%S'
28
+ )
29
+ self.setFormatter(formatter)
30
+
31
+ def emit(self, record):
32
+ """Emit log record to both stdout and file."""
33
+ try:
34
+ msg = self.format(record)
35
+
36
+ # Write to stdout
37
+ print(msg, flush=True)
38
+
39
+ # Write to file
40
+ with open(self.log_file_path, 'a', encoding='utf-8') as f:
41
+ f.write(msg + '\n')
42
+ f.flush()
43
+
44
+ except Exception:
45
+ self.handleError(record)
46
+
47
+
48
+ def setup_enhanced_logging(log_level: str = "INFO", log_file: str = "/tmp/app.log"):
49
+ """
50
+ Setup enhanced dual logging for VoiceCal.ai
51
+
52
+ Args:
53
+ log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
54
+ log_file: Path to log file (default: /tmp/app.log)
55
+ """
56
+
57
+ # Clear any existing handlers
58
+ root_logger = logging.getLogger()
59
+ root_logger.handlers.clear()
60
+
61
+ # Set log level
62
+ level = getattr(logging, log_level.upper(), logging.INFO)
63
+ root_logger.setLevel(level)
64
+
65
+ # Add dual output handler
66
+ dual_handler = DualOutputHandler(log_file)
67
+ dual_handler.setLevel(level)
68
+ root_logger.addHandler(dual_handler)
69
+
70
+ # Log startup message
71
+ startup_msg = f"""
72
+ {'='*80}
73
+ 🚀 VoiceCal.ai Enhanced Logging Started
74
+ 📅 Timestamp: {datetime.now().isoformat()}
75
+ 📋 Log Level: {log_level.upper()}
76
+ 📁 Log File: {log_file}
77
+ 🔧 SSH Debug Mode: Available via Dev Mode
78
+ {'='*80}
79
+ """
80
+
81
+ logging.info(startup_msg)
82
+
83
+ # Configure specific loggers for detailed debugging
84
+ configure_detailed_loggers()
85
+
86
+ return log_file
87
+
88
+
89
+ def configure_detailed_loggers():
90
+ """Configure specific loggers for detailed debugging."""
91
+
92
+ # Enhanced logging for critical components
93
+ loggers_config = {
94
+ 'app.core.agent': logging.DEBUG,
95
+ 'app.calendar.auth': logging.DEBUG,
96
+ 'app.core.session_factory': logging.DEBUG,
97
+ 'app.api.main': logging.DEBUG,
98
+ 'google.auth': logging.INFO,
99
+ 'google_auth_httplib2': logging.INFO,
100
+ 'googleapiclient.discovery': logging.INFO,
101
+ 'httpx': logging.WARNING, # Reduce Groq API noise
102
+ 'llama_index': logging.WARNING, # Reduce LlamaIndex noise
103
+ }
104
+
105
+ for logger_name, level in loggers_config.items():
106
+ logger = logging.getLogger(logger_name)
107
+ logger.setLevel(level)
108
+
109
+ logging.info("📊 Detailed logging configured for key components")
110
+
111
+
112
+ def log_function_entry(func_name: str, **kwargs):
113
+ """Log function entry with parameters."""
114
+ logger = logging.getLogger(f"app.debug.{func_name}")
115
+ params = ", ".join(f"{k}={v}" for k, v in kwargs.items())
116
+ logger.debug(f"🔵 ENTER {func_name}({params})")
117
+
118
+
119
+ def log_function_exit(func_name: str, result=None, error=None):
120
+ """Log function exit with result or error."""
121
+ logger = logging.getLogger(f"app.debug.{func_name}")
122
+ if error:
123
+ logger.error(f"🔴 EXIT {func_name} - ERROR: {error}")
124
+ else:
125
+ logger.debug(f"🟢 EXIT {func_name} - SUCCESS: {str(result)[:100]}...")
126
+
127
+
128
+ def setup_breakpoint_debugging():
129
+ """
130
+ Setup debugging utilities for SSH breakpoint sessions.
131
+
132
+ Usage in code:
133
+ from app.core.logging_config import debug_breakpoint
134
+ debug_breakpoint("Checking calendar auth", locals())
135
+ """
136
+ logging.info("🐛 SSH Breakpoint debugging utilities loaded")
137
+ logging.info(" Use debug_breakpoint(message, locals()) in code for interactive debugging")
138
+
139
+
140
+ def debug_breakpoint(message: str, local_vars: dict = None):
141
+ """
142
+ Interactive debugging breakpoint for SSH sessions.
143
+
144
+ Args:
145
+ message: Description of breakpoint location
146
+ local_vars: Local variables to inspect (pass locals())
147
+ """
148
+ import pdb
149
+ import json
150
+
151
+ logger = logging.getLogger("app.debug.breakpoint")
152
+ logger.critical(f"🛑 BREAKPOINT: {message}")
153
+
154
+ if local_vars:
155
+ # Log key variables
156
+ for key, value in local_vars.items():
157
+ if not key.startswith('_'):
158
+ try:
159
+ # Try to serialize value for logging
160
+ str_val = str(value)[:200]
161
+ logger.debug(f" {key}: {str_val}")
162
+ except:
163
+ logger.debug(f" {key}: <non-serializable>")
164
+
165
+ logger.critical("🔧 Starting interactive debugger (use 'c' to continue)")
166
+ pdb.set_trace()
167
+
168
+
169
+ def log_chat_request(session_id: str, message: str):
170
+ """Log incoming chat requests with details."""
171
+ logger = logging.getLogger("app.chat.request")
172
+ logger.info(f"💬 CHAT REQUEST | Session: {session_id[:8]}... | Message: {message[:100]}...")
173
+
174
+
175
+ def log_chat_response(session_id: str, response: str, tools_used: list = None):
176
+ """Log chat responses with details."""
177
+ logger = logging.getLogger("app.chat.response")
178
+ tools_str = f" | Tools: {tools_used}" if tools_used else ""
179
+ logger.info(f"🤖 CHAT RESPONSE | Session: {session_id[:8]}... | Response: {response[:100]}...{tools_str}")
180
+
181
+
182
+ def log_calendar_operation(operation: str, details: dict):
183
+ """Log calendar operations with details."""
184
+ logger = logging.getLogger("app.calendar.operation")
185
+ details_str = ", ".join(f"{k}={v}" for k, v in details.items())
186
+ logger.info(f"📅 CALENDAR {operation.upper()} | {details_str}")
187
+
188
+
189
+ def log_session_operation(operation: str, session_id: str, details: dict = None):
190
+ """Log session operations with details."""
191
+ logger = logging.getLogger("app.session.operation")
192
+ details_str = f" | {details}" if details else ""
193
+ logger.info(f"🔑 SESSION {operation.upper()} | ID: {session_id[:8]}...{details_str}")
194
+
195
+
196
+ # Utility for quick debugging prints that always show
197
+ def debug_print(message: str, data=None):
198
+ """Always-visible debug print for critical debugging."""
199
+ timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
200
+ print(f"🚨 DEBUG [{timestamp}] {message}", flush=True)
201
+ if data:
202
+ print(f" Data: {data}", flush=True)
203
+
204
+ # Also log to file if possible
205
+ try:
206
+ with open("/tmp/debug.log", "a") as f:
207
+ f.write(f"[{timestamp}] {message}\n")
208
+ if data:
209
+ f.write(f" Data: {data}\n")
210
+ f.flush()
211
+ except:
212
+ pass
scripts/debug_chat.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Interactive debugging script for VoiceCal.ai chat functionality
4
+
5
+ This script allows you to test and debug chat functionality step by step
6
+ with detailed logging and breakpoints for SSH Dev Mode sessions.
7
+
8
+ Usage:
9
+ cd /app && python3 scripts/debug_chat.py
10
+ """
11
+
12
+ import sys
13
+ import os
14
+ import uuid
15
+ from datetime import datetime
16
+
17
+ # Add app to path
18
+ sys.path.insert(0, '/app')
19
+
20
+ from app.core.logging_config import (
21
+ setup_enhanced_logging, debug_breakpoint, debug_print,
22
+ log_chat_request, log_function_entry, log_function_exit
23
+ )
24
+
25
+
26
+ def debug_session_manager():
27
+ """Debug session manager initialization."""
28
+ debug_print("=== DEBUGGING SESSION MANAGER ===")
29
+
30
+ try:
31
+ from app.core.session_factory import session_manager
32
+ debug_print("Session manager imported successfully")
33
+ debug_print(f"Session manager type: {type(session_manager).__name__}")
34
+
35
+ # Test session creation
36
+ session_id = str(uuid.uuid4())
37
+ debug_print(f"Testing session creation with ID: {session_id}")
38
+
39
+ # You can add a breakpoint here for interactive debugging
40
+ # debug_breakpoint("Session manager ready", locals())
41
+
42
+ return session_manager, session_id
43
+
44
+ except Exception as e:
45
+ debug_print(f"Session manager error: {e}")
46
+ import traceback
47
+ debug_print(f"Traceback: {traceback.format_exc()}")
48
+ return None, None
49
+
50
+
51
+ def debug_agent_creation(session_id):
52
+ """Debug agent creation process."""
53
+ debug_print("=== DEBUGGING AGENT CREATION ===")
54
+
55
+ try:
56
+ from app.core.agent import ChatCalAgent
57
+ debug_print("ChatCalAgent imported successfully")
58
+
59
+ debug_print(f"Creating agent for session: {session_id}")
60
+ agent = ChatCalAgent(session_id)
61
+ debug_print("Agent created successfully")
62
+
63
+ # Check agent properties
64
+ debug_print(f"Agent system prompt preview: {agent.base_system_prompt[:100]}...")
65
+ debug_print(f"Agent user info: {agent.user_info}")
66
+
67
+ # Breakpoint for agent inspection
68
+ # debug_breakpoint("Agent created", locals())
69
+
70
+ return agent
71
+
72
+ except Exception as e:
73
+ debug_print(f"Agent creation error: {e}")
74
+ import traceback
75
+ debug_print(f"Traceback: {traceback.format_exc()}")
76
+ return None
77
+
78
+
79
+ def debug_calendar_auth():
80
+ """Debug calendar authentication."""
81
+ debug_print("=== DEBUGGING CALENDAR AUTH ===")
82
+
83
+ try:
84
+ from app.calendar.auth import CalendarAuth
85
+ debug_print("CalendarAuth imported successfully")
86
+
87
+ auth = CalendarAuth()
88
+ debug_print(f"CalendarAuth created, redirect URI: {auth.redirect_uri}")
89
+
90
+ # Test credential loading
91
+ from app.config import settings
92
+ debug_print("Environment variables:")
93
+ debug_print(f" GOOGLE_CLIENT_ID: {settings.google_client_id[:10]}...")
94
+ debug_print(f" APP_ENV: {settings.app_env}")
95
+
96
+ # Test calendar service
97
+ service = auth.get_calendar_service()
98
+ debug_print("Calendar service created successfully")
99
+
100
+ return True
101
+
102
+ except Exception as e:
103
+ debug_print(f"Calendar auth error: {e}")
104
+ import traceback
105
+ debug_print(f"Traceback: {traceback.format_exc()}")
106
+ return False
107
+
108
+
109
+ def debug_chat_flow(message="Hello, I need to book an appointment with Peter"):
110
+ """Debug the complete chat flow."""
111
+ debug_print("=== DEBUGGING COMPLETE CHAT FLOW ===")
112
+
113
+ # Step 1: Session manager
114
+ session_manager, session_id = debug_session_manager()
115
+ if not session_manager:
116
+ return False
117
+
118
+ # Step 2: Agent creation
119
+ agent = debug_agent_creation(session_id)
120
+ if not agent:
121
+ return False
122
+
123
+ # Step 3: Calendar auth
124
+ calendar_ok = debug_calendar_auth()
125
+ if not calendar_ok:
126
+ debug_print("⚠️ Calendar auth failed, but continuing with chat test")
127
+
128
+ # Step 4: Test conversation
129
+ debug_print("=== TESTING CONVERSATION ===")
130
+ try:
131
+ conversation = session_manager.get_or_create_conversation(session_id)
132
+ debug_print("Conversation manager created")
133
+
134
+ debug_print(f"Sending message: {message}")
135
+
136
+ # Add breakpoint before getting response for interactive debugging
137
+ # debug_breakpoint("About to get agent response", locals())
138
+
139
+ response = conversation.get_response(message)
140
+ debug_print(f"Response received: {response[:200]}...")
141
+
142
+ return True
143
+
144
+ except Exception as e:
145
+ debug_print(f"Chat flow error: {e}")
146
+ import traceback
147
+ debug_print(f"Traceback: {traceback.format_exc()}")
148
+ return False
149
+
150
+
151
+ def main():
152
+ """Main debugging session."""
153
+ print("🐛 VoiceCal.ai Interactive Debugging Session")
154
+ print("=" * 60)
155
+
156
+ # Setup enhanced logging
157
+ setup_enhanced_logging(log_level="DEBUG", log_file="/tmp/debug_chat.log")
158
+
159
+ print("\n📋 Available debugging functions:")
160
+ print("1. debug_session_manager() - Test session management")
161
+ print("2. debug_agent_creation(session_id) - Test agent creation")
162
+ print("3. debug_calendar_auth() - Test calendar authentication")
163
+ print("4. debug_chat_flow() - Test complete chat flow")
164
+ print("5. debug_breakpoint(msg, locals()) - Interactive breakpoint")
165
+
166
+ print("\n🔧 Starting automated debug flow...")
167
+ success = debug_chat_flow()
168
+
169
+ if success:
170
+ print("\n✅ All debugging tests passed!")
171
+ else:
172
+ print("\n❌ Some debugging tests failed - check logs for details")
173
+
174
+ print(f"\n📁 Debug logs saved to: /tmp/debug_chat.log")
175
+ print("💡 For interactive debugging, uncomment debug_breakpoint() calls in this script")
176
+
177
+ # Interactive mode
178
+ print("\n🎮 Entering interactive mode...")
179
+ print("Available variables: session_manager, agent, conversation")
180
+ print("Type 'exit()' to quit")
181
+
182
+ import code
183
+ code.interact(local=locals())
184
+
185
+
186
+ if __name__ == "__main__":
187
+ main()