name: calendar-ops-skill description: > 当用户要对真实日历数据做查询或增删改时触发:看今天/本周安排、查冲突、建会议、改时间、删日程。典型说法"我明天几点开会"、"帮我约 xx"、"schedule a meeting"。不用于:对话里口头提到时间或倒计时(→直接回答)、周期性后台任务如"每天 9 点跑脚本"(→schedule-ops-skill)。 tools: [CalendarQuery, CalendarMutate]
日历操作技能
工具清单
| 工具 | 职责 | 只读 |
|---|---|---|
CalendarQuery |
查询日历源 / 日程项目(mode: list-sources / list-items / get-event 等) |
是 |
CalendarMutate |
创建 / 更新 / 删除日程(kind: event 或 reminder) |
否 |
加载:全部为 deferred 工具,调用前须先
ToolSearch(names: "CalendarQuery,CalendarMutate")激活 schema。
决策流程:用户想做什么?
路径 A — 查看日程 / 判断是否有空
- 先拿时间基准:用
Bash执行date '+%Y-%m-%dT%H:%M:%S%z'获取当前时刻和时区。 为什么?因为"今天""下周二"这类相对时间必须锚定到具体时区才有意义——"上午 10 点"对北京和纽约的人是完全不同的时刻,ISO 8601 不带时区偏移会导致静默错位。 - 查日程:用
CalendarQuery(mode:list-items),传入rangeStart/rangeEnd(ISO 8601 必须带时区偏移,如+08:00)。 如果用户只说"看看今天的安排",范围就是今天 00:00:00 到 23:59:59;如果说"这周有什么",范围扩展到整周。宁可查宽一点也不要漏掉边界上的事件。 - 按时间排序展示,标注冲突和空闲段。用户问"我有空吗"时,从查询结果反推空闲区间即可。
- 如果跨多个日历源,可传
sourceIds过滤特定日历,避免混入不相关的日程(如节假日日历)。
路径 B — 创建日程或提醒
为什么创建前必须检测冲突?因为双重预订浪费所有人的时间,还让用户显得不专业。
- 获取 sourceId:先
CalendarQuery(mode:list-sources)拿到可用日历源列表。 为什么?创建时sourceId是必填字段,凭空猜测 ID 必定失败。如果对话上文已经获取过 sourceId 且确信仍有效,可以复用。 - 查冲突:用
CalendarQuery(mode:list-items)查目标时间段是否已有安排。 - 有冲突 → 告知用户冲突详情,建议替代时段。绝不自作主张跳过冲突直接创建。 好的做法是推荐冲突前后最近的空闲段,让用户一键选择。
- 无冲突 → 用
CalendarMutate(action:create)创建。kind二选一:event(有明确开始/结束时间的日程)或reminder(提醒事项,更适合待办性质的内容)。
路径 C — 修改日程
- 先查到目标:用
CalendarQuery(mode:list-items)搜索,确认itemId。 为什么?用户说"把下午的会改到 3 点",你需要先精确定位到具体哪条日程,模糊匹配可能改错条目。 - 如果涉及时间变更,检查新时间段是否有冲突——理由同路径 B。
- 用
CalendarMutate(action:update),传itemId+ 要改的字段。只传需要改的字段,不要把所有字段重新提交。
路径 D — 删除日程
- 先查到目标,确认
itemId。 - 向用户确认后再执行
CalendarMutate(action:delete)。 删除不可逆,必须让用户明确同意。如果有多条相似日程,列出候选让用户选择。
路径 E — 标记完成/未完成
用 CalendarMutate(action: toggle-completed),传 itemId + completed 布尔值。主要适用于 reminder 类型的日程项。
常见陷阱
时区混乱(最高频错误)
所有时间必须使用 ISO 8601 且带时区偏移(如 +08:00、-05:00)。永远先用 Bash 执行 date 确定当前时间和时区,不要假设 UTC 或任何默认值。一个不带偏移的 2026-03-20T10:00:00 会被不同系统解读为不同时刻,导致日程出现在错误的时间。
相对时间引用
"下周二""后天下午""这个月底"——先用 Bash 执行 date 获取当前时间,再自己计算出绝对时间。注意"下周二"在周一和周三说出来指的是不同的日期;跨月、跨年边界也容易算错。遇到含糊表达时主动向用户确认。
忘记查 sourceId
CalendarMutate 的 create 动作要求 sourceId。不先调 list-sources 就创建 = 必然报错。用户可能有多个日历源(工作、个人、共享),要选对目标日历。
全天事件
全天事件需要设置 allDay: true。起止时间仍需提供,用当天 00:00:00 到 23:59:59(带时区偏移)。
查询范围过窄
用户说"最近有什么安排"时不要只查当天。根据语境适当扩大范围(未来 3-7 天),然后按日分组展示,让用户一目了然。
多条相似日程
用户说"删掉那个会议"但查询结果有多条匹配时,必须列出候选让用户选择,不要猜测。猜错删错的代价远高于多问一句。修改场景同理。
创建时遗漏关键信息
用户说"帮我约个会"但没说时间、地点、参会人——不要用默认值填充,主动追问缺失的关键字段。一个不完整的日程比没有日程更容易造成混乱。
工具速查
| 工具 | 用途 |
|---|---|
CalendarQuery |
两种模式:list-sources 查日历源列表、list-items 按时间范围查日程项 |
CalendarMutate |
四种动作:create 创建、update 修改、delete 删除、toggle-completed 切换完成 |
CalendarMutate 创建时的 kind 字段:event(日程事件)或 reminder(提醒事项)。