{
  "model": "google/gemini-flash-1.5-exp",
  "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 \"\u597d\u7684\uff0c\u53ef\u4ee5\u8bb0\u5f55\" / \"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: \"\u8bf7\u95ee\u8981\u8bb0\u5f55\u4ec0\u4e48\u5185\u5bb9\uff1f\u53ef\u4ee5\u544a\u8bc9\u6211\u5177\u4f53\u5403\u4e86\u4ec0\u4e48\u5417\uff1f\"\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-05 20:43:28 (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. \u6838\u5fc3\u753b\u50cf (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. \u751f\u7406\u72b6\u6001\u4e0e\u4f24\u75c5\u7ba1\u7406 (Physiological Status)\n\n### A. \u808c\u8089\u9aa8\u9abc\u7cfb\u7edf (Musculoskeletal)\n* **\u53f3\u811a (Chronic):** \u526f\u8db3\u821f\u9aa8 (Accessory Navicular).\n    * *Status:* \u7a33\u5b9a\uff0c\u5076\u6709\u9690\u75db\u3002\n    * *Trigger:* \u786c\u5730\u5f92\u6b65 > 10km\u3002\n    * *Protocol:* \u8fd0\u52a8\u540e\u51b0\u6577 10min\uff1b\u4e25\u7981\u9ad8\u51b2\u51fb\u8dd1\u8df3\uff1b\u692d\u5706\u673a\u4e3a\u4e3b\u3002\n* **\u5de6\u811a (Acute):** \u8db3\u5f13\u5185\u4fa7\u4ee3\u507f\u6027\u52b3\u635f (Compensatory Strain).\n    * *Cause:* \u957f\u671f\u907f\u8ba9\u53f3\u811a\u75db\u70b9\u5bfc\u81f4\u7684\u91cd\u5fc3\u504f\u79fb\u3002\n    * *Protocol:* \u8db3\u5e95\u7b4b\u819c\u653e\u677e (\u7f51\u7403\u6eda\u538b)\uff1b\u5f92\u6b65\u9700\u4f7f\u7528\u8db3\u5f13\u652f\u6491\u978b\u57ab\u3002\n* **\u80f8\u5ed3/\u547c\u5438 (Recurrent):** \u5047\u6027\u7f3a\u6c27/\u80f8\u95f7 (Chest Tightness).\n    * *Mechanism:* \u673a\u68b0\u6027\u7d27\u5f20 (\u80f8\u808c/\u80cc\u808c\u8fc7\u5ea6\u5145\u8840\u9501\u6b7b\u80f8\u5ed3) + \u795e\u7ecf\u6027\u5174\u594b (\u9152\u7cbe\u53cd\u5f39/Cortisol).\n    * *Not Cardiac:* \u5df2\u6392\u9664\u5fc3\u810f\u95ee\u9898\u3002\n    * *Protocol:* \u95e8\u6846\u62c9\u4f38 (\u80f8\u5c0f\u808c)\uff1bW\u5b57\u4f38\u5c55\uff1b\u5f39\u529b\u5e26\u5916\u65cb (\u53cd\u624b)\uff1b\u65e9\u8d77\u6de1\u76d0\u6c34 (\u9632\u4f4e\u8840\u538b)\u3002\n\n### B. \u795e\u7ecf\u4e0e\u4ee3\u8c22\u7cfb\u7edf (Neuro-Metabolic)\n* **\u9152\u7cbe\u654f\u611f\u5ea6:** \u9ad8\u3002\u6613\u5f15\u53d1 GABA Rebound (\u6b21\u65e5\u7126\u8651/\u80f8\u95f7/\u547c\u5438\u6025\u4fc3)\u3002\n* **\u8840\u7cd6\u654f\u611f\u5ea6:** \u5173\u6ce8\u80f0\u5c9b\u7d20\u62b5\u6297\uff1b\u6709\u9152\u540e\u4f4e\u8840\u7cd6\u98ce\u9669\u3002\n* **\u7761\u7720\u7279\u5f81:** \u6df1\u7761\u80fd\u529b\u5f3a\uff0c\u4f46\u5165\u7761\u6613\u53d7\u9ad8\u5f3a\u5ea6\u8bad\u7ec3\u540e\u7684 CNS \u5174\u594b\u5e72\u6270\u3002\n\n## 3. \u8fd0\u52a8\u504f\u597d\u4e0e\u6267\u884c (Training Protocols)\n\n### A. \u529b\u91cf\u8bad\u7ec3 (Strength)\n* **Upper Body Focus:**\n    * *Pull:* \u5f15\u4f53\u5411\u4e0a (GTG \u6a21\u5f0f\uff0c\u9ad8\u5bb9\u91cf 200+/week)\u3002\n    * *Push:* \u5367\u63a8 (\u5927\u91cd\u91cf/\u9ad8\u5bb9\u91cf\uff0ce.g., 70kg x 60 reps)\u3002\n* **Constraint:** \u529b\u91cf\u8bad\u7ec3\u540e\u5fc5\u987b\u8fdb\u884c\u53cd\u5411\u62c9\u4f38 (\u5916\u65cb)\uff0c\u9632\u6b62\u5706\u80a9\u5bfc\u81f4\u7684\u80f8\u95f7\u3002\n\n### B. \u6709\u6c27\u8bad\u7ec3 (Cardio)\n* **Primary Tool:** \u692d\u5706\u673a (Elliptical).\n* **Zone Strictness:** \u4e25\u683c Zone 2 (130-140 bpm).\n* **Anti-Glycolytic:** \u65ad\u98df\u65e5\u7981\u6b62 Zone 4 \u51b2\u523a\uff0c\u9632\u6b62\u808c\u8089\u5206\u89e3\u548c\u76ae\u8d28\u9187\u98d9\u5347\u3002\n\n## 4. \u996e\u98df\u4e0e\u65ad\u98df\u7b56\u7565 (Nutrition & Fasting)\n\n### A. \u57fa\u7840\u996e\u98df (Base Diet)\n* **Style:** Low Carb, High Protein, Bio-available focus.\n* **Monday Protocol:** \u7528\u4e8e\u5468\u672b\u201c\u91cd\u7f6e\u201d\u3002\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. \u65ad\u98df\u51b3\u7b56\u6811 (Fasting Decision Logic)\n* `IF (Yesterday == Heavy_Lifting OR Today == High_Stress/Chest_Tightness)`:\n    * **Execute:** PSMF (\u4e2d\u5348\u8865\u5145\u7eaf\u86cb\u767d\uff0c\u5b89\u629a\u76ae\u8d28\u9187\uff0c\u4fee\u8865\u808c\u8089).\n* `IF (Yesterday == Rest/Cheat_Day AND Today == Low_Stress)`:\n    * **Execute:** OMAD (\u53ea\u5403\u665a\u9910\uff0c\u8ffd\u6c42\u6df1\u5ea6\u81ea\u566c).\n* `IF (Sick OR Inflammation_High)`:\n    * **Execute:** Water Fast (\u53ea\u559d\u6c34/\u76d0\u6c34).\n\n## 5. \u8865\u5242\u65b9\u6848 (Supplement Stack)\n\n* **Daily:** Fish Oil (Omega-3), Vitamin B Complex (Energy/Nerve).\n* **Sleep/Recovery:** Magnesium (Glycinate/Citrate) - **\u5fc5\u987b\u7761\u524d\u6444\u5165**\uff0c\u9632\u6b62\u808c\u8089\u75c9\u631b\u548c\u52a9\u7720\u3002\n* **Metabolic Control:** Berberine (\u5c0f\u6a97\u78b1).\n    * *Rule:* \u968f\u9ad8\u78b3\u6c34\u9910\u670d\u7528\u3002\n    * *Warning:* **\u7981\u6b62**\u5728\u996e\u9152\u65f6\u6216\u996e\u9152\u524d\u670d\u7528 (\u4f4e\u8840\u7cd6\u98ce\u9669)\u3002\u996e\u9152\u65e5\u4ec5\u9650\u5348\u9910\u670d\u7528\u3002\n* **Hydration:** \u65e9\u8d77\u4e00\u676f**\u6d77\u76d0\u6c34** (\u5fc5\u505a\uff0c\u7279\u522b\u662f\u65ad\u98df\u65e5)\u3002\n\n## 6. \u9152\u7cbe\u9632\u5fa1\u534f\u8bae (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. \u529e\u516c\u73af\u5883\u5de5\u5b66 (Ergonomics)\n\n* **Monitor Height:** \u89c6\u7ebf\u5e73\u89c6\u5c4f\u5e55**\u4e0a\u8fb9\u6846** (Top Bezel)\uff0c\u7981\u6b62\u4ef0\u89c6\u3002\n* **Monitor Distance:** \u4e00\u81c2\u8ddd\u79bb (Fingertip touch).\n* **Scaling:** \u5b57\u4f53\u653e\u5927 (125%+)\uff0c\u907f\u514d\u63a2\u5934 (Forward Head Posture).\n* **Routine:** \u6bcf\u5c0f\u65f6\u505a W-Raise \u6fc0\u6d3b\u83f1\u5f62\u808c\u3002\n"
    },
    {
      "role": "user",
      "content": "\u641c\u7d22\u4e00\u4e0b\u6700\u65b0\u7684NAD+\u7814\u7a76"
    }
  ],
  "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 \u22647 days. Supported metrics: rhr (resting heart rate), hrv, sleep, stress, steps, heart_rate, weight. Example: user asks 'past 2 months RHR' \u2192 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"
}