# calendar +room-find

> **前置条件：** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md)。

针对一个或多个时间块查找/搜索可用会议室。会议室是日程的一种资源型参与人，不能脱离日程单独预定。

需要的 scopes: ["calendar:calendar.free_busy:read"]

## 适用场景

- 已知一个或多个待选时间块，需要查找可用会议室

## 命令

```bash
lark-cli calendar +room-find \
  --slot "2026-03-27T14:00:00+08:00~2026-03-27T15:00:00+08:00" \
  --slot "2026-03-27T16:00:00+08:00~2026-03-27T17:00:00+08:00" \
  --attendee-ids "ou_xxx,ou_yyy" \
  --city "北京" \
  --building "学清嘉创大厦B座" \
  --floor "F2" \
  --event-rrule "FREQ=DAILY;INTERVAL=1"
```

## 参数

| 参数 | 必填 | 说明 |
|------|------|------|
| `--slot <start~end>` | 是 | 期望查询的时间块，格式需遵循 `开始时间~结束时间`。若存在多个候选时间块，可重复传入此参数。 |
| `--city <text>` | 否 | 会议室所在城市强约束。**仅当**用户明确说出具体城市（如北京、上海）时才提取，**严禁**根据园区或楼宇名称自行联想或补全。 |
| `--building <text>` | 否 | 会议室所在楼宇强约束，承载城市以下、楼层以上的办公区/园区/楼栋描述。|
| `--floor <text>` | 否 | 仅用于筛选会议室所在楼层。应先做归一化，再传递规范值；例如 `2楼` / `二楼` / `2F` 统一为 `F2`。注意：此参数只筛选楼层，不可混入区域定位（如“A区”）或具体会议室号。 |
| `--room-name <text>` | 否 | 会议室名强约束。仅当用户明确提到会议室专名或会议室号（如“木星”“02”）时使用。应优先传递去后缀、去冗余后的规范名，例如 `木星会议室` → `木星`，`会议室 02` / `02会议室` → `02`。 |
| `--min-capacity <n>` | 否 | 会议室最小容纳人数。当用户明确参会人数或提出“至少容纳N人”等要求时，提取数字放入此参数，必须为正整数。 |
| `--max-capacity <n>` | 否 | 会议室最大容纳人数。用于过滤过大空间，必须为正整数。 |
| `--attendee-ids <id_list>` | 否 | 参会对象 ID 列表。支持用户 ID（`ou_` 前缀）和群组 ID（`oc_` 前缀），多个 ID 以逗号分隔。 |
| `--event-rrule <rrule>` | 否 | 重复日程的重复性规则，规则设置方式参考rfc5545。**【⚠️注意：系统绝对不支持 COUNT，如需限制重复次数，必须转为 UNTIL】**。示例值："FREQ=DAILY;INTERVAL=1" |
| `--timezone <tz>` | 否 | 对话中明确提及的预约日程所使用的时区（默认取用户设备时区，例如 `Asia/Shanghai`） |

## 规则

