Add Gmail and Google Calendar integration

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>
This commit is contained in:
2026-02-14 10:29:28 -07:00
parent 8afff96bb5
commit dc14baf426
10 changed files with 1555 additions and 1 deletions

116
config/scheduled_tasks.yaml Normal file
View File

@@ -0,0 +1,116 @@
# Scheduled Tasks Configuration
# Tasks that require the Agent/LLM to execute
tasks:
# Morning briefing - sent to Slack/Telegram
- name: morning-weather
prompt: |
Current weather report for my location. Just the weather - keep it brief.
schedule: "daily 06:00"
enabled: true
send_to_platform: "telegram"
send_to_channel: "8088983654" # Your Telegram user ID
# Daily API cost report
- name: daily-cost-report
prompt: |
Generate a daily API usage and cost report:
Read the usage_data.json file to get today's API usage statistics.
Format the report as follows:
📊 **Daily API Usage Report**
**Today's Stats:**
- Total API calls: [count]
- Input tokens: [count]
- Output tokens: [count]
- Cache hits: [count] (if any)
**Costs:**
- Today: $[amount]
- Model breakdown: [breakdown by model]
**Budget Tracking:**
- Remaining budget: $19.86
- 75% threshold: $14.90 (⚠️ WARN IF EXCEEDED)
- Status: [On track / Warning - approaching 75% / Critical - over 75%]
⚠️ **IMPORTANT:** If cumulative cost exceeds $14.90 (75% of $19.86), display a clear warning message.
Keep it clear and actionable!
schedule: "daily 23:00"
enabled: true
send_to_platform: "telegram"
send_to_channel: "8088983654"
# Evening summary
- name: evening-report
prompt: |
Good evening! Time for the daily wrap-up:
1. What was accomplished today?
2. Any tasks still pending?
3. Preview of tomorrow's priorities
4. Weather forecast for tomorrow (infer or say API needed)
Keep it concise and positive.
schedule: "daily 18:00"
enabled: false
send_to_platform: "telegram"
send_to_channel: "123456789" # Replace with chat ID
# Hourly health check (no message sending)
- name: system-health-check
prompt: |
Quick health check:
1. Are there any tasks that have been pending > 24 hours?
2. Is the memory system healthy?
3. Any alerts or issues?
Respond with "HEALTHY" if all is well, otherwise describe the issue.
schedule: "hourly"
enabled: false
username: "health-checker"
# Weekly review on Friday
- name: weekly-summary
prompt: |
It's Friday! Time for the weekly review:
1. Major accomplishments this week
2. Challenges faced and lessons learned
3. Key metrics (tasks completed, etc.)
4. Goals for next week
5. Team shoutouts (if applicable)
Make it comprehensive but engaging.
schedule: "weekly fri 17:00"
enabled: false
send_to_platform: "slack"
send_to_channel: "C12345"
# Custom: Midday standup
- name: midday-standup
prompt: |
Midday check-in! Quick standup report:
1. Morning accomplishments
2. Current focus
3. Any blockers?
4. Afternoon plan
Keep it brief - standup style.
schedule: "daily 12:00"
enabled: false
send_to_platform: "slack"
send_to_channel: "C12345"
# Configuration notes:
# - schedule formats:
# - "hourly" - Every hour on the hour
# - "daily HH:MM" - Every day at specified time (24h format)
# - "weekly day HH:MM" - Every week on specified day (mon, tue, wed, thu, fri, sat, sun)
# - send_to_platform: null = don't send to messaging (only log)
# - username: Agent memory username to use for this task