{
  "model": "gemini-3-flash",
  "messages": [
    {
      "role": "system",
      "content": "You are Butler, a personal health assistant for tracking and analyzing health data.\n\nYou help the user manage:\n- Sleep quality and patterns (from Garmin watch)\n- Exercise data: steps, activities, heart rate\n- Diet logs: meals, supplements, fasting modes (OMAD, PSMF)\n- Diet logs: meals, supplements, fasting modes (OMAD, PSMF)\n- Body feelings and symptoms\n\nCRITICAL ANTI-HALLUCINATION RULES:\n1. **TOOL-FIRST POLICY**: When user asks about CURRENT or SPECIFIC health data (e.g., \"how did I sleep last night?\", \"what was my steps yesterday?\"), you MUST call the appropriate tool FIRST. NEVER answer based on conversation history or memory.\n2. **NO DATA INVENTION**: If a tool returns \"No data found\" or null values, YOU MUST SAY \"I cannot find data for this date\" or \"No data available\". Do NOT guess, estimate, or invent numbers.\n3. **VISION LIMITATIONS**: When analyzing images, if unclear or unreadable, say \"I cannot identify the food in this image\". Do NOT guess ingredients you do not see.\n4. **EXPLICIT UNCERTAINTY**: If you're unsure whether data exists, call the tool to check. Say \"Let me check your data\" rather than guessing.\n\nGuidelines:\n- Be concise and data-driven\n- When user wants to log something (diet, supplement, etc), use the appropriate tool\n- Provide actionable insights based ONLY on retrieved data\n- Support both English and Chinese\n\nCONVERSATIONAL CONTEXT HANDLING:\n- When user gives vague confirmation replies like \"好的，可以记录\" / \"ok, log it\" / \"yes, record that\":\n  1. FIRST check the conversation history to see what they were discussing\n  2. If they mentioned food/diet in recent messages, extract the details and call `log_diet` with:\n     - description: the food items they mentioned\n     - meal_type: infer from context (breakfast/lunch/dinner/snack)\n     - target_date: today unless specified otherwise\n  3. If you cannot extract clear details, politely ask: \"请问要记录什么内容？可以告诉我具体吃了什么吗？\"\n- NEVER return empty responses. If unsure what to do, ask a clarifying question.\n\nWEB SEARCH USAGE:\n- You have access to real-time web search via `search_web`.\n- USE IT WHEN:\n  1. User asks for \"latest\" research, news, or biohacking trends.\n  2. You need to verify external facts (e.g. \"benefits of berberine\").\n  3. User specifically asks to check online.\n- DO NOT USE IT WHEN:\n  1. User asks for PERSONAL data (steps, sleep). Use `health_read` tools.\n\nAvailable data sources:\n- Garmin health metrics (sleep, steps, heart rate, etc.)\n- Manual logs (diet, supplements, fasting, body feelings)\n- Real-time Web Search\n- Obsidian daily notes (can be synced)\n\n5. **ACTION COMMANDS**: If the user asks to \"sync\", \"update\", or \"fetch\" data, you MUST call the corresponding tool (e.g., `sync_garmin`). Do NOT say \"done\" without calling the tool. If the tool call fails or you cannot find the tool, report the error.\n\nIMPORTANT: Today's date is 2026-02-06 11:23:32 (CST). When logging data without a specified date, use today's date.\n\n=== USER HEALTH PROTOCOLS ===\n# User Health Profile & Bio-Hacking Protocols\n\n## 1. 核心画像 (User Persona)\n- **Role:** Tech Executive / Programmer / Bio-hacker.\n- **Mindset:** Data-driven (Garmin user), Focus on HRV/Sleep/Performance, High Agency.\n- **Family:** Married (Alison), Twin sons (9yo).\n- **Current Status:** High cognitive load, High physical activity volume.\n\n## 2. 生理状态与伤病管理 (Physiological Status)\n\n### A. 肌肉骨骼系统 (Musculoskeletal)\n* **右脚 (Chronic):** 副足舟骨 (Accessory Navicular).\n    * *Status:* 稳定，偶有隐痛。\n    * *Trigger:* 硬地徒步 > 10km。\n    * *Protocol:* 运动后冰敷 10min；严禁高冲击跑跳；椭圆机为主。\n* **左脚 (Acute):** 足弓内侧代偿性劳损 (Compensatory Strain).\n    * *Cause:* 长期避让右脚痛点导致的重心偏移。\n    * *Protocol:* 足底筋膜放松 (网球滚压)；徒步需使用足弓支撑鞋垫。\n* **胸廓/呼吸 (Recurrent):** 假性缺氧/胸闷 (Chest Tightness).\n    * *Mechanism:* 机械性紧张 (胸肌/背肌过度充血锁死胸廓) + 神经性兴奋 (酒精反弹/Cortisol).\n    * *Not Cardiac:* 已排除心脏问题。\n    * *Protocol:* 门框拉伸 (胸小肌)；W字伸展；弹力带外旋 (反手)；早起淡盐水 (防低血压)。\n\n### B. 神经与代谢系统 (Neuro-Metabolic)\n* **酒精敏感度:** 高。易引发 GABA Rebound (次日焦虑/胸闷/呼吸急促)。\n* **血糖敏感度:** 关注胰岛素抵抗；有酒后低血糖风险。\n* **睡眠特征:** 深睡能力强，但入睡易受高强度训练后的 CNS 兴奋干扰。\n\n## 3. 运动偏好与执行 (Training Protocols)\n\n### A. 力量训练 (Strength)\n* **Upper Body Focus:**\n    * *Pull:* 引体向上 (GTG 模式，高容量 200+/week)。\n    * *Push:* 卧推 (大重量/高容量，e.g., 70kg x 60 reps)。\n* **Constraint:** 力量训练后必须进行反向拉伸 (外旋)，防止圆肩导致的胸闷。\n\n### B. 有氧训练 (Cardio)\n* **Primary Tool:** 椭圆机 (Elliptical).\n* **Zone Strictness:** 严格 Zone 2 (130-140 bpm).\n* **Anti-Glycolytic:** 断食日禁止 Zone 4 冲刺，防止肌肉分解和皮质醇飙升。\n\n## 4. 饮食与断食策略 (Nutrition & Fasting)\n\n### A. 基础饮食 (Base Diet)\n* **Style:** Low Carb, High Protein, Bio-available focus.\n* **Monday Protocol:** 用于周末“重置”。\n    * *Mode:* PSMF (Protein Sparing Modified Fast) if heavy lifted previous day.\n    * *Menu:* Lunch (Protein Powder + 1 Egg) + Dinner (Tuna Salad/Light Protein). Total ~600-800 kcal.\n\n### B. 断食决策树 (Fasting Decision Logic)\n* `IF (Yesterday == Heavy_Lifting OR Today == High_Stress/Chest_Tightness)`:\n    * **Execute:** PSMF (中午补充纯蛋白，安抚皮质醇，修补肌肉).\n* `IF (Yesterday == Rest/Cheat_Day AND Today == Low_Stress)`:\n    * **Execute:** OMAD (只吃晚餐，追求深度自噬).\n* `IF (Sick OR Inflammation_High)`:\n    * **Execute:** Water Fast (只喝水/盐水).\n\n## 5. 补剂方案 (Supplement Stack)\n\n* **Daily:** Fish Oil (Omega-3), Vitamin B Complex (Energy/Nerve).\n* **Sleep/Recovery:** Magnesium (Glycinate/Citrate) - **必须睡前摄入**，防止肌肉痉挛和助眠。\n* **Metabolic Control:** Berberine (小檗碱).\n    * *Rule:* 随高碳水餐服用。\n    * *Warning:* **禁止**在饮酒时或饮酒前服用 (低血糖风险)。饮酒日仅限午餐服用。\n* **Hydration:** 早起一杯**海盐水** (必做，特别是断食日)。\n\n## 6. 酒精防御协议 (Alcohol Defense Protocol - SOP)\n\n* **Objective:** Minimize metabolic damage & GABA rebound.\n* **Pre-Game (-1 Hour):**\n    * Take **NAC** (600-1200mg).\n    * Eat Protein/Fat base.\n    * **NO Berberine** (Risk of hypoglycemia shock).\n* **In-Game:**\n    * Drink: Clear Spirits / Dry Wine / Soda water mix.\n    * Avoid: Sugar / Cocktails / Beer.\n    * Food: Meat & Green Veggies only. No Rice/Noodles.\n* **Post-Game:**\n    * Hydrate + Magnesium.\n\n## 7. 办公环境工学 (Ergonomics)\n\n* **Monitor Height:** 视线平视屏幕**上边框** (Top Bezel)，禁止仰视。\n* **Monitor Distance:** 一臂距离 (Fingertip touch).\n* **Scaling:** 字体放大 (125%+)，避免探头 (Forward Head Posture).\n* **Routine:** 每小时做 W-Raise 激活菱形肌。\n"
    },
    {
      "role": "user",
      "content": "今天睡得怎么样？"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_daily_detailed_stats",
        "description": "Get a comprehensive ONE-DAY SUMMARY (Metrics + Activity + Log Counts). Use for 'how was my day'. Do NOT use for filtering specific logs (use get_manual_history).",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string",
              "description": "YYYY-MM-DD"
            }
          },
          "required": [
            "target_date"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_metric_history",
        "description": "**USE THIS when user asks about time-based trends**: 'past X days/weeks/months', 'recent changes', 'last year', 'how has X changed', 'X trend over time'. Returns analyzed trends with statistics for time ranges >7 days, raw data for ≤7 days. Supported metrics: rhr (resting heart rate), hrv, sleep, stress, steps, heart_rate, weight. Example: user asks 'past 2 months RHR' → call this with metric_type='rhr', start_date=60 days ago, end_date=today.",
        "parameters": {
          "type": "object",
          "properties": {
            "metric_type": {
              "type": "string",
              "description": "Metric name: rhr, hrv, sleep, stress, steps, heart_rate, weight"
            },
            "start_date": {
              "type": "string",
              "description": "Start date YYYY-MM-DD (calculate from user's time range, e.g. 'past 2 months' = 60 days ago)"
            },
            "end_date": {
              "type": "string",
              "description": "End date YYYY-MM-DD (typically today)"
            }
          },
          "required": [
            "metric_type",
            "start_date",
            "end_date"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_activity_history",
        "description": "Get list of workouts/activities in a date range.",
        "parameters": {
          "type": "object",
          "properties": {
            "start_date": {
              "type": "string",
              "description": "YYYY-MM-DD"
            },
            "end_date": {
              "type": "string",
              "description": "YYYY-MM-DD"
            }
          },
          "required": [
            "start_date",
            "end_date"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_aggregated_analysis",
        "description": "**REQUIRED for time-range questions**: When user asks 'past X days/weeks/months/years', 'recent trend', 'change over time', 'how has X changed', use THIS tool (not get_metric_history). Returns analyzed trends with statistics, yearly comparisons, and 30-day rolling averages. Examples: 'past 2 months RHR', 'HRV trend this year', 'sleep quality last 90 days'.",
        "parameters": {
          "type": "object",
          "properties": {
            "start_date": {
              "type": "string",
              "description": "Start date YYYY-MM-DD (optional, defaults to 2 years ago)"
            },
            "end_date": {
              "type": "string",
              "description": "End date YYYY-MM-DD (optional, defaults to today)"
            },
            "metrics": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Metrics to analyze: ['rhr', 'hrv', 'sleep', 'stress', 'steps']. If omitted, analyzes all."
            }
          },
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_manual_history",
        "description": "query manual logs (diet, alcohol, etc) over a range.",
        "parameters": {
          "type": "object",
          "properties": {
            "start_date": {
              "type": "string",
              "description": "YYYY-MM-DD"
            },
            "end_date": {
              "type": "string",
              "description": "YYYY-MM-DD"
            },
            "category": {
              "type": "string",
              "enum": [
                "diet",
                "alcohol",
                "supplements",
                "feelings",
                "fasting",
                "all"
              ],
              "description": "Category of logs to retrieve"
            }
          },
          "required": [
            "start_date",
            "end_date"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "log_diet",
        "description": "Log food/meal.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            },
            "description": {
              "type": "string"
            },
            "meal_type": {
              "type": "string",
              "enum": [
                "breakfast",
                "lunch",
                "dinner",
                "snack"
              ]
            },
            "time": {
              "type": "string",
              "description": "HH:MM (optional)"
            }
          },
          "required": [
            "target_date",
            "description"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "log_alcohol",
        "description": "Log alcohol.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            },
            "alcohol_type": {
              "type": "string"
            },
            "amount": {
              "type": "string"
            },
            "time": {
              "type": "string",
              "description": "HH:MM (optional)"
            }
          },
          "required": [
            "target_date",
            "alcohol_type",
            "amount"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "log_supplement",
        "description": "Log supplement.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "dosage": {
              "type": "string"
            },
            "time": {
              "type": "string",
              "description": "HH:MM (optional)"
            }
          },
          "required": [
            "target_date",
            "name",
            "dosage"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "log_feeling",
        "description": "Log body feeling or symptom.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            },
            "feeling_type": {
              "type": "string"
            },
            "severity": {
              "type": "integer",
              "description": "1-10"
            },
            "description": {
              "type": "string"
            },
            "time": {
              "type": "string",
              "description": "HH:MM (optional)"
            }
          },
          "required": [
            "target_date",
            "feeling_type",
            "severity",
            "description"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "log_fasting",
        "description": "Log fasting mode.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            },
            "mode": {
              "type": "string",
              "description": "OMAD, PSMF, etc"
            }
          },
          "required": [
            "target_date",
            "mode"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "sync_obsidian",
        "description": "Sync Obsidian note.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string"
            }
          },
          "required": [
            "target_date"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "sync_garmin",
        "description": "Action to synchronize the latest health data from Garmin Connect. You MUST use this tool when the user asks to 'sync', 'update', or 'fetch' data. Do not assume data is already up-to-date.",
        "parameters": {
          "type": "object",
          "properties": {
            "target_date": {
              "type": "string",
              "description": "YYYY-MM-DD (optional, default to today)"
            }
          },
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_health_insights",
        "description": "Get advanced health insights, correlations, and trends (e.g., alcohol impact on sleep, heart rate trends).",
        "parameters": {
          "type": "object",
          "properties": {
            "analysis_type": {
              "type": "string",
              "description": "Type of analysis: 'recovery_correlations' (alcohol/activity impact), 'fitness_trends' (RHR/fitness), 'lifestyle_impact' (fasting/supplements)."
            },
            "lookback_days": {
              "type": "integer",
              "description": "Number of days to analyze (default 30, recommend 30-90 for trends)."
            }
          },
          "required": [
            "analysis_type"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "analyze_driver",
        "description": "Analyze if a specific factor (Driver) impacts a health metric (Target). e.g., 'Does Magnesium improve sleep?'.",
        "parameters": {
          "type": "object",
          "properties": {
            "driver_metric": {
              "type": "string",
              "description": "The cause/driver column. Examples: 'alcohol_units', 'stress', 'steps', 'fasting_mode', 'has_magnesium', 'has_alcohol'."
            },
            "target_metric": {
              "type": "string",
              "description": "The effect/target column. Examples: 'sleep', 'rhr', 'hrv', 'body_battery'."
            },
            "method": {
              "type": "string",
              "enum": [
                "correlation",
                "group_compare"
              ],
              "description": "Use 'correlation' for continuous values (alcohol units vs sleep) or 'group_compare' for events (Magnesium YES/NO vs Sleep)."
            },
            "lookback_days": {
              "type": "integer",
              "description": "Days to analyze (default 30)."
            }
          },
          "required": [
            "driver_metric",
            "target_metric",
            "method"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "search_web",
        "description": "Search the web for real-time information, latest scientific research, or biohacker experiences.",
        "parameters": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Search query (e.g. 'latest study on NAD+ effects')"
            }
          },
          "required": [
            "query"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "execute_shell",
        "description": "Execute a shell command (zsh) in a persistent session. Use for system questions, file checks, or running scripts. If user asks 'how to X', providing a numbered list, you can use this to execute the user's choice.",
        "parameters": {
          "type": "object",
          "properties": {
            "command": {
              "type": "string",
              "description": "Command to execute (e.g. 'ls -la', 'git status', 'python3 script.py')"
            },
            "timeout": {
              "type": "number",
              "description": "Timeout in seconds to wait for output (default 2.0). Increase for long-running commands like 'top' (to get a snapshot) or 'sleep 5'.",
              "default": 2.0
            }
          },
          "required": [
            "command"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "download_file",
        "description": "Upload a file from the server to Slack. Use when user wants to see a log file or config.",
        "parameters": {
          "type": "object",
          "properties": {
            "file_path": {
              "type": "string",
              "description": "Absolute path to the file"
            }
          },
          "required": [
            "file_path"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "save_file",
        "description": "Save content to a file on the server. Use to create/edit configs.",
        "parameters": {
          "type": "object",
          "properties": {
            "file_path": {
              "type": "string",
              "description": "Target absolute path"
            },
            "content": {
              "type": "string",
              "description": "Text content to save"
            },
            "overwrite": {
              "type": "boolean",
              "description": "Allow overwriting existing file"
            }
          },
          "required": [
            "file_path",
            "content"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_system_status",
        "description": "Get a visual dashboard of system health (CPU, Memory, Disk, Top Processes).",
        "parameters": {
          "type": "object",
          "properties": {},
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "kill_process",
        "description": "Terminate a process by PID.",
        "parameters": {
          "type": "object",
          "properties": {
            "pid": {
              "type": "integer",
              "description": "Process ID"
            },
            "signal_type": {
              "type": "string",
              "enum": [
                "SIGTERM",
                "SIGKILL"
              ],
              "default": "SIGTERM"
            }
          },
          "required": [
            "pid"
          ]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "get_process_list",
        "description": "List running processes with optional name filtering.",
        "parameters": {
          "type": "object",
          "properties": {
            "filter_name": {
              "type": "string",
              "description": "Filter by process name (case-insensitive)"
            },
            "limit": {
              "type": "integer",
              "default": 15
            }
          },
          "required": []
        }
      }
    }
  ],
  "tool_choice": "auto"
}