[
  {
    "type": "function",
    "function": {
      "name": "read_file",
      "description": "读取/搜索/抽取 UTF-8 文本文件。type=read/search/extract，仅单文件操作。",
      "parameters": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "description": "文件路径：工作区内请用相对路径，工作区外可用绝对路径。"
          },
          "type": {
            "type": "string",
            "enum": ["read", "search", "extract"],
            "description": "读取模式：read=按行读取；search=在文件内搜索；extract=按行段抽取。"
          },
          "max_chars": {
            "type": "integer",
            "description": "返回内容最大字符数，超出将截断。"
          },
          "start_line": {
            "type": "integer",
            "description": "[read] 起始行号（1-based）。"
          },
          "end_line": {
            "type": "integer",
            "description": "[read] 结束行号（>= start_line）。"
          },
          "query": {
            "type": "string",
            "description": "[search] 搜索关键词。"
          },
          "max_matches": {
            "type": "integer",
            "description": "[search] 最多返回多少条命中窗口。"
          },
          "context_before": {
            "type": "integer",
            "description": "[search] 命中行向上追加行数。"
          },
          "context_after": {
            "type": "integer",
            "description": "[search] 命中行向下追加行数。"
          },
          "case_sensitive": {
            "type": "boolean",
            "description": "[search] 是否区分大小写。"
          },
          "segments": {
            "type": "array",
            "description": "[extract] 需要抽取的行区间数组。",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "description": "片段标签（可选）。"
                },
                "start_line": {
                  "type": "integer",
                  "description": "起始行号（>=1）。"
                },
                "end_line": {
                  "type": "integer",
                  "description": "结束行号（>= start_line）。"
                }
              },
              "required": ["start_line", "end_line"]
            },
            "minItems": 1
          }
        },
        "required": ["path", "type"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "edit_file",
      "description": "在文件中执行精确字符串替换；建议先用 read_file 精确复制 old_string。",
      "parameters": {
        "type": "object",
        "properties": {
          "file_path": {
            "type": "string",
            "description": "文件路径：工作区内请用相对路径，工作区外可用绝对路径。"
          },
          "old_string": {
            "type": "string",
            "description": "要替换的旧文本（必须与文件内容精确匹配）。"
          },
          "new_string": {
            "type": "string",
            "description": "替换的新文本（必须不同于 old_string）。"
          }
        },
        "required": ["file_path", "old_string", "new_string"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "web_search",
      "description": "网络搜索（Tavily）。用于外部资料或最新信息检索。",
      "parameters": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "搜索关键词（不要包含时间范围）。"
          },
          "max_results": {
            "type": "integer",
            "description": "最大返回结果数。"
          },
          "topic": {
            "type": "string",
            "enum": ["general", "news", "finance"],
            "description": "搜索主题类型。"
          },
          "time_range": {
            "type": "string",
            "enum": ["day", "week", "month", "year", "d", "w", "m", "y"],
            "description": "相对时间范围（与 days / start_date+end_date 互斥）。"
          },
          "days": {
            "type": "integer",
            "description": "最近 N 天（仅 topic=news 可用）。"
          },
          "start_date": {
            "type": "string",
            "description": "开始日期 YYYY-MM-DD（必须与 end_date 同时提供）。"
          },
          "end_date": {
            "type": "string",
            "description": "结束日期 YYYY-MM-DD（必须与 start_date 同时提供）。"
          },
          "country": {
            "type": "string",
            "description": "国家过滤，仅 topic=general 可用（英文小写国名）。"
          }
        },
        "required": ["query"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "extract_webpage",
      "description": "网页内容提取（Tavily）。mode=read 直接返回内容，mode=save 保存为文件。",
      "parameters": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["read", "save"],
            "description": "read=直接返回内容；save=写入文件。"
          },
          "url": {
            "type": "string",
            "description": "目标网页 URL。"
          },
          "target_path": {
            "type": "string",
            "description": "[save] 保存路径：工作区内请用相对路径，工作区外可用绝对路径。必须是 .md 文件。mode=save 必填。"
          }
        },
        "required": ["mode", "url"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "run_command",
      "description": "在当前终端环境执行一次性命令（非交互式）。",
      "parameters": {
        "type": "object",
        "properties": {
          "command": {
            "type": "string",
            "description": "要执行的命令。"
          },
          "timeout": {
            "type": "number",
            "description": "超时时间（秒），必填。"
          },
          "working_dir": {
            "type": "string",
            "description": "工作目录：工作区内请用相对路径，工作区外可用绝对路径。"
          }
        },
        "required": ["command", "timeout"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "search_workspace",
      "description": "在本地目录内搜索文件名或文件内容（跨文件）。仅返回摘要。",
      "parameters": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["file", "content"],
            "description": "file=搜索文件名；content=跨文件搜索内容。"
          },
          "query": {
            "type": "string",
            "description": "搜索关键词或正则。"
          },
          "root": {
            "type": "string",
            "description": "搜索起点目录：工作区内请用相对路径，工作区外可用绝对路径。默认 '.'。"
          },
          "use_regex": {
            "type": "boolean",
            "description": "是否使用正则匹配（默认 false）。"
          },
          "case_sensitive": {
            "type": "boolean",
            "description": "是否区分大小写（默认 false）。"
          },
          "max_results": {
            "type": "integer",
            "description": "最大返回结果数（默认 20）。"
          },
          "max_matches_per_file": {
            "type": "integer",
            "description": "[content] 每个文件最多返回多少处匹配（默认 3）。"
          },
          "include_glob": {
            "type": "array",
            "description": "仅包含匹配这些 glob 的文件。",
            "items": { "type": "string" }
          },
          "exclude_glob": {
            "type": "array",
            "description": "排除匹配这些 glob 的文件。",
            "items": { "type": "string" }
          },
          "max_file_size": {
            "type": "integer",
            "description": "跳过超过该字节数的文件。"
          }
        },
        "required": ["mode", "query"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "read_mediafile",
      "description": "读取图片或视频文件并附加给模型。非媒体文件将拒绝。",
      "parameters": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "description": "媒体文件路径：工作区内请用相对路径，工作区外可用绝对路径。"
          }
        },
        "required": ["path"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "todo",
      "description": "管理用户的待办事项。支持创建、完成、删除和更新待办。可设置提醒时间，到提醒时间后系统会自动发送消息通知你提醒用户。\n查询待办请使用 recall 工具。",
      "parameters": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": ["add", "complete", "delete", "update"],
            "description": "操作类型。add=新增待办，complete=标记完成，delete=删除待办，update=更新待办内容或提醒时间。"
          },
          "content": {
            "type": "string",
            "description": "待办内容。add 时必填，update 时可选（不提供则保留原内容）。内容中必须使用明确的绝对日期，禁止使用「明天」「下周三」等相对时间表述。"
          },
          "id": {
            "type": "string",
            "description": "待办 ID，由系统自动生成。complete、delete、update 时必填，从 recall 工具的搜索结果中获取。add 时不需要提供。"
          },
          "remind_at": {
            "type": "string",
            "description": "提醒触发时间。设置提醒前必须先执行 date '+%Y-%m-%dT%H:%M:%S' 获取当前精确本地时间，再据此计算。使用本地时间不带时区后缀，格式如 2026-05-01T14:45:00，禁止使用带 Z 或 +08:00 的格式。仅 add 和 update 时有效。add 时可选，不提供则不设置提醒。update 时传 null 可取消已有提醒。"
          },
          "keywords": {
            "type": "array",
            "items": { "type": "string" },
            "description": "关键词数组，便于 recall 搜索匹配。add 和 update 时可选。"
          }
        },
        "required": ["action"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "remember",
      "description": "记录用户个人记忆。当用户表达了个人偏好、习惯、身份信息、人际关系、重要事件等值得记住的信息时调用。\n注意：不要记录无意义信息，例如用户的打招呼、让调低音量等一次性操作。\n待办事项请使用 todo 工具。",
      "parameters": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": ["add", "update", "delete"],
            "description": "操作类型：add=新增记忆，update=更新已有记忆，delete=删除记忆"
          },
          "type": {
            "type": "string",
            "enum": ["preference", "habit", "event", "identity", "relationship", "machine", "other"],
            "description": "记忆类型。preference=偏好喜欢什么不喜欢什么，habit=用户的生活习惯，event=过去需要记住的重要事件，identity=用户的身份信息，relationship=用户和其他人的关联，machine=本机电脑上的信息（如特定路径、脚本、配置等），other=其他"
          },
          "content": {
            "type": "string",
            "description": "记忆内容。add时必须提供。update时可选（不提供则保留原内容）。一律使用「用户」指代用户本人，禁止使用用户的名字、昵称或称呼。如「用户喜欢喝咖啡」而非「jojo喜欢喝咖啡」。"
          },
          "keywords": {
            "type": "array",
            "items": { "type": "string" },
            "description": "关键词数组，便于后续搜索匹配"
          },
          "id": {
            "type": "string",
            "description": "记忆ID。update和delete时必填"
          }
        },
        "required": ["action"]
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "recall",
      "description": "搜索用户个人记忆。当用户提问可能涉及个人偏好、历史或已知信息时使用。注意：简单操作如调音量、问天气不需要搜索。搜索结果自然融入回答，不要显式说'根据我的记忆'。",
      "parameters": {
        "type": "object",
        "properties": {
          "types": {
            "type": "array",
            "items": { "type": "string" },
            "description": "限定搜索的记忆类型，可选值：preference, habit, event, todo, identity, relationship, machine, other。不提供则搜索所有类型"
          },
          "query": {
            "type": "string",
            "description": "搜索关键词，在记忆内容和关键词中匹配"
          },
          "start_date": {
            "type": "string",
            "description": "起始日期（ISO格式，如2026-01-01），可选"
          },
          "end_date": {
            "type": "string",
            "description": "结束日期（ISO格式，如2026-12-31），可选"
          },
          "max_results": {
            "type": "integer",
            "description": "最大返回数量，默认10"
          }
        },
        "required": []
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "set_identity",
      "description": "设置用户的身份信息和 AI 助手个性化配置。当用户表达以下意图时使用此工具，而不是 remember：\n- 希望 AI 助手叫什么名字\n- 希望被怎么称呼（用户的名字/昵称）\n- 希望 AI 助手用什么语气交流\n这三个配置会立即生效，影响后续所有对话。可以只更新其中一个字段。",
      "parameters": {
        "type": "object",
        "properties": {
          "assistant_name": {
            "type": "string",
            "description": "AI 助手的名字，如'小A'、'Jarvis'。可选。"
          },
          "user_name": {
            "type": "string",
            "description": "用户希望被称呼的名字，如'jojo'、'张总'。可选。"
          },
          "assistant_tone": {
            "type": "string",
            "description": "AI 助手的语气，可选值：友好、专业、幽默、简洁、温暖、正式。可选。"
          }
        },
        "required": []
      }
    }
  }
]
