Files
alert-contract-expiring-hr/SKILL.md
taojianmin 6437d6e414
All checks were successful
技能自动化发布 / release (push) Successful in 7s
v1.1.6: 按 skill-template human_verification 设计模式重构 RPA
按 skill-template examples/real_browser_rpa 设计模式重构 platform_collector,
把 v1.1.5 修复的硬编码等待时间统一抽到 constants.py,并补上手工登录 fallback
和结构化错误码。

核心改动:
- constants.py 新增 24 个 RPA 常量(HUMAN_WAIT_TIMEOUT=180 / HUMAN_POLL_INTERVAL=2.0 /
  DEFAULT_PAGE_TIMEOUT_MS=15s / GOTO_TIMEOUT_MS=60s / SPA_LOGIN_* / TABLE_* /
  SIDEBAR_LINK_TIMEOUT_MS 等),与 skill-template human_verification 同名常量对齐
- platform_collector 重构:
  * 新增 RPAError / LoginTimeoutError (ERROR:LOGIN_TIMEOUT) /
    MissingBrowserError (ERROR:MISSING_BROWSER) / TableNotFoundError (ERROR:TABLE_NOT_FOUND)
  * 新增 _is_logged_in / _wait_for_manual_login(轮询 + 180s 兜底,与
    skill-template task_rpa.py::_ensure_logged_in 对齐)
  * _fill_spa_login 自动 fill 失败时 → 自动 fallback _wait_for_manual_login
    (仅 --show-browser 模式;headless 模式抛 LoginTimeoutError 退出码 2)
  * 所有 wait_for_timeout / wait_for_selector timeout 替换为常量
  * collect_all() 加 human_wait_timeout 参数(CLI 透传)
  * page.set_default_timeout(DEFAULT_PAGE_TIMEOUT_MS) 覆盖 Playwright 默认 15s
- app.py cmd_collect_platform:
  * 捕获 RPAError → JSON 输出 {error: e.code, detail: ...} + exit 2
  * 新增 --human-wait-timeout N flag
- requirements.txt:删除违规的 playwright>=1.40.0(playwright 由宿主 jiangchang_skill_core
  runtime 提供,文件顶部注释已声明)
- .env.example:新增 HUMAN_WAIT_TIMEOUT / RPA_PAGE_TIMEOUT_MS / RPA_GOTO_TIMEOUT_MS
  覆盖项
- tests/run_tests.py:新增 7 个 platform_collector 纯函数测试
  (_gen_contract_id × 2 / _normalize_date × 2 / _parse_days × 2 / _parse_alert)
- SKILL.md version 1.1.5 → 1.1.6;CHANGELOG.md 加 1.1.6 条目

测试:28/28 通过(21 原有 + 7 新增)
POLICY-RELEASE-001:SKILL.md=1.1.6 == CHANGELOG=1.1.6 == SKILL_VERSION=1.1.6

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 17:29:08 +08:00

