Commit Graph

31 Commits

Author SHA1 Message Date
d3fee3f46c chore: auto release commit (2026-09-15 01:30:18)
Some checks failed
技能自动化发布 / release (push) Failing after 4s
2026-09-15 01:30:18 +08:00
ebea77b5f2 chore: auto release commit (2026-09-15 01:27:04)
Some checks failed
技能自动化发布 / release (push) Failing after 4s
2026-09-15 01:27:05 +08:00
430274dbf9 chore: auto release commit (2026-09-15 01:23:04)
Some checks failed
技能自动化发布 / release (push) Failing after 4s
2026-09-15 01:23:04 +08:00
0157fde0f1 chore: auto release commit (2026-09-15 01:20:35)
Some checks failed
技能自动化发布 / release (push) Failing after 7s
2026-09-15 01:20:35 +08:00
aa9bf262fe chore: auto release commit (2026-09-15 01:15:35)
Some checks failed
技能自动化发布 / release (push) Failing after 5s
2026-09-15 01:15:35 +08:00
52831b80e0 chore: auto release commit (2026-09-15 01:10:24)
Some checks failed
技能自动化发布 / release (push) Failing after 6s
2026-09-15 01:10:24 +08:00
17a7a54349 chore: auto release commit (2026-09-15 01:07:11)
Some checks failed
技能自动化发布 / release (push) Failing after 4s
2026-09-15 01:07:11 +08:00
c21339ae44 chore: auto release commit (2026-09-15 01:02:50)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-15 01:02:50 +08:00
9878f570d7 chore: auto release commit (2026-09-15 00:57:09)
All checks were successful
技能自动化发布 / release (push) Successful in 5s
2026-09-15 00:57:09 +08:00
44088336b4 chore: auto release commit (2026-09-15 00:49:52)
All checks were successful
技能自动化发布 / release (push) Successful in 4s
2026-09-15 00:49:52 +08:00
293b7d1591 chore: auto release commit (2026-09-15 00:32:44)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
2026-09-15 00:32:44 +08:00
693a5e4a53 chore: auto release commit (2026-09-14 23:55:58)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-14 23:55:58 +08:00
c05b765b9d fix: require strictly increasing renewal scores
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-14 22:42:22 +08:00
df5f1b7223 chore: auto release commit (2026-09-14 19:03:19)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
2026-09-14 19:03:19 +08:00
ec786b3480 chore: auto release commit (2026-09-14 18:53:07)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-14 18:53:07 +08:00
11739478d2 chore: auto release commit (2026-09-14 18:50:28)
All checks were successful
技能自动化发布 / release (push) Successful in 8s
2026-09-14 18:50:28 +08:00
7d9aad1672 chore: auto release commit (2026-09-14 18:45:22)
All checks were successful
技能自动化发布 / release (push) Successful in 19s
2026-09-14 18:45:22 +08:00
8ccae17111 chore: auto release commit (2026-09-14 18:37:22)
All checks were successful
技能自动化发布 / release (push) Successful in 11s
2026-09-14 18:37:22 +08:00
04d562745f chore: auto release commit (2026-09-14 18:23:05)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-14 18:23:06 +08:00
8ad3186057 chore: auto release commit (2026-09-14 18:15:26)
All checks were successful
技能自动化发布 / release (push) Successful in 6s
2026-09-14 18:15:26 +08:00
6eb304bca2 chore: auto release commit (2026-09-14 18:08:16)
All checks were successful
技能自动化发布 / release (push) Successful in 5s
2026-09-14 18:08:16 +08:00
55239fd4dd chore: auto release commit (2026-09-14 17:49:26)
All checks were successful
技能自动化发布 / release (push) Successful in 8s
2026-09-14 17:49:26 +08:00
6437d6e414 v1.1.6: 按 skill-template human_verification 设计模式重构 RPA
All checks were successful
技能自动化发布 / release (push) Successful in 7s
按 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
f38f662316 v1.1.5: platform_collector 修复登录等待太短导致采集不到数据
All checks were successful
技能自动化发布 / release (push) Successful in 8s
问题:sandbox RPA 采集时,给用户登录态的等待时间太短(settle_ms=0 /
input timeout=10s / wait_for_url 20s / click 后 0ms 路由稳定时间),SPA
异步跳转被打断,session 没保住,最终 40s 内找不到表格、fetched_rows=0。

修复(核心 5 处):
- _fill_spa_login:settle_ms 默认 4000ms、input timeout 20s、wait_for_url 30s、
  URL 判断覆盖 /auth/ 中间态
- _goto(SPA_LOGIN_URL) 后 wait 3000ms(SPA hydration)
- 登录按钮 click 后 wait 2000ms(等 token 写入 cookie 再 goto home)
- 步骤 4 改为 retry 循环(最多 2 次)
- 步骤 5.6:刷新后若 URL 在 /login 重新登录一次

