diff --git a/README.md b/README.md index 633e89e..fa903a4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,75 @@ -# pipeline-opportunity +# pipeline-opportunity — 商机产线能力包 +把招标市场情报转化为软件研发商机:**热点软件推荐 → 每日AI/Agent招标 → 研发报告编写 → 人工确认 → 研发审批流程**。 + +## 平台边界(重要) + +- **数据爬取平台**(ebpe.cc:/d/ymq/work/tender_opp,独立部署):采集中国招标网站数据、 + 持久存储、去重,仅通过内网 HTTP 只读接口对外(`192.168.16.2:9085`,X-API-Token 鉴权)。 +- **本模块(产线平台侧)**:商机业务闭环。只消费爬虫数据,不爬取、不存招标原始数据; + 报告/审批状态落产线库 `opp_reports` / `opp_approvals` 表,绝不回写爬虫库。 + +依赖方向:产线平台 ──HTTP──> 数据爬取平台(单向)。 + +## 产线闭环与门禁 + +``` +opp_hot_software / opp_daily_ai_tenders(爬虫平台数据) + ↓ 选定方向 +opp_create_report(草稿)→ opp_update_report(补写,数据必须来自工具返回) + ↓ +opp_submit_report ──> 人工确认任务(门禁,pipeline_human_tasks: opp_report_confirm) + ↓ 人工确认通过(confirm 回流) +initiate_approval ──> 研发审批任务(门禁,opp_dev_approval) + ↓ 人工审批结论回流 +approved / rejected(rejected 可退回 draft 重来) +``` + +状态机:`draft → confirmed → approval_initiated → approved/rejected`(非法迁移一律拒绝)。 +agent 禁止自批自审:确认与审批结论只能由人工任务回流驱动。 + +## 工具清单(主 agent / 驾驶舱) + +| 工具 | 用途 | +|------|------| +| opp_hot_software | 热点软件推荐(招标量+预算+地区排名) | +| opp_daily_ai_tenders | 每日 AI/Agent 招标展示数据 | +| opp_search_tenders | 关键词检索招标信息 | +| opp_tender_detail | 单条详情(含原文/预算/联系人/来源链接) | +| opp_crawler_stats | 爬虫平台采集健康度 | +| opp_create_report / opp_update_report | 报告草稿创建与补写 | +| opp_list_reports / opp_get_report | 报告列表与全文 | +| opp_submit_report | 提交人工确认(门禁) | +| opp_list_approvals | 审批单列表 | +| opp_diagnose | 产线诊断(报告分布/待办/爬虫连通性) | + +角色:`agent.opp_analyst`(商机分析师)、`agent.opp_writer`(研发报告撰写工程师)。 +slash 命令:`/hot` `/ai` `/reports` `/oppdiag`。 + +## 爬虫平台接入配置 + +系统级配置禁硬编码,走 appbase `params` 表(兜底默认值内网地址): + +| params 键 | 值 | +|-----------|-----| +| `tender_api_base` | `http://192.168.16.2:9085`(默认) | +| `tender_api_token` | 爬虫平台 `state/api.env` 中的 TENDER_API_TOKEN | + +## 部署(宿主 = pipeline-app) + +1. `git clone` 到 `/pkgs/pipeline-opportunity` +2. `bash build.sh`(建表 + 种子数据 + wwwroot 软链 + pip install) +3. app 入口已接线:`load_pipeline_opportunity()`(try/except 兜底) +4. RBAC:`cd && py3/bin/python pkgs/pipeline-opportunity/scripts/load_path.py` +5. i18n:合并 `i18n/{zh,en}/msg.txt` 到宿主 wwwroot(merge_i18n.py),调 /i18n_getmsgs 刷新 +6. 重启应用;浏览器验证驾驶舱 `/pipeline-opportunity/agent` + +## 表 + +- `opp_reports`:研发报告(software/title/content/status/confirm_task_id/confirmed_by) +- `opp_approvals`:研发审批(report_id/status/note/resolved_by) + +## 技能 + +产线技能在 pipeline-core 技能库:`skills_library/pipelines/opportunity_general/` +(common/opp-workflow 总纲 + roles/agent.opp_analyst、agent.opp_writer 角色技能)。 diff --git a/i18n/en/msg.txt b/i18n/en/msg.txt new file mode 100644 index 0000000..3d4e510 --- /dev/null +++ b/i18n/en/msg.txt @@ -0,0 +1,22 @@ +商机产线: Opportunity Pipeline +研发报告: R&D Report +研发审批: R&D Approval +热点软件推荐: Hot Software Ranking +今日AI招标: Today's AI Tenders +报告状态: Report Status +草稿: Draft +人工确认通过: Human-Confirmed +已发起研发审批: Approval Initiated +审批通过: Approved +审批驳回: Rejected +提交确认: Submit for Confirmation +发起审批: Initiate Approval +软件/主题: Software/Theme +报告标题: Report Title +报告正文: Report Content +确认人: Confirmed By +审批说明: Approval Note +发起人: Initiated By +审批人: Resolved By +商机分析师: Opportunity Analyst +研发报告撰写工程师: R&D Report Writer diff --git a/i18n/zh/msg.txt b/i18n/zh/msg.txt new file mode 100644 index 0000000..9bab307 --- /dev/null +++ b/i18n/zh/msg.txt @@ -0,0 +1,22 @@ +商机产线: 商机产线 +研发报告: 研发报告 +研发审批: 研发审批 +热点软件推荐: 热点软件推荐 +今日AI招标: 今日AI招标 +报告状态: 报告状态 +草稿: 草稿 +人工确认通过: 人工确认通过 +已发起研发审批: 已发起研发审批 +审批通过: 审批通过 +审批驳回: 审批驳回 +提交确认: 提交确认 +发起审批: 发起审批 +软件/主题: 软件/主题 +报告标题: 报告标题 +报告正文: 报告正文 +确认人: 确认人 +审批说明: 审批说明 +发起人: 发起人 +审批人: 审批人 +商机分析师: 商机分析师 +研发报告撰写工程师: 研发报告撰写工程师 diff --git a/pipeline_opportunity/__pycache__/opp_common.cpython-310.pyc b/pipeline_opportunity/__pycache__/opp_common.cpython-310.pyc index 1679ebf..729cc08 100644 Binary files a/pipeline_opportunity/__pycache__/opp_common.cpython-310.pyc and b/pipeline_opportunity/__pycache__/opp_common.cpython-310.pyc differ diff --git a/pipeline_opportunity/opp_common.py b/pipeline_opportunity/opp_common.py index d335a5c..d1dec26 100644 --- a/pipeline_opportunity/opp_common.py +++ b/pipeline_opportunity/opp_common.py @@ -161,20 +161,29 @@ async def find_human_task(sor, project_id, task_type, status=None): async def create_human_task(sor, project_id, task_type, title, description="", - assignee_role="owner"): - """创建项目级人工任务(确认/审批门禁)。幂等由调用方先 find 保证。""" + assignee_role="owner.superuser", assignee_id=""): + """创建项目级人工任务(确认/审批门禁)。幂等由调用方先 find 保证。 + + pipeline_human_tasks NOT NULL 列:id/task_id/step_name/version/task_type/status。 + task_id 与步骤任务解耦(确认/审批是产线级门禁,非步骤产物)→ 填空串。 + """ hid = new_id() await sor.C("pipeline_human_tasks", { "id": hid, - "project_id": project_id, + "task_id": "", + "step_name": task_type, + "version": 1, "task_type": task_type, - "title": title, - "description": description, + "assignee_role": assignee_role or "owner.superuser", + "assignee_id": assignee_id or "", "status": "pending", - "assignee_role": assignee_role, - "created_by": "agent.opportunity", + "project_id": project_id or "", + "title": (title or "")[:480], + "description": description or "", }) await sor.sqlExe("COMMIT", {}) + logger.info("opp create_human_task type=%s id=%s project=%s", + task_type, hid, project_id) return hid diff --git a/skill/SKILL.md b/skill/SKILL.md new file mode 100644 index 0000000..ad331b5 --- /dev/null +++ b/skill/SKILL.md @@ -0,0 +1,85 @@ +--- +name: pipeline-opportunity +description: "商机产线能力包——招标市场情报(数据爬取平台)→热点软件推荐→每日AI招标→研发报告→人工确认→研发审批。含爬虫平台接入配置与工具清单。" +--- + +# pipeline_opportunity + +商机产线能力包:把中国招标市场情报转化为软件研发商机。挂载到宿主应用(pipeline-app)即生效, +项目 `sd_projects.pipeline_id='opportunity_general'` 时自动启用全部工具。 + +## 平台边界(必读) + +``` +数据爬取平台 (ebpe.cc:/d/ymq/work/tender_opp) 产线平台 (本模块) + 采集/存储/去重/只读查询 商机业务闭环 + ┌──────────────────────────┐ ┌──────────────────────────┐ + │ ccgp+ggzy 采集 (30min) │ 内网HTTP只读 │ 热点推荐/每日AI招标 │ + │ SQLite 持久 (1700+条) │ ←──────────────── │ 研发报告→人工确认→研发审批 │ + │ http_api.py :9085 +token │ │ opp_reports/opp_approvals │ + └──────────────────────────┘ └──────────────────────────┘ +``` + +- 本模块**不爬取、不存**招标原始数据,只消费爬虫平台;报告/审批状态落产线库。 +- 爬虫平台侧细节见其仓库 `BOUNDARY.md`/`README.md`(HTTP 端点 /api/tenders 等)。 + +## Architecture + +``` +pipeline_opportunity/ +├── init.py # load_pipeline_opportunity()(幂等挂载) +├── opp_common.py # DB上下文/爬虫HTTP客户端/状态机/人工任务 +├── opp_data_capability.py # 爬虫平台只读封装(热点/搜索/详情/每日AI/健康度) +├── opp_report_capability.py # 报告+审批状态机(draft→confirmed→approval→approved/rejected) +├── opp_ability.py # 12工具+prompt+2角色+4 slash 命令(PipelineAbility 注册) +├── wwwroot/ # opp_reports / opp_approvals CRUD 页面(xls2ui 生成) +├── models/ + json/ # DDL 与 CRUD 源 +└── scripts/load_path.py # RBAC 路径注册 +``` + +## 爬虫平台接入(配置不硬编码) + +appbase `params` 表两个键(`opp_common.get_crawler_config` 读取,默认内网地址兜底): + +| 键 | 值 | +|----|-----| +| `tender_api_base` | `http://192.168.16.2:9085`(内网网卡绑定,公网不可达) | +| `tender_api_token` | 爬虫平台 `state/api.env` 的 TENDER_API_TOKEN | + +## 工具(主 agent,opp_ 前缀) + +| 工具 | 用途 | +|------|------| +| `opp_hot_software(days,top)` | 热点软件推荐:招标量+预算+地区排名 | +| `opp_daily_ai_tenders(date)` | 每日 AI/Agent 招标展示数据 | +| `opp_search_tenders(keyword,days,source,limit)` | 关键词检索 | +| `opp_tender_detail(tender_id)` | 单条详情(原文/预算/联系人/来源链接) | +| `opp_crawler_stats()` | 爬虫平台采集健康度 | +| `opp_create_report / opp_update_report` | 报告草稿创建/补写 | +| `opp_list_reports / opp_get_report` | 报告列表/全文 | +| `opp_submit_report(report_id)` | 提交人工确认(创建门禁任务) | +| `opp_list_approvals` | 审批单列表 | +| `opp_diagnose` | 产线诊断 | + +角色:`agent.opp_analyst` / `agent.opp_writer`;slash:`/hot` `/ai` `/reports` `/oppdiag`。 + +## 状态机与门禁(不要绕过) + +``` +draft ──人工确认──> confirmed ──发起──> approval_initiated ──人工结论──> approved + ↑ └ rejected ──> draft(可重来) +``` + +- 确认/审批都是 `pipeline_human_tasks` 人工任务(task_type: `opp_report_confirm` / + `opp_dev_approval`),结论由人工回流,agent 禁止自批自审。 +- 非法迁移一律拒绝(`REPORT_TRANSITIONS`)。 +- 报告中的招标数字必须来自工具返回的真实数据,禁止编造;引用带来源链接。 + +## 部署清单(宿主侧) + +1. `build.sh`(建表+种子+wwwroot 软链+pip install) +2. app 入口 `load_pipeline_opportunity()`(已接线,try/except 兜底) +3. `scripts/load_path.py` 注册 RBAC +4. i18n 合并 `i18n/{zh,en}/msg.txt` +5. params 表配 `tender_api_base` / `tender_api_token` +6. 重启 → 驾驶舱验证 `/hot` 或 `opp_diagnose`