149 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: 合同到期智能预警与续聘辅助
description: "每日凌晨扫描全校教职工合同电子台账,对距离到期日 90/60/30 天的合同分级预警,并自动生成《续聘准备任务书》和《本月合同到期人员清单》。"
version: 1.1.6
author: 深圳匠厂科技有限公司
metadata:
openclaw:
slug: alert-contract-expiring-hr
platform_kit_min_version: "1.2.11"
emoji: "📋"
category: "人事"
developer_ids:
- 12345 # 占位,请换成你的匠厂用户 ID
- 12468
brands: # 可选;未写则发布后仅挂匠厂市场(jiangchang)
- jiangchang # 匠厂主站
- huashang # 华商等 OEM:按目标市场填写,可多选
allowed-tools:
- bash
---
# 合同到期智能预警与续聘辅助(alert-contract-expiring-hr)
这是基于匠厂 skill-template 主仓 v1.0.108 派生的业务技能。覆盖需求规格书第 4.2 节「🟡 人事处 Skill 002 —— 合同到期"智能预警与续聘辅助"」。
## Agent / 宿主编排(复制为业务技能后必改)
### AI + RPA 定位
- **Agent 是入口与编排者**:理解用户意图("扫描本月即将到期的合同"、"给张三生成续聘任务书")、补齐参数、判断风险、选择 Action,并用业务语言解释结果。
- **本技能不涉及浏览器 / 桌面 / 手机 RPA**:合同台账读取走人事系统官方 API,考核数据走党委教师工作部 API。
- 开发者与 AI 编程工具先读 `development/AI_RPA.md`。
### 架构铁律(先读)
- **宿主产品入口平级**:对话任务 / 数据管理 / 定时任务是同一技能能力的不同触发场景,**同等重要**;本技能**重点挂定时任务入口**(每日凌晨扫描)。
- **单业务内核、多入口**:数据管理 / 定时任务 / Agent / 技能详情 / 直接 CLI 必须复用同一 domain service;禁止按入口复制业务逻辑。
- **业务行生命周期**:本技能对合同台账表的每一份合同有"可预警 / 预警中 / 已续聘 / 已驳回"角色约束,遵守 `references/WORK_ITEM_STATUS.md`。
- **HTML 整页报告**:本技能输出个人版《续聘准备任务书》走 `render-html`;单位版清单走 PDF 导出。
### 如何触发(能力类型)
| 你要做什么 | Agent 怎么做 | 进任务中心? |
|------------|--------------|--------------|
| 健康检查 / 短查询 | OpenClaw bash/exec + 共享 Python 跑 CLI | 否 |
| 已声明 sync 的 Action | `run_skill_action` 或等效短 CLI | 否 |
| 长任务(每日凌晨扫描全校 1000+ 份合同) | **必须** `run_skill_action` | 是(仅因 async) |
### 用户意图路由表(业务技能复制后必改)
| 用户意图(本技能自填) | Agent 怎么做 | 进任务中心? |
|------------------------|--------------|--------------|
| 检查运行环境 | 短 CLI:`python {baseDir}/scripts/main.py health` | 否 |
| 查看版本 | 短 CLI:`python {baseDir}/scripts/main.py version` | 否 |
| 查看配置位置 | 短 CLI:`python {baseDir}/scripts/main.py config-path` | 否 |
| 每日凌晨定时扫描合同到期 | `run_skill_action` → `scan-expiring-contracts`(cron / agent) | 是(async) |
| 给某位教师生成续聘任务书 | `run_skill_action` → `generate-renewal-task`(输入:`contract_id`) | 否(sync) |
| 下发单位版续聘清单 | `run_skill_action` → `dispatch-task-notice`(输入:`unit_id` 或 `month`) | 否(sync) |
| 标记合同为已续签 | `run_skill_action` → `mark-contract-renewed`(输入:`contract_id` + 续签材料 ID) | 否(sync) |
| 在浏览器中打开续聘任务书 | `run_skill_action` → `render-html` | 否(sync) |
| 从 SmartCampus 平台抓合同 + 材料 | `run_skill_action` → `collect-from-platform`(首次需用户手工登录保存 profile) | 否(sync) |
| 解析已下载材料 PDF/Word | `run_skill_action` → `parse-materials`(可选 `--contract-id`) | 否(sync) |
## 共享 Python(必读)
宿主共享 runtime 在 `{JIANGCHANG_DATA_ROOT}/python-runtime/.venv`,并已前置到 PATH(同时设 `VIRTUAL_ENV`)。短 CLI 一条命令直接跑:
```bash
python {baseDir}/scripts/main.py health
python {baseDir}/scripts/main.py version
python {baseDir}/scripts/main.py config-path
python {baseDir}/scripts/main.py init-db
```
## 数据来源(v1.1.1)
本技能合同 / 业绩数据有 **三层来源**,按优先级:
1. **HR 系统 API(生产环境推荐)**:通过宿主 `jiangchang_skill_core` 包揽
2. **SmartCampus HR 平台 RPA 采集(v1.1.1 新增)**:`collect-from-platform` CLI 用 Playwright 抓 `https://sandbox.jc2009.com/industries/campus/smartcampus/app/hr/contracts` 表格 6 列(姓名/单位/到期日/剩余天数/预警/建议)→ 落 `contracts` 表
- **当前 sandbox mock 未部署「续聘材料包」按钮**,RPA 仅能采集 6 列台账;材料下载功能预留,sandbox 后端补按钮后自动启用
- `parse-materials` CLI + `material_parser`(pypdf/python-docx/OCR)已实现,本地 `data/materials/` 放 PDF/Word 即可跑解析
3. **样例 CSV(本地开发)**:`examples/contracts_sample.csv` + `performance_sample.csv`,首次 `init-db` 自动加载
AI 续聘建议(v1.1.1)默认调宿主 `jiangchang_skill_core.llm_manager.call_llm_json`;本地无 LLM 时降级到规则版(基于分数阈值),并在 `renewal_tasks.decision_source` 列标注 `llm` / `rules` / `rules_no_materials` 三种来源。
- 公共库来自共享 venv 的 `jiangchang-platform-kit>=1.2.11`(包名路径 `jiangchang_skill_core`);**不要 vendor** `scripts/jiangchang_skill_core/`。
- 根目录 `requirements.txt` **只声明技能特有**依赖;不要写 `jiangchang-platform-kit` / `playwright`。
- `metadata.openclaw.platform_kit_min_version` 是宿主兼容声明,**不是** pip 依赖。
- `health` 用 `collect_runtime_diagnostics` 做只读诊断。
配置:仓库 `.env.example` 为模板;用户 `.env` 在 `{JIANGCHANG_DATA_ROOT}/{JIANGCHANG_USER_ID}/{slug}/.env`。优先级:进程环境变量 > 用户 `.env` > `.env.example`。
## 面向用户问答(LLM 规则)
- 本文(`SKILL.md`)是 LLM / OpenClaw 平台读取的技能入口,**不是**用户市场说明。
- 根目录市场材料面向普通用户(见下方「文档分工」),**不是** Agent 调用契约。
当用户询问以下问题时,**必须优先读取**根目录 `README.md`(能力说明)与 `TUTORIAL.md`(逐步用法):
- 这个技能是做什么的
- 这个技能怎么用
- 适合什么场景
- 使用前要准备什么
- 执行后会得到什么
- 能不能帮我完成某个业务任务
**回答「怎么用 / 能做什么」时的要求:**
1. 「能做什么 / 场景 / 概念类 FAQ」以 `README.md`(说明 Tab)为主;「点哪里 / 说什么 / 排障」以 `TUTORIAL.md`(教程 Tab)为主。
2. **禁止**在回答中粘贴 `python …/scripts/main.py …` 或其它命令行。
3. **禁止**为答用法而去 `dir` / `ls` / 列技能目录。
4. **不要**向普通用户暴露 Playwright、DOM、Python、RPA、库表名、`error_code` 等实现细节。
5. 用户问「怎么用」时:**优先读 `TUTORIAL.md`**。
## 文档分工
| 文档 | 读者 | 用途 |
|------|------|------|
| 根目录 `README.md` | 普通用户 | 市场 **说明** Tab |
| 根目录 `TUTORIAL.md` | 普通用户 | 市场 **教程** Tab |
| 根目录 `DEMO.md` | 普通用户 | 市场 **演示** Tab |
| 根目录 `CHANGELOG.md` | 普通用户 | 市场 **更新日志** Tab |
| `SKILL.md`(本文) | LLM / OpenClaw 平台 | 技能入口、触发与运行契约摘要 |
| `references/` | Agent 编排 / 调用 | CLI、Action、schema 契约 |
| `development/` | 开发者 / AI 编程代理 | 需求、开发教程、测试、深度技术规范 |
## 目录约定
- `assets/`、`development/`、`evals/`、`references/`、`scripts/`、`tests/`
- CLI 入口固定为 `scripts/main.py`
- 业务逻辑按 `cli / db / service / util` 分层
## 技能命名与 slug
- slug:`alert-contract-expiring-hr`(`alert` 动词 + `contract-expiring` 名词 + `hr` 人事处缩写)
- name:**用户可见的中文业务名称**;`description` 是说明,不是名称。
- 目录名、默认 `{slug}.db` 使用 slug,不使用中文。
## 平台元数据
- `metadata.openclaw.developer_ids`:技能发布后的默认开发者可见用户 ID 列表。
- 开发期技能常为不公开:不加本人 ID,开发者自己也无法在市场安装自测。
- 当 `access_scope = 0`(不公开)时,平台会把 `developer_ids` 中的用户自动补写到 `skill_user_access`。
---
> **本技能开发状态:** v1.1.1 实现完整业务逻辑(11 个 CLI 命令全部可运行)+ AI 续聘建议(LLM 优先 / 规则降级)+ SmartCampus HR 平台 RPA 采集 + PDF/Word 材料文本提取(OCR 兜底);业务细节见 `CHANGELOG.md`。