健壮性修复(5 处):
- 侧边栏 link 等待 15s → 30s
- reload timeout 20s → 30s
- 「续聘材料包」click 后 wait 1500ms → 3000ms
- 抽出 _dump_page helper,自动 mkdir(parents=True) 修 5 处 dump 父目录缺失
- 移除残留 dump_path / html 引用

版本对齐:
- SKILL.md version 1.1.4 → 1.1.5
- constants.py SKILL_VERSION 1.1.4 → 1.1.5
- CHANGELOG.md 加 1.1.5 条目

测试:21/21 通过

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 17:06:28 +08:00
f9be73fa17 chore: auto release commit (2026-09-14 16:22:59) 2026-09-14 16:22:59 +08:00
1707b453c8 chore: auto release commit (2026-09-14 16:15:23) 2026-09-14 16:15:23 +08:00
4af2b4fbf3 v1.1.2: sandbox 卡卡片文本采集 + 解析为 performance 记录
sandbox 行为新发现:
1. 「续聘材料包」按钮不是下载文件,而是触发页面下方显示「续聘准备任务书」
   +「单位清单」卡片(含 checklist + 近三年考核表)
2. 进入 hr/contracts 页面后需要刷新(page.reload)才能看到表格行
3. 表格列序扩展为 10 列:工号 / 姓名 / 单位 / 岗位 / 合同类型 / 起止日期 / 剩余天数 / 预警 / 建议 / 材料包按钮
4. contract_id 改用工号(稳定,不随姓名变化)

改动:
- platform_collector.collect_all:
  * 进入 hr/contracts 后 page.reload 刷新触发 SPA mock 数据加载
  * 新列序映射:r[0]=工号 r[1]=姓名 r[2]=单位 r[3]=岗位 r[4]=合同类型
    r[5]=起止日期 r[6]=剩余天数 r[7]=预警 r[8]=建议
  * 合同 end_date 从「2024-03-01 ~ 2026-04-15」截取 ~ 后的部分
  * 点「续聘材料包」按钮 → 抓下方卡片 inner_text(含 checklist + 考核等次)
  * 把卡片文本存入 materials_content(parse_method='sandbox_card')
- _persist_contracts 增加 sandbox_card 路径分支:写 materials_content 后同步调
  repo.parse_sandbox_card_performance → 抽 year + 等次 → 写 performance_records
- repository.parse_sandbox_card_performance:双模式正则匹配
  * 行格式 "2024\t称职"
  * 叙述式 "2024年:等次「称职」"
- repository.upsert_performance_record + 等次 → 分数映射
  (优秀=90 称职=75 基本称职=60 不称职=30)

实测(sandbox 3 合同):
- RPA-T20190033-20260415 钱实验 → 解析 4 条 performance
- RPA-T20200055-20260630 孙助理 → 解析 6 条
- RPA-T20180021-20260831 王明远 → 解析 6 条
- generate-renewal-task 全部输出 observe + decision_source=rules

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 16:01:20 +08:00
213ab5e209 v1.1.1: platform_collector RPA 流程跑通(headless 抓 3 行)
修复 Playwright 自动化流程稳定性问题:

1. 提取辅助函数 _goto / _fill_root_login / _click_campus_link / _fill_spa_login,
   每个失败独立处理,避免一处报错阻塞后续步骤

2. 强化导航路径:强制 goto /select → click 智慧校园 → goto sandbox SPA login →
   SPA login → 强制 goto SPA_HOME → 等侧边栏 link 出现 → click hr/contracts
   - 即使 sandbox 后端跳走不一致(root login demo/123456 不稳定),也能继续

3. SPA 路由 vs 整页 reload:
   - click 侧边栏 link 优先(SPA pushState,避免 goto 触发整页 reload 被踢回 login)
   - 兜底用 history.pushState + dispatchEvent('popstate') 触发 SPA 路由

4. 表格渲染等待:
   - 增加 3s 初始等待 + 20 次重试(共 40s),给 SPA 异步填充 mock 数据时间

5. 材料下载按钮检查:
   - 检查 '续聘材料包' 按钮是否存在;当前 sandbox mock 未部署此按钮,
     自动跳过下载(仅采集 6 列:姓名/单位/到期日/剩余天数/预警/建议)

6. 调试 dump:
   - SPA home → spa_home_dump.html
   - hr/contracts → hr_contracts_dump.html
   - 失败兜底 → sandbox_dump.html

实测结果(headless=True,profile cookie 复用):
- 抓 3 行合同落库(RPA-钱实验-20260415 / 孙助理 / 王明远)
- sandbox 未部署材料包按钮,跳过下载(不阻塞采集)
- 所有 11 个 CLI exit code = 0

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 15:36:19 +08:00
a3b4092a30 v1.1.1: 升级 AI 续聘建议为 LLM + Playwright RPA 采集 SmartCampus 平台材料
新增:

- scripts/service/platform_collector.py:Playwright RPA(持久化 browser profile 复用登录态),抓合同表(姓名/单位/到期日/剩余天数/预警/建议),逐行点"续聘材料包"按钮下载 PDF/Word 到 data/materials/

