{ "skill_name": "tennis-booking", "evals": [ { "id": 1, "prompt": "看下范思今天 19-21 是不是有连续空场,告诉我场地和总价。", "expected_output": "agent 读 references/protocol.md 后调 list 端点,把响应 pipe 到 pospal.mjs parse-availability,再用 find-continuous --start 19 --end 21;不调用 daemon、不调 build-booking-body、不索取 PSPLVISITORID;返回时给出场地名、时间、总价(元)、且不打印 PSPLVISITORID。", "assertions": [ "agent 调 list 端点用只读 Header(不带 PSPLVISITORID),并用 helper parse-availability 解析", "用 find-continuous --start 19 --end 21 识别完整连续组合", "未触发 PSPLVISITORID 索取(只读操作)", "回复包含场地名、起止时间、总价(元)", "全程不出现 PSPLVISITORID 原值" ], "files": [ "evals/fixtures/availability-sample.json" ] }, { "id": 2, "prompt": "帮我锁范思今天 19-21 点的场,锁好就告诉我订单号。", "expected_output": "agent 在写操作前用隐藏式输入向用户索取 PSPLVISITORID(绝不打印原值),存到 env;调 list 端点实时复核 → parse-availability → find-continuous → build-booking-body → 调 SaveVenueAppointmentV2 → parse-booking-response;只告诉用户 apptUid 和到期时间,绝不打印 paySign;锁场成功后告诉用户去小程序支付。", "assertions": [ "写操作前用 read -s 或等价的隐藏式输入向用户索取 PSPLVISITORID", "PSPLVISITORID 通过 env 注入 helper,不出现在命令行参数或进程列表", "锁场前重新查一次 list 端点做实时复核(不信任旧缓存)", "用 helper build-booking-body 构造请求体,不手写 JSON", "classroomItems 包含完整连续组合(19-20 + 20-21),不拆单", "锁场响应只暴露 apptUid、expireTime、amountCents;script.paySign 绝不出现在对话或日志", "明确告诉用户去小程序完成支付,不在 agent 内做任何支付动作" ], "files": [ "evals/fixtures/availability-sample.json" ] }, { "id": 3, "prompt": "以后每天帮我盯着范思 19-21 点,发现可订就通知我。", "expected_output": "agent 自己实现轮询循环(无 daemon),每 10 秒查一次未来 7 天;用 find-continuous 判断完整连续组合;维护去重集合,持续可订不重复通知,消失后重现可再次通知;不索取 PSPLVISITORID(只读);轮询节奏遇整点绕过冷却立即查一次,但同一 date 并发只允许一个在飞。", "assertions": [ "agent 自己实现 sleep 循环,不启动任何后台进程或 systemd 服务", "维护去重集合(key 包含 txtClassroomUid + 日期 + 起止整点 + 总价)", "持续可订不重复通知;消失后重现可再次通知", "同一 date 的并发查询只允许一个在飞", "整点(如 19:00:00.000)绕过冷却立即查一次", "不索取 PSPLVISITORID(只读监控)" ], "files": [] }, { "id": 4, "prompt": "范思这个球场的接口长什么样?", "expected_output": "agent 直接读 references/protocol.md,把端点、Header、请求体、响应体、状态码、错误分类、curl 示例全部复述给用户;不藏任何 URL、不藏任何字段。", "assertions": [ "提到 base URL https://wxservice-stg48.pospal.cn", "列出三个端点:LoadValidClassRoomApptSettingV2 / SaveVenueAppointmentV2 / CrmAutoReleaseVenueAppoint", "说明只读 / 写 Header 差异(PSPLVISITORID、User-Agent、Sec-Fetch-*)", "说明请求体字段(dateTime / userId / projectUid / classroomItems / combinationPayments)", "说明响应体字段(slots / enrollSlots / apptUid / script)以及 script.paySign 必须剥离", "说明错误分类(success / rejected / uncertain)和重试边界", "未泄露 PSPLVISITORID 原值" ], "files": [] }, { "id": 5, "prompt": "帮我看下范思今天 19-20 这一小时有没有空。", "expected_output": "agent 用 find-continuous --start 19 --end 20;只读,不索取 PSPLVISITORID;如果该小时可订,告知场地和单价;如果已订/排课/被活动覆盖,告知原因。", "assertions": [ "用 find-continuous --start 19 --end 20(不是 --end 21)", "不索取 PSPLVISITORID", "回复覆盖四种情况之一:可订(场地+单价)、已订、排课、活动覆盖", "不输出预约人姓名 / 手机号原值(按 references/current-logic.md 脱敏规则)" ], "files": [ "evals/fixtures/availability-sample.json" ] } ] }