**Problem**: User got generic "Sorry, I encountered an error" (80 chars)
instead of the detailed timeout message with progress info and suggestions.
**Root Cause**: agent.py error handlers were replacing exception messages
with hardcoded generic text, discarding the detailed timeout info from
llm_interface.py.
**Solution**:
1. TimeoutError handler: Use str(e) to preserve detailed message from
llm_interface.py (message count, last tool, suggestions)
2. General Exception handlers: Include actual error text (limited to 500
chars) instead of "Please try again"
3. Applied to both Agent SDK and Direct API code paths
**Impact**: Users now see the actual error details including:
- Progress when task timed out (message count, last tool used)
- Actionable suggestions (break into sub-tasks, use delegate_task)
- Actual error messages for debugging instead of generic text
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
**Problem**: User frustrated that 10-minute timeout returned unhelpful
generic message "task may be too complex" when task "create a repo for
the dhcp course" timed out after 80 messages.
**Solution**: Enhanced timeout error to provide:
- Progress info (message count, last tool used)
- Complexity indicator (# of different tools)
- Actionable suggestions (break into sub-tasks, use delegate_task)
**Changes**:
- Track _last_message_count and _last_tool_names as instance vars
(survive timeout unlike local vars in canceled async function)
- Update tracking variables in message loop
- Build multi-line error message with progress summary and suggestions
- Use chr(10) for newlines to avoid string literal corruption
**Impact**: Users now get helpful guidance instead of generic error when
complex tasks timeout, including suggestion to use new delegate_task tool
for parallel work.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add sub_agent_manager.register_sub_agent() call when agent_id provided
- Add missing return statement (method was returning None)
- Fixes watchdog tracking for when delegation is implemented
Bug found during investigation of why watchdog didn't engage during
parallel task test. Root cause was no MCP tool for delegation, but
this bug would have prevented tracking even if delegation worked.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed error logging from MEMORY.md (permanent) to daily logs (time-based).
This prevents MEMORY.md from becoming polluted with error stack traces
that degrade search quality.
Impact:
- Future errors go to memory/YYYY-MM-DD.md (naturally age out)
- MEMORY.md stays focused on project context only
- Search results no longer polluted by duplicate stack traces
Change: self_healing.py line 131: daily=False → daily=True
Note: SOUL.md, MEMORY.md, jordan.md also optimized (not in git - gitignored)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moved obsidian_mcp.py into mcp_servers/obsidian/ to align with other
MCP server organization (SSH, Cloudflare, Loki). This improves code
discoverability and maintains consistent package structure.
Changes:
- Moved obsidian_mcp.py → mcp_servers/obsidian/obsidian_mcp.py
- Updated lazy import in llm_interface.py (line 396)
- Updated lazy import in tools.py (line 550)
- Deleted empty scripts/ directory
All imports verified with runtime tests. Zero functional changes.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- Cloudflare Code Mode MCP: Exposes entire Cloudflare API (2,500+ endpoints)
via remote MCP server at https://mcp.cloudflare.com/mcp
* Two tools: search() to query OpenAPI spec, execute() to run JS code
* Uses npx mcp-remote as stdio bridge
* Auth via CLOUDFLARE_API_TOKEN as Bearer header
- Loki MCP Server: Log querying and analysis via Loki HTTP API
* Query logs with LogQL syntax
* Real-time log streaming support
* Label introspection and metrics queries
* Configurable via LOKI_URL environment variable
Technical changes:
- Created mcp_servers/cloudflare/ with config and connection logic
- Created mcp_servers/loki/ with HTTP client and MCP tool wrappers
- Added promtail-config-optimized.yaml for syslog ingestion config
- Updated .env.example with Cloudflare and Loki configuration templates
Both integrations:
- Use environment variables for configuration (no hardcoded credentials)
- Include feature flags (CLOUDFLARE_MCP_ENABLED, LOKI_MCP_ENABLED)
- Follow existing MCP server patterns for consistency
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- SSH MCP server with two tools:
* ssh_execute: Run commands on remote hosts via SSH
* ssh_file_upload: Upload files via SFTP
- Support for both password and SSH key authentication
- Auto-accept SSH host keys (AutoAddPolicy) for homelab use
- Gmail attachment download functionality
- Added download_attachment tool for Gmail API
Technical changes:
- Created mcp_servers/mcp_ssh.py with MCP-compliant text output
- Updated llm_interface.py to load SSH MCP server
- Added paramiko>=3.4.0 to requirements.txt
- Updated .env.example with SSH configuration template
- Enhanced gmail_client.py with download_attachment() method
- Added download_attachment tool handler in tools.py
SSH credentials configured via environment variables:
- PROXMOX_SSH_HOST, PROXMOX_SSH_USER, PROXMOX_SSH_PORT
- PROXMOX_SSH_PASSWORD (or) PROXMOX_SSH_KEY_FILE
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Scaffold mcp_servers/loki/ with config and async HTTP client
- Fix Slack/Telegram adapters to use non-blocking connections
- Upgrade default model to claude-sonnet-4-6
- Improve Agent SDK message collection for empty ResultMessage cases
- Add Message-ID to email summaries, increase body truncation limit
- Fix .gitignore inline comments that broke sensitive file exclusions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add SelfHealingSystem with error observation infrastructure
- Capture errors with full context: type, message, stack trace, intent, inputs
- Log to MEMORY.md with deduplication (max 3 attempts per error signature)
- Integrate error capture in agent, tools, runtime, and scheduler
- Non-invasive: preserves all existing error handling behavior
- Foundation for future diagnosis and auto-fixing capabilities
Phase 1 of 4-phase rollout - observation only, no auto-fixing yet.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add People API integration with contact management tools (create, list, get)
- Fix OAuth flow: replace deprecated OOB with localhost callback
- Fix Ctrl+C handling with proper signal handlers for graceful shutdown
- Fix UTF-8 encoding in scheduled_tasks.py for Windows compatibility
- Add users/ directory to gitignore to protect personal data
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements on-demand Google tools (not adapter) for email and calendar access via OAuth2.
Features:
- OAuth2 user consent flow with automatic token refresh
- 3 Gmail tools: send_email, read_emails, get_email
- 3 Calendar tools: read_calendar, create_calendar_event, search_calendar
- Lazy loading pattern for Google clients
- Secure token storage with file permissions
- Browser-based setup: python bot_runner.py --setup-google
Architecture:
- Tools-only approach (zero API calls when not in use)
- User-initiated actions only (no continuous polling)
- MIME message creation for emails with threading support
- HTML to text conversion for email parsing
- ISO 8601 timestamp handling for calendar events
Files added:
- google_tools/oauth_manager.py: OAuth2 flow and token management
- google_tools/gmail_client.py: Gmail API wrapper
- google_tools/calendar_client.py: Calendar API wrapper
- google_tools/utils.py: Email/MIME helpers
- config/scheduled_tasks.yaml: Example scheduled tasks config
Files modified:
- tools.py: Added 6 Google tool handlers with lazy initialization
- bot_runner.py: Added --setup-google command for OAuth authorization
- requirements.txt: Added Google API dependencies
- .gitignore: Added google_credentials.yaml and google_oauth_token.json
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>