- scripts/service/material_parser.py:PDF/Word 文本提取(pypdf → pdf2image + pytesseract OCR 扫描件兜底;python-docx 抽 docx;antiword 兜底 .doc)

- scripts/service/llm_decision.py:AI 决策统一入口(优先调宿主 jiangchang_skill_core.llm_manager.call_llm_json;本地降级到规则版;输出 decision_source ∈ {llm, rules, rules_no_materials})

- scripts/db/migrations.py:idempotent ALTER/CREATE,建 materials_content 表 + renewal_tasks 加 decision_source / materials_summary 列

修改:

- scripts/db/connection.py:init_db() 自动调 apply_all() 应用 v1.1.1 迁移

- scripts/db/repository.py:加 insert_material / list_materials_for_contract / list_pending_materials / summarize_materials / get_task_full

- scripts/service/task_generator.py:AI 决策统一改为调 llm_decision.decide_suggestion(materials_summary=...);reason 文案加「已结合材料包(X 份文件,Y 字 / 待解析)综合判断:...」

- scripts/service/html_renderer.py:ctx 加 DECISION_SOURCE(LLM 推理 / 本地规则 / 本地规则(无材料))+ MATERIALS_COUNT

- scripts/templates/task.html.j2:footer 加 "AI 建议来源:{{DECISION_SOURCE}} · 已审阅材料 {{MATERIALS_COUNT}} 份"

- scripts/cli/app.py:新增 2 个 CLI(collect-from-platform / parse-materials);现有 9 个不动

- requirements.txt:playwright / pypdf / python-docx / pdf2image / pytesseract / Pillow

- .env.example:SMARTCAMPUS_BASE_URL / SMARTCAMPUS_PROFILE_DIR / MATERIALS_DOWNLOAD_DIR / OCR_LANG / LLM_MODEL_NAME / LLM_API_BASE_URL / LLM_API_TOKEN

- SKILL.md:version 1.1.0 → 1.1.1;用户意图路由表加 2 行;新增「数据来源」段(三层来源 + AI 决策透明化)

- README.md:使用前要准备 → 加 playwright install chromium 步骤

- CHANGELOG.md:v1.1.1 条目

- scripts/util/constants.py:SKILL_VERSION 1.1.0 → 1.1.1

本地验证:11 个 CLI 全部 exit 0;decision_source=rules;reason 含「已结合材料包(6 份文件,待解析)」;HTML footer 含决策来源。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 15:01:24 +08:00
06c053d7d7 v1.1.0: 实现核心业务逻辑(扫描/任务书/派发/状态机)
新增(scripts/ 分层完整实现):
- scripts/util/{constants,date_util,runtime_paths,logging_setup}.py
- scripts/db/{connection,seed_data,repository}.py(SQLite + 5 张表 + 50 份样例合同)
- scripts/service/{scanner,task_generator,dispatcher,html_renderer}.py
- scripts/cli/app.py(argparse 子命令)
- scripts/templates/task.html.j2(Jinja2 渲染,无 jinja2 时降级到 str.replace)
- examples/{contracts_sample,performance_sample}.csv(本地样例数据)

修改:
- scripts/main.py:argparse + jiangchang_skill_core 降级
- SKILL.md:version 1.0.1 → 1.1.0
- CHANGELOG.md:加 v1.1.0 条目
- .env.example:加 DB_PATH / HTML_OUTPUT_DIR / JIANGCHANG_DATA_DIR

本地验证(9 个 CLI 命令全部 exit code = 0):
- health / version / config-path / init-db:基础 4 命令
- scan-expiring-contracts --thresholds 90,60,30:42 份可续聘 → 红 10 / 橙 10 / 黄 10,生成 30 任务
- render-html:写 output/<task_id>.html(4.9 KB)
- generate-renewal-task:单份合同任务书生成
- mark-contract-renewed:状态机更新 + 关闭 open alerts
- dispatch-task-notice:按单位/月份派发 payload(dry-run 模式)

业务规则(AI 续聘建议本地版,规则顺序判断):
1. 师德 < 60 → non_renew
2. 近 3 年考核有不合格(< 60)→ observe
3. 全部 >= 80 且逐年上升 → renew
4. 其他 → observe

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-14 14:17:43 +08:00
e2b45d690e v1.0.1: 合同到期智能预警与续聘辅助 - 初版骨架
基于匠厂 skill-template 主仓 v1.0.108 派生的业务技能。

核心业务:
- 每日凌晨定时扫描全校教职工合同电子台账
- 距到期日 90 / 60 / 30 天分级预警(黄 / 橙 / 红)
- 自动生成个人版《续聘准备任务书》与单位版《本月到期人员清单》
- 30 天红色预警自动抄送分管校领导

输出形态:
- 个人版 HTML 任务书 + 单位版 PDF 清单 + 三级预警通知

预期提效:因合同逾期未续签导致的劳动纠纷降为 0;人事处年终集中突击签合同的工作量减少 60%。

业务行生命周期:可续聘 → 预警中(黄 / 橙 / 红)→ 已续签 / 已驳回 / 已过期

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