- 多个 `--slot` 会由 CLI 内部并发调用单时间块接口，再聚合成一次输出
- `+room-find` 的时间输入必须是**确定时间块**，不是时间区间搜索。
- 如果是重复性日程，必须校验返回中的 `reserve_until_time`（该会议室最晚可预约时间）是否覆盖 `event-rrule` 对应的重复范围。
- `--city` 仅在用户明确说出城市时才提取；不要仅凭 `望京办公室`、`漕河泾园区`、`南山办公室` 这类位置名自动补城市。
- 若已经提取了 `--city`，则 `--building` 中不要再重复携带城市前缀。例如用户说 `北京学清嘉创大厦B座` 时，应提取为 `--city "北京"` 与 `--building "学清嘉创大厦B座"`，不要把 `北京学清嘉创大厦B座` 原样整体传入 `--building`。
- 同一语义槽位只保留一个规范值。例如用户说“2楼”，应转换为 `--floor "F2"`；**禁止**同时传 `2楼 F2` 这类重复楼层信息。
- 参数归类顺序应为：`city/building/floor` > `floor + room-name` 复合表达 > `room-name`。若短词更像楼层/区域定位（如 `2L`、`2F`），优先落到 `--floor`，不要默认落到 `--room-name`。像 `学清2层` 这种表达，通常拆为 `--building "学清"` 与 `--floor "F2"`。
- 对会议室名要做轻量归一化：`木星会议室` 应提取为 `--room-name "木星"`；`会议室 02` / `02会议室` 应提取为 `--room-name "02"`。
- 对复合会议室号要优先拆分结构化信息：`F3-05` / `F5-07` / `3楼-08` 这类表达，若可稳定识别楼层与会议室号，应优先提取为 `--floor "F3"` + `--room-name "05"`、`--floor "F5"` + `--room-name "07"`、`--floor "F3"` + `--room-name "08"`，不要把整段直接作为 `--room-name`。
- 当提供了会议室搜索筛选条件时，返回结果也**不保证**与搜索词完全字面匹配。底层可能会结合邻近楼层做推荐，例如用户搜索 `2层`，即使 `2层` 没有空闲会议室，也可能返回相近的 `3层` 候选。这不应被误判为接口返回异常。

## 输出格式

**将返回的候选会议室整理为易读的结构化排版向用户展示。严禁将时间和会议室名称放在同一行展示，必须分行并使用编号列表呈现可用会议室，严禁揉成一团纯文本堆叠。**

```text
## 2026-03-27 周五

[选项 1] 14:00 - 15:00
  可用会议室：
  1. 学清嘉创大厦B座-F2-02🎦(7人)
  2. 学清嘉创大厦B座-F3-05🎦(11人)

💡 请回复您倾向的选项编号以及对应的会议室序号，我来为您完成预定。
```

> **AI 行为指导：**
> - **结构化展示时间块与会议室**：默认按“时间块 -> 会议室候选”的层级结构展示。**严禁将时间与会议室名称输出在同一行**。以清晰的分行列表呈现可用会议室，并直接询问用户意向。默认原样展示完整 `room_name`；不要擅自缩写、截断、改写，或仅提取楼层及会议室号替代完整名称。
> - **`room_name` 必须逐字透传**：展示给用户的会议室名称，必须直接使用 CLI/API 返回的 `room_name` 原值。禁止提取楼层、会议室号、容量、视频能力后重组成新的名称，禁止意译、缩写、去前缀、去后缀，或仅保留“便于阅读”的摘要名。
> - **重复日程要明确阻断原因与自动缩短**：若某候选会议室的 `reserve_until_time` 无法覆盖重复性日程，**必须**向用户明确说明该会议室最长可约至何时。若用户确认继续选用该会议室，你必须**自动将日程的重复规则结束时间缩短**至该 `reserve_until_time`，以防止会议室预约失败。不能直接按原规则继续。
> - **正确解释推荐结果**：如果返回结果与用户输入条件不完全字面一致，先说明底层可能返回邻近位置或相近条件的推荐候选，不要直接将其判定为异常。
> - **默认减少用户输入成本**：应主动引导用户不必一开始就提供很详细的会议室搜索条件。只要时间块已明确，用户直接表达“想约会议室”即可，先基于当前信息查询候选；只有在用户对结果不满意时，再引导其补充更具体的楼宇、楼层、会议室名或容量条件。

**字段说明：**

| 字段名 | 说明 |
| :--- | :--- |
| `room_id` | 会议室唯一标识，用于后续创建日程时添加为会议室参与人使用。 |
| `room_name` | 会议室名称，默认原样完整展示给用户，不要自行缩写、截断、改写，也不要用楼层及会议室号摘要替代原值。 |
| `capacity` | 会议室最大容纳人数。 |
| `reserve_until_time` | 该会议室当前允许被预约到的最晚时间点，用于校验重复性日程是否超期。 |

## 参考

- [lark-calendar-create](lark-calendar-create.md)
- [lark-calendar-suggestion](lark-calendar-suggestion.md)
- [lark-calendar](../SKILL.md) — 日历完整 API
