From c74ae0b4189bed40a4290634b80c951ba42f887f Mon Sep 17 00:00:00 2001 From: sladro Date: Sun, 28 Sep 2025 20:21:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DCLI=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=B9=B6=E7=AE=80=E5=8C=96=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要修改: - 修复CLI模块导入:添加__main__.py和正确的包配置 - 修复InteractionHandler调用错误:使用__call__而非.interact() - 删除重复交互:AnalysisAgent和TocAgent都询问生成模式 - 简化生成方式:删除模板选项,只保留AI生成 - 消除代码重复:BidParser专注解析,TocAgent负责生成 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- 111/analysis_result.json | 548 ++++++++++++++++++ 111/tasks.json | 211 +++++++ 222/analysis_result.json | 361 ++++++++++++ 222/tasks.json | 68 +++ pyproject.toml | 14 +- src/bidmaster/__init__.py | 6 + src/bidmaster/__main__.py | 10 + src/bidmaster/agents/analysis.py | 111 ++-- src/bidmaster/agents/builders/toc_builder.py | 12 +- src/bidmaster/agents/interaction.py | 79 ++- src/bidmaster/cli/__init__.py | 6 +- src/bidmaster/cli/project.py | 213 ++++--- .../nodes/toc/generate_sub_chapters.py | 24 +- src/bidmaster/tools/parser.py | 231 +------- uv.lock | 2 +- 15 files changed, 1503 insertions(+), 393 deletions(-) create mode 100644 111/analysis_result.json create mode 100644 111/tasks.json create mode 100644 222/analysis_result.json create mode 100644 222/tasks.json create mode 100644 src/bidmaster/__main__.py diff --git a/111/analysis_result.json b/111/analysis_result.json new file mode 100644 index 0000000..22162d9 --- /dev/null +++ b/111/analysis_result.json @@ -0,0 +1,548 @@ +{ + "project_name": "111", + "source_file": "C:\\Users\\sladr\\Downloads\\test2.docx", + "success": true, + "technical_count": 19, + "commercial_count": 12, + "deviation_count": 0, + "chapter_count": 6, + "execution_time": 192.46280717849731, + "warnings": [ + "AI审查: 6条优化建议" + ], + "bid_structure": { + "scoring_criteria": [ + { + "item_name": "供应商名称", + "max_score": 0.0, + "description": "生产厂商名称与营业执照、资质证书一致;代理商名称与营业执照、获得制造商授权代理的公司名称一致", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "响应文件的签署", + "max_score": 0.0, + "description": "有法定代表人或其委托代理人签字并加盖单位章", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "响应文件格式", + "max_score": 0.0, + "description": "符合\"响应文件格式\"的要求", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "营业执照", + "max_score": 0.0, + "description": "供应商须具有工商行政主管部门核发的有效法人营业执照,提供营业执照原件扫描件", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "资质要求", + "max_score": 0.0, + "description": "符合第一章\"供应商资格要求\"规定", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "利益冲突", + "max_score": 0.0, + "description": "单位负责人为同一人或者存在控股、管理关系的不同单位,不得同时参加同一标段响应或者未划分标段的同一磋商项目响应;与采购当事人存在利害关系可能影响磋商公正性的法人、其他组织或者个人,不得参加响应", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "联合体供应商", + "max_score": 0.0, + "description": "符合第二章\"供应商须知\"第1.4.2项规定", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "不存在禁止响应的情形", + "max_score": 0.0, + "description": "不存在第二章\"供应商须知\"第1.4.3项规定的任何一种情形", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "响应内容", + "max_score": 0.0, + "description": "符合第二章\"供应商须知\"项规定", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "技术性能指标", + "max_score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定", + "category": "equipment_spec", + "chapter_id": "chapter_02_equipment_spec" + }, + { + "item_name": "权利义务", + "max_score": 0.0, + "description": "符合第二章\"供应商须知\"规定和第五章\"合同主要条款\"中的实质性要求和条件", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + }, + { + "item_name": "响应设备及技术服务和质保服务", + "max_score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定和第五章\"合同主要条款\"中的实质性要求和条件", + "category": "after_sales", + "chapter_id": "chapter_03_after_sales" + }, + { + "item_name": "技术支持资料", + "max_score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定", + "category": "after_sales", + "chapter_id": "chapter_03_after_sales" + }, + { + "item_name": "质保期", + "max_score": 3.0, + "description": "售后质保期2年,得1分。售后质保期延长至3年,得2分。售后质保期延长至4年,得3分。", + "category": "after_sales", + "chapter_id": "chapter_03_after_sales" + }, + { + "item_name": "硬件配置", + "max_score": 8.0, + "description": "以确保设备性配置不低于招标文件硬件配置要求。打分标准设备硬件的品牌、硬件配置高低、技术先进性、稳定性、兼容性以及售后服务质量等每项指标综合打分。硬件未满足技术要求按每1项不满足扣1分,扣完为止。(招标文件中参数要求提供的检测报告、功能截图、证书等证明材料供应商必须按要求提供,否则评委不予采信)", + "category": "equipment_spec", + "chapter_id": "chapter_02_equipment_spec" + }, + { + "item_name": "软件功能", + "max_score": 8.0, + "description": "应按照磋商文件功能要求实现,各项软件功能完成率,软件功能按每1项不满足扣1分,扣完为止。", + "category": "technical_solution", + "chapter_id": "chapter_04_technical_solution" + }, + { + "item_name": "系统架构", + "max_score": 5.0, + "description": "对系统架构、实施内容、技术特点、安装规范、售后服务等方面进行说明,缺少1项扣1分,扣完为止。", + "category": "technical_solution", + "chapter_id": "chapter_04_technical_solution" + }, + { + "item_name": "网路安全防护", + "max_score": 5.0, + "description": "1.防火墙配置、入侵检测系统、安全更新和补丁管理、用户权限管理、安全培训和意识提升、数据加密根据以上各项内容的打分情况,可以综合评估组织的网络安全防护水平,缺少1项扣1分,扣完为止。", + "category": "quality_safety", + "chapter_id": "chapter_05_quality_safety" + }, + { + "item_name": "技术实力", + "max_score": 3.0, + "description": "投标人具有自主研发的实时视频分析平台系统的知识产权和AI识别方法的发明专利,每提供一个得1分,共3分。(提供证书原件的扫描件并加盖公章)", + "category": "compliance", + "chapter_id": "chapter_01_compliance" + } + ], + "deviation_items": [], + "chapters": [ + { + "id": "evaluation_index", + "title": "评标索引表(技术评分完全对应)", + "level": 1, + "score": null, + "template_placeholder": "{{evaluation_index_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance", + "title": "合规响应 (3.0分)", + "level": 1, + "score": 3.0, + "template_placeholder": "{{chapter_01_compliance_content}}", + "children": [ + { + "id": "chapter_01_compliance_sub_01", + "title": "供应商基本信息", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_01_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_02", + "title": "响应文件签署确认", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_02_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_03", + "title": "响应文件格式规范", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_03_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_04", + "title": "营业执照及资质证明", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_04_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_05", + "title": "专业资质要求响应", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_05_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_06", + "title": "利益冲突声明", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_06_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_07", + "title": "联合体供应商说明", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_07_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_08", + "title": "禁止响应情形声明", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_08_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_09", + "title": "响应内容完整性", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_09_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_10", + "title": "权利义务确认", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_01_compliance_sub_10_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_11", + "title": "技术实力证明", + "level": 2, + "score": 3.0, + "template_placeholder": "{{chapter_01_compliance_sub_11_content}}", + "children": [ + { + "id": "chapter_01_compliance_sub_11_01", + "title": "技术团队配置与经验", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_01_compliance_sub_11_01_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_11_02", + "title": "技术设备与资源保障", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_01_compliance_sub_11_02_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_11_03", + "title": "技术研发能力展示", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_01_compliance_sub_11_03_content}}", + "children": [] + }, + { + "id": "chapter_01_compliance_sub_11_04", + "title": "技术服务质量保证", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_01_compliance_sub_11_04_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_02_equipment_spec", + "title": "设备规格 (8.0分)", + "level": 1, + "score": 8.0, + "template_placeholder": "{{chapter_02_equipment_spec_content}}", + "children": [ + { + "id": "chapter_02_equipment_spec_sub_01", + "title": "技术性能指标", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_02", + "title": "硬件配置", + "level": 2, + "score": 8.0, + "template_placeholder": "{{chapter_02_equipment_spec_sub_02_content}}", + "children": [ + { + "id": "chapter_02_equipment_spec_sub_02_01", + "title": "核心硬件组件配置", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_02_01_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_02_02", + "title": "硬件性能参数说明", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_02_02_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_02_03", + "title": "硬件兼容性与扩展性", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_02_03_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_02_04", + "title": "硬件质量保证措施", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_02_04_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_03_after_sales", + "title": "售后服务 (3.0分)", + "level": 1, + "score": 3.0, + "template_placeholder": "{{chapter_03_after_sales_content}}", + "children": [ + { + "id": "chapter_03_after_sales_sub_01", + "title": "响应设备及技术服务和质保服务", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_03_after_sales_sub_01_content}}", + "children": [] + }, + { + "id": "chapter_03_after_sales_sub_02", + "title": "技术支持资料", + "level": 2, + "score": 0.0, + "template_placeholder": "{{chapter_03_after_sales_sub_02_content}}", + "children": [] + }, + { + "id": "chapter_03_after_sales_sub_03", + "title": "质保期", + "level": 2, + "score": 3.0, + "template_placeholder": "{{chapter_03_after_sales_sub_03_content}}", + "children": [ + { + "id": "chapter_03_after_sales_sub_03_01", + "title": "质保期限承诺", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_after_sales_sub_03_01_content}}", + "children": [] + }, + { + "id": "chapter_03_after_sales_sub_03_02", + "title": "质保服务范围", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_after_sales_sub_03_02_content}}", + "children": [] + }, + { + "id": "chapter_03_after_sales_sub_03_03", + "title": "质保期服务响应机制", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_after_sales_sub_03_03_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_04_technical_solution", + "title": "技术方案 (13.0分)", + "level": 1, + "score": 13.0, + "template_placeholder": "{{chapter_04_technical_solution_content}}", + "children": [ + { + "id": "chapter_04_technical_solution_sub_01", + "title": "软件功能设计", + "level": 2, + "score": 8.0, + "template_placeholder": "{{chapter_04_technical_solution_sub_01_content}}", + "children": [ + { + "id": "chapter_04_technical_solution_sub_01_01", + "title": "核心功能模块设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_04_technical_solution_sub_01_02", + "title": "用户交互界面设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_04_technical_solution_sub_01_03", + "title": "数据处理功能设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_04_technical_solution_sub_01_04", + "title": "系统管理功能设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_01_04_content}}", + "children": [] + } + ] + }, + { + "id": "chapter_04_technical_solution_sub_02", + "title": "系统架构设计", + "level": 2, + "score": 5.0, + "template_placeholder": "{{chapter_04_technical_solution_sub_02_content}}", + "children": [ + { + "id": "chapter_04_technical_solution_sub_02_01", + "title": "总体架构设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_02_01_content}}", + "children": [] + }, + { + "id": "chapter_04_technical_solution_sub_02_02", + "title": "技术架构选型", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_02_02_content}}", + "children": [] + }, + { + "id": "chapter_04_technical_solution_sub_02_03", + "title": "系统部署架构", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_technical_solution_sub_02_03_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_05_quality_safety", + "title": "质量安全 (5.0分)", + "level": 1, + "score": 5.0, + "template_placeholder": "{{chapter_05_quality_safety_content}}", + "children": [ + { + "id": "chapter_05_quality_safety_sub_01", + "title": "网络安全防护体系", + "level": 2, + "score": 5.0, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_content}}", + "children": [ + { + "id": "chapter_05_quality_safety_sub_01_01", + "title": "网络边界安全防护", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_05_quality_safety_sub_01_02", + "title": "入侵检测与防御系统", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_05_quality_safety_sub_01_03", + "title": "网络安全审计与监控", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_05_quality_safety_sub_01_04", + "title": "网络访问控制策略", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_04_content}}", + "children": [] + }, + { + "id": "chapter_05_quality_safety_sub_01_05", + "title": "网络安全应急预案", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_quality_safety_sub_01_05_content}}", + "children": [] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/111/tasks.json b/111/tasks.json new file mode 100644 index 0000000..3270087 --- /dev/null +++ b/111/tasks.json @@ -0,0 +1,211 @@ +[ + { + "id": 1, + "title": "供应商名称", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "生产厂商名称与营业执照、资质证书一致;代理商名称与营业执照、获得制造商授权代理的公司名称一致", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 2, + "title": "响应文件的签署", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "有法定代表人或其委托代理人签字并加盖单位章", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 3, + "title": "响应文件格式", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "符合\"响应文件格式\"的要求", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 4, + "title": "营业执照", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "供应商须具有工商行政主管部门核发的有效法人营业执照,提供营业执照原件扫描件", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 5, + "title": "资质要求", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "符合第一章\"供应商资格要求\"规定", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 6, + "title": "利益冲突", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "单位负责人为同一人或者存在控股、管理关系的不同单位,不得同时参加同一标段响应或者未划分标段的同一磋商项目响应;与采购当事人存在利害关系可能影响磋商公正性的法人、其他组织或者个人,不得参加响应", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 7, + "title": "联合体供应商", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "符合第二章\"供应商须知\"第1.4.2项规定", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 8, + "title": "不存在禁止响应的情形", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "不存在第二章\"供应商须知\"第1.4.3项规定的任何一种情形", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 9, + "title": "响应内容", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "符合第二章\"供应商须知\"项规定", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 10, + "title": "技术性能指标", + "chapter_id": "chapter_02_equipment_spec", + "score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定", + "category": "equipment_spec", + "status": "pending", + "content": "", + "placeholder": "{{chapter_02_equipment_spec_content}}" + }, + { + "id": 11, + "title": "权利义务", + "chapter_id": "chapter_01_compliance", + "score": 0.0, + "description": "符合第二章\"供应商须知\"规定和第五章\"合同主要条款\"中的实质性要求和条件", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + }, + { + "id": 12, + "title": "响应设备及技术服务和质保服务", + "chapter_id": "chapter_03_after_sales", + "score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定和第五章\"合同主要条款\"中的实质性要求和条件", + "category": "after_sales", + "status": "pending", + "content": "", + "placeholder": "{{chapter_03_after_sales_content}}" + }, + { + "id": 13, + "title": "技术支持资料", + "chapter_id": "chapter_03_after_sales", + "score": 0.0, + "description": "符合第三章\"采购需求及技术要求\"规定", + "category": "after_sales", + "status": "pending", + "content": "", + "placeholder": "{{chapter_03_after_sales_content}}" + }, + { + "id": 14, + "title": "质保期", + "chapter_id": "chapter_03_after_sales", + "score": 3.0, + "description": "售后质保期2年,得1分。售后质保期延长至3年,得2分。售后质保期延长至4年,得3分。", + "category": "after_sales", + "status": "pending", + "content": "", + "placeholder": "{{chapter_03_after_sales_content}}" + }, + { + "id": 15, + "title": "硬件配置", + "chapter_id": "chapter_02_equipment_spec", + "score": 8.0, + "description": "以确保设备性配置不低于招标文件硬件配置要求。打分标准设备硬件的品牌、硬件配置高低、技术先进性、稳定性、兼容性以及售后服务质量等每项指标综合打分。硬件未满足技术要求按每1项不满足扣1分,扣完为止。(招标文件中参数要求提供的检测报告、功能截图、证书等证明材料供应商必须按要求提供,否则评委不予采信)", + "category": "equipment_spec", + "status": "pending", + "content": "", + "placeholder": "{{chapter_02_equipment_spec_content}}" + }, + { + "id": 16, + "title": "软件功能", + "chapter_id": "chapter_04_technical_solution", + "score": 8.0, + "description": "应按照磋商文件功能要求实现,各项软件功能完成率,软件功能按每1项不满足扣1分,扣完为止。", + "category": "technical_solution", + "status": "pending", + "content": "", + "placeholder": "{{chapter_04_technical_solution_content}}" + }, + { + "id": 17, + "title": "系统架构", + "chapter_id": "chapter_04_technical_solution", + "score": 5.0, + "description": "对系统架构、实施内容、技术特点、安装规范、售后服务等方面进行说明,缺少1项扣1分,扣完为止。", + "category": "technical_solution", + "status": "pending", + "content": "", + "placeholder": "{{chapter_04_technical_solution_content}}" + }, + { + "id": 18, + "title": "网路安全防护", + "chapter_id": "chapter_05_quality_safety", + "score": 5.0, + "description": "1.防火墙配置、入侵检测系统、安全更新和补丁管理、用户权限管理、安全培训和意识提升、数据加密根据以上各项内容的打分情况,可以综合评估组织的网络安全防护水平,缺少1项扣1分,扣完为止。", + "category": "quality_safety", + "status": "pending", + "content": "", + "placeholder": "{{chapter_05_quality_safety_content}}" + }, + { + "id": 19, + "title": "技术实力", + "chapter_id": "chapter_01_compliance", + "score": 3.0, + "description": "投标人具有自主研发的实时视频分析平台系统的知识产权和AI识别方法的发明专利,每提供一个得1分,共3分。(提供证书原件的扫描件并加盖公章)", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_compliance_content}}" + } +] \ No newline at end of file diff --git a/222/analysis_result.json b/222/analysis_result.json new file mode 100644 index 0000000..eb070ec --- /dev/null +++ b/222/analysis_result.json @@ -0,0 +1,361 @@ +{ + "project_name": "222", + "source_file": "C:\\Users\\sladr\\Downloads\\test2.docx", + "success": true, + "technical_count": 6, + "commercial_count": 3, + "deviation_count": 0, + "chapter_count": 6, + "execution_time": 166.37327432632446, + "warnings": [ + "AI审查: 4条优化建议" + ], + "bid_structure": { + "scoring_criteria": [ + { + "item_name": "质保期", + "max_score": 3.0, + "description": "售后质保期2年,得1分。售后质保期延长至3年,得2分。售后质保期延长至4年,得3分。", + "category": "after_sales", + "chapter_id": "chapter_01_after_sales" + }, + { + "item_name": "硬件配置", + "max_score": 8.0, + "description": "以确保设备性配置不低于招标文件硬件配置要求。打分标准设备硬件的品牌、硬件配置高低、技术先进性、稳定性、兼容性以及售后服务质量等每项指标综合打分。硬件未满足技术要求按每1项不满足扣1分,扣完为止。(招标文件中参数要求提供的检测报告、功能截图、证书等证明材料供应商必须按要求提供,否则评委不予采信)", + "category": "equipment_spec", + "chapter_id": "chapter_02_equipment_spec" + }, + { + "item_name": "软件功能", + "max_score": 8.0, + "description": "应按照磋商文件功能要求实现,各项软件功能完成率,软件功能按每1项不满足扣1分,扣完为止。", + "category": "technical_solution", + "chapter_id": "chapter_03_technical_solution" + }, + { + "item_name": "系统架构", + "max_score": 5.0, + "description": "对系统架构、实施内容、技术特点、安装规范、售后服务等方面进行说明,缺少1项扣1分,扣完为止。", + "category": "technical_solution", + "chapter_id": "chapter_03_technical_solution" + }, + { + "item_name": "网路安全防护", + "max_score": 5.0, + "description": "1.防火墙配置、入侵检测系统、安全更新和补丁管理、用户权限管理、安全培训和意识提升、数据加密根据以上各项内容的打分情况,可以综合评估组织的网络安全防护水平,缺少1项扣1分,扣完为止。", + "category": "quality_safety", + "chapter_id": "chapter_04_quality_safety" + }, + { + "item_name": "技术实力", + "max_score": 3.0, + "description": "投标人具有自主研发的实时视频分析平台系统的知识产权和AI识别方法的发明专利,每提供一个得1分,共3分。(提供证书原件的扫描件并加盖公章)", + "category": "compliance", + "chapter_id": "chapter_05_compliance" + } + ], + "deviation_items": [], + "chapters": [ + { + "id": "evaluation_index", + "title": "评标索引表(技术评分完全对应)", + "level": 1, + "score": null, + "template_placeholder": "{{evaluation_index_content}}", + "children": [] + }, + { + "id": "chapter_01_after_sales", + "title": "售后服务 (3.0分)", + "level": 1, + "score": 3.0, + "template_placeholder": "{{chapter_01_after_sales_content}}", + "children": [ + { + "id": "chapter_01_after_sales_sub_01", + "title": "售后服务承诺", + "level": 2, + "score": 3.0, + "template_placeholder": "{{chapter_01_after_sales_sub_01_content}}", + "children": [ + { + "id": "chapter_01_after_sales_sub_01_01", + "title": "质保期承诺", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_01_after_sales_sub_01_01_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_02_equipment_spec", + "title": "设备规格 (8.0分)", + "level": 1, + "score": 8.0, + "template_placeholder": "{{chapter_02_equipment_spec_content}}", + "children": [ + { + "id": "chapter_02_equipment_spec_sub_01", + "title": "硬件配置", + "level": 2, + "score": 8.0, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_content}}", + "children": [ + { + "id": "chapter_02_equipment_spec_sub_01_01", + "title": "服务器硬件配置", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_01_02", + "title": "存储设备配置", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_01_03", + "title": "网络设备配置", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_01_04", + "title": "安全设备配置", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_04_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_01_05", + "title": "硬件性能参数", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_05_content}}", + "children": [] + }, + { + "id": "chapter_02_equipment_spec_sub_01_06", + "title": "硬件兼容性说明", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_02_equipment_spec_sub_01_06_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_03_technical_solution", + "title": "技术方案 (13.0分)", + "level": 1, + "score": 13.0, + "template_placeholder": "{{chapter_03_technical_solution_content}}", + "children": [ + { + "id": "chapter_03_technical_solution_sub_01", + "title": "软件功能设计", + "level": 2, + "score": 8.0, + "template_placeholder": "{{chapter_03_technical_solution_sub_01_content}}", + "children": [ + { + "id": "chapter_03_technical_solution_sub_01_01", + "title": "核心功能模块设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_01_02", + "title": "用户交互功能设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_01_03", + "title": "数据处理功能设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_01_04", + "title": "系统管理功能设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_01_04_content}}", + "children": [] + } + ] + }, + { + "id": "chapter_03_technical_solution_sub_02", + "title": "系统架构设计", + "level": 2, + "score": 5.0, + "template_placeholder": "{{chapter_03_technical_solution_sub_02_content}}", + "children": [ + { + "id": "chapter_03_technical_solution_sub_02_01", + "title": "总体架构设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_02_01_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_02_02", + "title": "技术架构选型", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_02_02_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_02_03", + "title": "系统部署架构", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_02_03_content}}", + "children": [] + }, + { + "id": "chapter_03_technical_solution_sub_02_04", + "title": "安全架构设计", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_03_technical_solution_sub_02_04_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_04_quality_safety", + "title": "质量安全 (5.0分)", + "level": 1, + "score": 5.0, + "template_placeholder": "{{chapter_04_quality_safety_content}}", + "children": [ + { + "id": "chapter_04_quality_safety_sub_01", + "title": "网络安全防护体系", + "level": 2, + "score": 5.0, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_content}}", + "children": [ + { + "id": "chapter_04_quality_safety_sub_01_01", + "title": "网络边界安全防护", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_04_quality_safety_sub_01_02", + "title": "入侵检测与防御系统", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_04_quality_safety_sub_01_03", + "title": "网络访问控制策略", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_04_quality_safety_sub_01_04", + "title": "网络安全审计与监控", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_04_content}}", + "children": [] + }, + { + "id": "chapter_04_quality_safety_sub_01_05", + "title": "网络安全应急响应机制", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_04_quality_safety_sub_01_05_content}}", + "children": [] + } + ] + } + ] + }, + { + "id": "chapter_05_compliance", + "title": "合规响应 (3.0分)", + "level": 1, + "score": 3.0, + "template_placeholder": "{{chapter_05_compliance_content}}", + "children": [ + { + "id": "chapter_05_compliance_sub_01", + "title": "技术实力", + "level": 2, + "score": 3.0, + "template_placeholder": "{{chapter_05_compliance_sub_01_content}}", + "children": [ + { + "id": "chapter_05_compliance_sub_01_01", + "title": "核心技术团队介绍", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_compliance_sub_01_01_content}}", + "children": [] + }, + { + "id": "chapter_05_compliance_sub_01_02", + "title": "技术研发能力展示", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_compliance_sub_01_02_content}}", + "children": [] + }, + { + "id": "chapter_05_compliance_sub_01_03", + "title": "技术解决方案优势", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_compliance_sub_01_03_content}}", + "children": [] + }, + { + "id": "chapter_05_compliance_sub_01_04", + "title": "技术实施保障措施", + "level": 3, + "score": null, + "template_placeholder": "{{chapter_05_compliance_sub_01_04_content}}", + "children": [] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/222/tasks.json b/222/tasks.json new file mode 100644 index 0000000..fe04b17 --- /dev/null +++ b/222/tasks.json @@ -0,0 +1,68 @@ +[ + { + "id": 1, + "title": "质保期", + "chapter_id": "chapter_01_after_sales", + "score": 3.0, + "description": "售后质保期2年,得1分。售后质保期延长至3年,得2分。售后质保期延长至4年,得3分。", + "category": "after_sales", + "status": "pending", + "content": "", + "placeholder": "{{chapter_01_after_sales_content}}" + }, + { + "id": 2, + "title": "硬件配置", + "chapter_id": "chapter_02_equipment_spec", + "score": 8.0, + "description": "以确保设备性配置不低于招标文件硬件配置要求。打分标准设备硬件的品牌、硬件配置高低、技术先进性、稳定性、兼容性以及售后服务质量等每项指标综合打分。硬件未满足技术要求按每1项不满足扣1分,扣完为止。(招标文件中参数要求提供的检测报告、功能截图、证书等证明材料供应商必须按要求提供,否则评委不予采信)", + "category": "equipment_spec", + "status": "pending", + "content": "", + "placeholder": "{{chapter_02_equipment_spec_content}}" + }, + { + "id": 3, + "title": "软件功能", + "chapter_id": "chapter_03_technical_solution", + "score": 8.0, + "description": "应按照磋商文件功能要求实现,各项软件功能完成率,软件功能按每1项不满足扣1分,扣完为止。", + "category": "technical_solution", + "status": "pending", + "content": "", + "placeholder": "{{chapter_03_technical_solution_content}}" + }, + { + "id": 4, + "title": "系统架构", + "chapter_id": "chapter_03_technical_solution", + "score": 5.0, + "description": "对系统架构、实施内容、技术特点、安装规范、售后服务等方面进行说明,缺少1项扣1分,扣完为止。", + "category": "technical_solution", + "status": "pending", + "content": "", + "placeholder": "{{chapter_03_technical_solution_content}}" + }, + { + "id": 5, + "title": "网路安全防护", + "chapter_id": "chapter_04_quality_safety", + "score": 5.0, + "description": "1.防火墙配置、入侵检测系统、安全更新和补丁管理、用户权限管理、安全培训和意识提升、数据加密根据以上各项内容的打分情况,可以综合评估组织的网络安全防护水平,缺少1项扣1分,扣完为止。", + "category": "quality_safety", + "status": "pending", + "content": "", + "placeholder": "{{chapter_04_quality_safety_content}}" + }, + { + "id": 6, + "title": "技术实力", + "chapter_id": "chapter_05_compliance", + "score": 3.0, + "description": "投标人具有自主研发的实时视频分析平台系统的知识产权和AI识别方法的发明专利,每提供一个得1分,共3分。(提供证书原件的扫描件并加盖公章)", + "category": "compliance", + "status": "pending", + "content": "", + "placeholder": "{{chapter_05_compliance_content}}" + } +] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 18ea0a5..94f7fad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [project] name = "bidmaster-cli" version = "0.1.0" -description = "Add your description here" -readme = "README.md" +description = "AI标书撰写助手" +readme = "PROJECT_SPEC.md" requires-python = ">=3.11" dependencies = [ "chromadb>=1.1.0", @@ -20,6 +20,16 @@ dependencies = [ "sentence-transformers>=5.1.1", ] +[project.scripts] +bidmaster = "bidmaster.cli.main:cli" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["src/bidmaster"] + [dependency-groups] dev = [ "black>=25.9.0", diff --git a/src/bidmaster/__init__.py b/src/bidmaster/__init__.py index 01b17e4..e54a17b 100644 --- a/src/bidmaster/__init__.py +++ b/src/bidmaster/__init__.py @@ -5,6 +5,12 @@ __all__ = ["parse", "generate", "assemble"] +# CLI入口 +def main(): + """CLI主入口函数""" + from .cli.main import cli + cli() + from .tools.parser import BidParser from .tools.rag import RAGTool from .tools.table import TableGenerator diff --git a/src/bidmaster/__main__.py b/src/bidmaster/__main__.py new file mode 100644 index 0000000..8541a8b --- /dev/null +++ b/src/bidmaster/__main__.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 +"""BidMaster CLI模块入口 + +支持 python -m bidmaster 调用 +""" + +from . import main + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/bidmaster/agents/analysis.py b/src/bidmaster/agents/analysis.py index 8ff3c17..388db65 100644 --- a/src/bidmaster/agents/analysis.py +++ b/src/bidmaster/agents/analysis.py @@ -20,11 +20,28 @@ from ..config import get_settings logger = logging.getLogger(__name__) +def _validate_template_file(file_path: str) -> bool: + """验证模板文件是否有效 + + Args: + file_path: 文件路径 + + Returns: + 是否为有效的Word模板文件 + """ + try: + path = Path(file_path) + return path.exists() and path.suffix.lower() == '.docx' + except Exception: + return False + + class AnalysisAgentState(TypedDict): """Analysis Agent的状态定义""" # 输入参数 source_file: str + interaction_handler: Any # InteractionHandler实例 # 执行状态 current_step: str @@ -246,51 +263,32 @@ def generate_toc_with_agent_node(state: AnalysisAgentState) -> AnalysisAgentStat if not technical_criteria: raise ValueError("缺少技术评分项,无法生成章节结构") - # 询问用户选择生成方式 - from rich.console import Console - import click - console = Console() - - console.print("\n📝 请选择章节内容生成方式:", style="blue") - console.print("1. AI智能生成子标题(推荐)- 根据评分项要求智能生成2-3级标题") - console.print("2. 基于模板生成 - 使用预定义模板结构") + # 从状态中获取或创建InteractionHandler + interaction_handler = state.get("interaction_handler") + if not interaction_handler: + # 如果没有提供InteractionHandler,创建默认的交互式处理器 + from .interaction import InteractionHandler, InteractionMode + interaction_handler = InteractionHandler(mode=InteractionMode.INTERACTIVE) + # 直接使用AI生成模式 generation_mode = "ai" template_file = None - try: - choice = click.prompt("请输入选择", type=click.Choice(['1', '2']), show_choices=False) - if choice == '2': - generation_mode = "template" - while True: - template_path = click.prompt("请输入模板文件路径(.docx格式)", type=str) - from pathlib import Path - if Path(template_path).exists() and template_path.lower().endswith('.docx'): - template_file = template_path - console.print(f"✅ 模板文件: {template_file}", style="green") - break - else: - console.print("❌ 文件不存在或格式不正确,请重新输入", style="red") - except Exception as e: - logger.error(f"用户交互失败: {e}") - state["error"] = f"无法获取用户输入: {e}" - state["should_continue"] = False - return state - - # 调用TocGeneratorAgent - from .toc_generator import TocGeneratorAgent - toc_agent = TocGeneratorAgent() - result = toc_agent.generate_sync( + # 使用TocAgent(新架构)生成目录 + from .builders.toc_builder import TocAgent + toc_agent = TocAgent(interaction_handler) + result = toc_agent.generate_toc_sync( technical_criteria=technical_criteria, generation_mode=generation_mode, template_file=template_file ) - if not result.success: - raise ValueError(f"目录生成失败: {result.error_message}") + # 检查是否有错误 + if result.get("error"): + raise ValueError(f"目录生成失败: {result['error']}") # 映射评分项到生成的章节 - chapters = result.chapters + chapters = result.get("final_chapters", []) for criteria in technical_criteria: # 根据类别找到对应章节 category = criteria.category.value @@ -313,8 +311,8 @@ def generate_toc_with_agent_node(state: AnalysisAgentState) -> AnalysisAgentStat state["progress"] = 0.85 # 添加警告信息 - if result.warnings: - state["warnings"].extend(result.warnings) + if result.get("warnings"): + state["warnings"].extend(result.get("warnings", [])) except Exception as e: logger.error(f"目录生成失败: {e}") @@ -399,8 +397,9 @@ def should_continue_processing(state: AnalysisAgentState) -> str: class AnalysisAgent: """Analysis Agent - 第一阶段分析Agent""" - def __init__(self): + def __init__(self, interaction_handler=None): self.settings = get_settings() + self.interaction_handler = interaction_handler self.graph = self._build_graph() def _build_graph(self) -> StateGraph: @@ -478,6 +477,7 @@ class AnalysisAgent: # 初始化状态 initial_state = AnalysisAgentState( source_file=source_file, + interaction_handler=self.interaction_handler, current_step="", progress=0.0, should_continue=True, @@ -533,4 +533,41 @@ class AnalysisAgent: """同步执行接口(用于CLI调用)""" return asyncio.run(self.execute(source_file)) + @classmethod + def create_with_handler(cls, interaction_handler) -> 'AnalysisAgent': + """使用指定的交互处理器创建Agent + + Args: + interaction_handler: 交互处理函数 + + Returns: + AnalysisAgent实例 + """ + return cls(interaction_handler) + + @classmethod + def create_silent(cls) -> 'AnalysisAgent': + """创建静默模式的Agent(使用默认值) + + Returns: + 静默模式的AnalysisAgent实例 + """ + from .interaction import InteractionHandler, InteractionMode + handler = InteractionHandler(mode=InteractionMode.SILENT) + return cls(handler) + + @classmethod + def create_programmatic(cls, presets: Dict[str, Any]) -> 'AnalysisAgent': + """创建程序化模式的Agent(使用预设值) + + Args: + presets: 预设值字典 + + Returns: + 程序化模式的AnalysisAgent实例 + """ + from .interaction import InteractionHandler, InteractionMode + handler = InteractionHandler(mode=InteractionMode.PROGRAMMATIC, presets=presets) + return cls(handler) + diff --git a/src/bidmaster/agents/builders/toc_builder.py b/src/bidmaster/agents/builders/toc_builder.py index b999f17..75640b8 100644 --- a/src/bidmaster/agents/builders/toc_builder.py +++ b/src/bidmaster/agents/builders/toc_builder.py @@ -38,11 +38,11 @@ class TocAgentBuilder(AgentBuilder): """目录生成Agent构建器""" @classmethod - def create(cls, interaction_handler: Optional[Callable] = None) -> 'TocAgentBuilder': + def create(cls, interaction_handler = None) -> 'TocAgentBuilder': """创建预配置的TocAgent构建器 Args: - interaction_handler: 交互处理函数 + interaction_handler: InteractionHandler实例或兼容的交互处理函数 Returns: 配置完成的构建器实例 @@ -102,21 +102,21 @@ class TocAgent(BaseAgent): 封装了目录生成的完整工作流程。 """ - def __init__(self, interaction_handler: Optional[Callable] = None): + def __init__(self, interaction_handler = None): """初始化TocAgent Args: - interaction_handler: 交互处理函数 + interaction_handler: InteractionHandler实例或兼容的交互处理函数 """ builder = TocAgentBuilder.create(interaction_handler) super().__init__(builder) @classmethod - def create_with_handler(cls, interaction_handler: Callable) -> 'TocAgent': + def create_with_handler(cls, interaction_handler) -> 'TocAgent': """使用指定的交互处理器创建Agent Args: - interaction_handler: 交互处理函数 + interaction_handler: InteractionHandler实例 Returns: TocAgent实例 diff --git a/src/bidmaster/agents/interaction.py b/src/bidmaster/agents/interaction.py index 52362e1..05835bb 100644 --- a/src/bidmaster/agents/interaction.py +++ b/src/bidmaster/agents/interaction.py @@ -6,7 +6,7 @@ import json import logging from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple, Union, Callable import click from rich.console import Console @@ -98,6 +98,10 @@ class InteractionHandler: return self._handle_file_path(**kwargs) elif interaction_type == "confirm": return self._handle_confirm(**kwargs) + elif interaction_type == "generation_mode_choice": + return self._handle_generation_mode_choice(**kwargs) + elif interaction_type == "template_file_path": + return self._handle_template_file_path(**kwargs) else: logger.warning(f"未知交互类型: {interaction_type}") return kwargs.get('default') @@ -283,6 +287,79 @@ class InteractionHandler: return None + def _handle_generation_mode_choice(self, + prompt: str, + options: Dict[str, Dict[str, str]], + default: str = "ai", + **kwargs) -> str: + """处理生成模式选择交互 + + Args: + prompt: 提示文本 + options: 选项字典,格式 {"1": {"label": "描述", "value": "ai"}} + default: 默认值 + **kwargs: 其他参数 + + Returns: + 选择的模式值 + """ + from rich.console import Console + import click + + console = Console() + console.print(f"\n📝 {prompt}:", style="blue") + + # 显示选项 + for key, option in options.items(): + console.print(f"{key}. {option['label']}") + + try: + choice = click.prompt( + "请输入选择", + type=click.Choice(list(options.keys())), + show_choices=False + ) + return options[choice]["value"] + except Exception as e: + logger.error(f"选择输入失败: {e}") + return default + + def _handle_template_file_path(self, + prompt: str, + validation: Optional[Callable] = None, + error_message: str = "输入无效,请重新输入", + **kwargs) -> str: + """处理模板文件路径输入交互 + + Args: + prompt: 提示文本 + validation: 验证函数 + error_message: 错误消息 + **kwargs: 其他参数 + + Returns: + 有效的文件路径 + """ + from rich.console import Console + import click + + console = Console() + + while True: + try: + file_path = click.prompt(prompt, type=str) + + if validation and not validation(file_path): + console.print(f"❌ {error_message}", style="red") + continue + + console.print(f"✅ 模板文件: {file_path}", style="green") + return file_path + + except Exception as e: + logger.error(f"文件路径输入失败: {e}") + console.print(f"❌ 输入失败: {e}", style="red") + def get_interaction_history(self) -> List[Dict[str, Any]]: """获取交互历史 diff --git a/src/bidmaster/cli/__init__.py b/src/bidmaster/cli/__init__.py index 8b94cd9..f66a200 100644 --- a/src/bidmaster/cli/__init__.py +++ b/src/bidmaster/cli/__init__.py @@ -1 +1,5 @@ -# CLI层 - 命令行接口 \ No newline at end of file +# CLI层 - 命令行接口 + +from .main import cli + +__all__ = ["cli"] \ No newline at end of file diff --git a/src/bidmaster/cli/project.py b/src/bidmaster/cli/project.py index 2803b85..5384245 100644 --- a/src/bidmaster/cli/project.py +++ b/src/bidmaster/cli/project.py @@ -128,7 +128,14 @@ def parse(scoring_file: str, deviation_file: str | None, template_file: str | No @project.command() -def new(): +@click.option("--mode", "-m", + type=click.Choice(['interactive', 'silent', 'programmatic']), + default='interactive', + help="交互模式:interactive(默认)|silent(静默)|programmatic(预设)") +@click.option("--presets", "-p", + type=str, + help="程序化模式的预设配置JSON字符串") +def new(mode: str, presets: str): """核心命令:解析招标文件,生成任务清单和Word框架""" try: console.print("🎯 BidMaster 标书项目创建向导", style="bold blue") @@ -164,90 +171,97 @@ def new(): project_path.mkdir(parents=True, exist_ok=True) console.print(f"📁 项目目录: {project_path.absolute()}", style="green") - # 创建解析器 - parser = BidParser() + # 使用AnalysisAgent(新架构)替代直接调用BidParser + from ..agents.analysis import AnalysisAgent + import json - # 智能解析招标文件 - with console.status("正在解析招标文件..."): - technical_criteria, commercial_criteria, deviation_items = parser.parse_word_with_filter(bidding_file) + # 根据模式创建AnalysisAgent + if mode == 'silent': + analysis_agent = AnalysisAgent.create_silent() + console.print("📌 使用静默模式(自动选择默认值)", style="dim") + elif mode == 'programmatic': + if not presets: + console.print("❌ 程序化模式需要提供预设配置 --presets", style="red") + return + try: + preset_dict = json.loads(presets) + analysis_agent = AnalysisAgent.create_programmatic(preset_dict) + console.print(f"📌 使用程序化模式,预设配置: {list(preset_dict.keys())}", style="dim") + except json.JSONDecodeError: + console.print("❌ 预设配置JSON格式错误", style="red") + return + else: # interactive + analysis_agent = AnalysisAgent() + console.print("📌 使用交互模式", style="dim") - if not technical_criteria and not commercial_criteria: - console.print("❌ 未找到有效的评分表", style="red") + # 执行完整的分析流程(包括目录生成) + with console.status("正在分析招标文件并生成目录结构..."): + result = analysis_agent.execute_sync(bidding_file) + + if not result.success: + console.print(f"❌ 分析失败: {result.error_message}", style="red") return - # 创建标书结构(只使用技术部分) - from ..tools.parser import BidStructure - bid_structure = BidStructure() - bid_structure.scoring_criteria = technical_criteria - bid_structure.deviation_items = deviation_items - - # 生成专业目录结构 - bid_structure.chapters = parser._generate_professional_chapters(technical_criteria) - parser._map_criteria_to_chapters(bid_structure) + # 获取分析结果 + bid_structure = result.bid_structure # 保存解析结果 import json analysis_file = project_path / "analysis_result.json" with open(analysis_file, 'w', encoding='utf-8') as f: - # 将BidStructure转为字典保存 + # 将AnalysisResult转为字典保存 data = { - "project_name": f"标书项目-{Path(bidding_file).stem}", + "project_name": project_name, "source_file": str(Path(bidding_file).absolute()), - "technical_criteria": [ - { - "item_name": c.item_name, - "max_score": c.max_score, - "description": c.description, - "category": c.category.value, - "chapter_id": c.chapter_id - } for c in technical_criteria - ], - "commercial_criteria": [ - { - "item_name": c.item_name, - "max_score": c.max_score, - "description": c.description, - "category": c.category.value, - "chapter_id": c.chapter_id - } for c in commercial_criteria - ], - "deviation_items": [ - { - "requirement": d.requirement, - "response_type": d.response_type, - "chapter_id": d.chapter_id - } for d in deviation_items - ], - "chapters": [ - _serialize_chapter(chapter) for chapter in bid_structure.chapters - ] + "success": result.success, + "technical_count": result.technical_count, + "commercial_count": result.commercial_count, + "deviation_count": result.deviation_count, + "chapter_count": result.chapter_count, + "execution_time": result.execution_time, + "warnings": result.warnings, + "bid_structure": { + "scoring_criteria": [ + { + "item_name": c.item_name, + "max_score": c.max_score, + "description": c.description, + "category": c.category.value, + "chapter_id": c.chapter_id + } for c in bid_structure.scoring_criteria + ], + "deviation_items": [ + { + "requirement": d.requirement, + "response_type": d.response_type, + "chapter_id": d.chapter_id + } for d in bid_structure.deviation_items + ], + "chapters": [ + _serialize_chapter(chapter) for chapter in bid_structure.chapters + ] + } } json.dump(data, f, ensure_ascii=False, indent=2) - # 生成任务清单 + # 生成任务清单(基于评分项) tasks = [] task_id = 1 - def _extract_tasks_from_chapters(chapters, parent_path=""): - nonlocal task_id - for chapter in chapters: - if chapter.level == 3 and chapter.score and chapter.score > 0: - # 三级标题且有分值的为具体任务 - tasks.append({ - "id": task_id, - "title": chapter.title, - "chapter_id": chapter.id, - "score": chapter.score, - "status": "pending", - "content": "", - "placeholder": chapter.template_placeholder or f"{{{{{chapter.id}_content}}}}" - }) - task_id += 1 - - if chapter.children: - _extract_tasks_from_chapters(chapter.children, f"{parent_path}/{chapter.title}") - - _extract_tasks_from_chapters(bid_structure.chapters) + # 为每个评分项创建任务 + for criteria in bid_structure.scoring_criteria: + tasks.append({ + "id": task_id, + "title": criteria.item_name, + "chapter_id": criteria.chapter_id, + "score": criteria.max_score, + "description": criteria.description, + "category": criteria.category.value, + "status": "pending", + "content": "", + "placeholder": f"{{{{{criteria.chapter_id}_content}}}}" + }) + task_id += 1 tasks_file = project_path / "tasks.json" with open(tasks_file, 'w', encoding='utf-8') as f: @@ -272,10 +286,18 @@ def new(): console.print("✅ 项目创建成功!", style="green") # 显示统计信息 - console.print(f"\n💰 识别到商务评分项: {len(commercial_criteria)}项(已排除)") - console.print(f"📊 技术评分项: {len(technical_criteria)}项") - console.print(f"📋 偏离项: {len(deviation_items)}项") + console.print(f"\n💰 识别到商务评分项: {result.commercial_count}项(已排除)") + console.print(f"📊 技术评分项: {result.technical_count}项") + console.print(f"📋 偏离项: {result.deviation_count}项") + console.print(f"📚 生成章节: {result.chapter_count}个") console.print(f"📝 生成任务: {len(tasks)}个") + console.print(f"⏱️ 处理耗时: {result.execution_time:.2f}秒") + + # 显示警告信息(如果有) + if result.warnings: + console.print(f"\n⚠️ 警告信息:", style="yellow") + for warning in result.warnings: + console.print(f" • {warning}", style="yellow") # 显示生成的文件 console.print("\n📂 生成的文件:") @@ -422,41 +444,46 @@ def smart_parse(word_file: str): console.print("❌ 只支持Word(.docx)格式文件", style="red") return - # 创建解析器 - parser = BidParser() + # 使用AnalysisAgent进行智能解析 + from ..agents.analysis import AnalysisAgent - # 智能解析单个Word文档(区分技术和商务) + # 创建静默模式的AnalysisAgent(避免交互) + analysis_agent = AnalysisAgent.create_silent() + + # 智能解析单个Word文档 with console.status("正在智能识别和解析表格..."): - technical_criteria, commercial_criteria, deviation_items = parser.parse_word_with_filter(word_file) + result = analysis_agent.execute_sync(word_file) - if not technical_criteria and not commercial_criteria and not deviation_items: - console.print("❌ 未找到有效的评分表或偏离表", style="red") + if not result.success: + console.print(f"❌ 分析失败: {result.error_message}", style="red") return - # 创建标书结构(只使用技术部分) - from ..tools.parser import BidStructure - bid_structure = BidStructure() - bid_structure.scoring_criteria = technical_criteria # 只使用技术部分 - bid_structure.deviation_items = deviation_items + # 获取分析结果 + bid_structure = result.bid_structure - # 生成专业目录结构(基于技术部分) - bid_structure.chapters = parser._generate_professional_chapters(technical_criteria) - parser._map_criteria_to_chapters(bid_structure) + if not bid_structure.scoring_criteria and not bid_structure.deviation_items: + console.print("❌ 未找到有效的评分表或偏离表", style="red") + return # 显示解析结果 console.print("✅ 智能解析完成!", style="green") - # 显示商务部分(如果有,但说明不包含在技术目录中) - if commercial_criteria: - console.print(f"\n💰 识别到商务评分项(共{len(commercial_criteria)}项,已排除):", style="yellow") - for item in commercial_criteria[:3]: - console.print(f" • {item.item_name} ({item.max_score}分)") - if len(commercial_criteria) > 3: - console.print(f" • ... 还有{len(commercial_criteria) - 3}项") + # 显示统计信息 + console.print(f"\n💰 识别到商务评分项: {result.commercial_count}项(已排除)") + console.print(f"📊 技术评分项: {result.technical_count}项(用于目录生成)") + console.print(f"📋 偏离项: {result.deviation_count}项") + console.print(f"📚 生成章节: {result.chapter_count}个") + console.print(f"⏱️ 处理耗时: {result.execution_time:.2f}秒") + + # 显示警告信息(如果有) + if result.warnings: + console.print(f"\n⚠️ 警告信息:", style="yellow") + for warning in result.warnings: + console.print(f" • {warning}", style="yellow") # 显示技术评分标准 if bid_structure.scoring_criteria: - console.print(f"\n📊 技术评分标准(共{len(technical_criteria)}项,用于目录生成):") + console.print(f"\n📊 技术评分标准详情:") table = Table(title="技术评分标准解析结果") table.add_column("技术类别", style="green") table.add_column("评分项", style="yellow") diff --git a/src/bidmaster/nodes/toc/generate_sub_chapters.py b/src/bidmaster/nodes/toc/generate_sub_chapters.py index 15de377..183cfc6 100644 --- a/src/bidmaster/nodes/toc/generate_sub_chapters.py +++ b/src/bidmaster/nodes/toc/generate_sub_chapters.py @@ -36,29 +36,9 @@ class GenerateSubChaptersNode(BaseNode): if not preliminary_chapters: raise ValueError("缺少初步章节") - # 通过context处理交互 - generation_mode = context.interact( - "choice", - key="generation_mode", - prompt="请选择章节内容生成方式", - options=[ - ("ai", "AI智能生成子标题(推荐)- 根据评分项要求智能生成2-3级标题"), - ("template", "基于模板生成 - 使用预定义模板结构") - ], - default="ai" - ) - + # 只使用AI生成,不再需要交互选择 + generation_mode = "ai" template_file = None - if generation_mode == "template": - template_file = context.interact( - "file_path", - key="template_file", - prompt="请输入模板文件路径(.docx格式)", - validation={ - "exists": True, - "extensions": [".docx"] - } - ) # 为每个章节生成子标题 enhanced_chapters = [] diff --git a/src/bidmaster/tools/parser.py b/src/bidmaster/tools/parser.py index b69c0c3..fa6ee38 100644 --- a/src/bidmaster/tools/parser.py +++ b/src/bidmaster/tools/parser.py @@ -62,72 +62,6 @@ class DocumentChapter(BaseModel): template_placeholder: str | None = Field(default=None, description="模板占位符") -class ChapterTemplate: - """标准章节模板""" - - STANDARD_CHAPTERS = { - "evaluation_index": { - "id": "eval_index", - "title": "1. 评标索引表(技术评分完全对应)", - "level": 1, - "placeholder": "{{evaluation_index_content}}" - }, - "compliance_response": { - "id": "compliance", - "title": "2. 实质性响应/星号条款偏离表", - "level": 1, - "placeholder": "{{compliance_response_content}}" - }, - "technical_solution": { - "id": "tech_solution", - "title": "3. 总体技术方案", - "level": 1, - "placeholder": "{{technical_solution_content}}" - }, - "equipment_spec": { - "id": "equipment", - "title": "4. 关键设备规格书及检测报告", - "level": 1, - "placeholder": "{{equipment_spec_content}}" - }, - "implementation": { - "id": "implementation", - "title": "5. 项目实施与交付计划", - "level": 1, - "placeholder": "{{implementation_content}}" - }, - "quality_system": { - "id": "quality", - "title": "6. 质量、安全、环境体系", - "level": 1, - "placeholder": "{{quality_system_content}}" - }, - "after_sales": { - "id": "after_sales", - "title": "7. 运维服务及备品备件", - "level": 1, - "placeholder": "{{after_sales_content}}" - }, - "contract_delivery": { - "id": "delivery", - "title": "8. 验收与绩效考核对应表", - "level": 1, - "placeholder": "{{contract_delivery_content}}" - } - } - - @classmethod - def get_category_chapter_mapping(cls) -> dict[TechnicalCategory, str]: - """获取技术类别到章节的映射""" - return { - TechnicalCategory.TECHNICAL_SOLUTION: "technical_solution", - TechnicalCategory.EQUIPMENT_SPEC: "equipment_spec", - TechnicalCategory.IMPLEMENTATION: "implementation", - TechnicalCategory.QUALITY_SAFETY: "quality_system", - TechnicalCategory.AFTER_SALES: "after_sales", - TechnicalCategory.COMPLIANCE: "compliance_response", - TechnicalCategory.OTHER: "technical_solution" - } class BidStructure(BaseModel): @@ -181,12 +115,7 @@ class BidParser: # 解析Word模板(可选) if template_file: bid_structure.chapters = self._parse_template_file(template_file) - else: - # 生成专业目录结构 - bid_structure.chapters = self._generate_professional_chapters(bid_structure.scoring_criteria) - - # 重新映射评分项到对应章节 - self._map_criteria_to_chapters(bid_structure) + # 注意:章节生成现在完全由TocAgent负责,不在BidParser中处理 return bid_structure @@ -748,161 +677,3 @@ class BidParser: return chapters - def _group_scoring_items(self, scoring_criteria: List[ScoringCriteria], category: TechnicalCategory) -> dict[str, List[ScoringCriteria]]: - """对同一类别下的评分项进行智能分组""" - # 过滤出指定类别的评分项 - category_items = [item for item in scoring_criteria if item.category == category] - - if not category_items: - return {} - - groups = {} - - for item in category_items: - item_name = item.item_name - group_key = None - - # 规则1:识别前缀模式(如"平台要求-xxx") - if "-" in item_name: - prefix = item_name.split("-")[0].strip() - if len(prefix) <= 10: # 前缀不能太长 - group_key = f"{prefix}要求" - - # 规则2:识别关键词分组 - if not group_key: - keywords_mapping = { - "原型": "系统原型设计", - "展示": "系统原型设计", - "方案": "方案设计", - "投标": "方案设计", - "人员": "人员配置方案", - "配置": "人员配置方案", - "测试": "测试质量保障", - "工具": "测试质量保障", - "质保": "质保服务方案", - "售后": "售后服务方案", - "服务": "售后服务方案", - "企业": "企业资质证明", - "实力": "企业资质证明", - "认证": "技术认证证书", - "证书": "技术认证证书", - "适配": "技术认证证书" - } - - for keyword, group_name in keywords_mapping.items(): - if keyword in item_name: - group_key = group_name - break - - # 规则3:默认分组 - if not group_key: - group_key = "其他要求" - - if group_key not in groups: - groups[group_key] = [] - groups[group_key].append(item) - - return groups - - def _add_sub_chapters(self, parent_chapter: DocumentChapter, groups: dict[str, List[ScoringCriteria]], chapter_num: str) -> None: - """为父章节添加二三级子章节""" - if not groups: - return - - sub_chapter_index = 1 - for group_name, scoring_items in groups.items(): - # 创建二级标题 - sub_chapter_id = f"{parent_chapter.id}_{sub_chapter_index:02d}" - sub_chapter_title = f"{chapter_num}.{sub_chapter_index} {group_name}" - - sub_chapter = DocumentChapter( - id=sub_chapter_id, - title=sub_chapter_title, - level=2, - template_placeholder=f"{{{{{sub_chapter_id}_content}}}}" - ) - - # 为二级标题添加三级标题(具体评分项) - item_index = 1 - for scoring_item in scoring_items: - item_chapter_id = f"{sub_chapter_id}_{item_index:02d}" - item_title = f"{chapter_num}.{sub_chapter_index}.{item_index} {scoring_item.item_name}" - if scoring_item.max_score > 0: - item_title += f" ({scoring_item.max_score}分)" - - item_chapter = DocumentChapter( - id=item_chapter_id, - title=item_title, - level=3, - score=scoring_item.max_score, - template_placeholder=f"{{{{{item_chapter_id}_content}}}}" - ) - - sub_chapter.children.append(item_chapter) - item_index += 1 - - parent_chapter.children.append(sub_chapter) - sub_chapter_index += 1 - - def _generate_professional_chapters(self, scoring_criteria: List[ScoringCriteria]) -> List[DocumentChapter]: - """基于评分标准生成专业三级目录结构""" - chapters = [] - - # 1. 评标索引表(始终包含) - chapters.append(self._create_standard_chapter("evaluation_index")) - - # 2. 合规响应表(始终包含) - compliance_chapter = self._create_standard_chapter("compliance_response") - # 为合规章节添加二三级标题 - compliance_groups = self._group_scoring_items(scoring_criteria, TechnicalCategory.COMPLIANCE) - self._add_sub_chapters(compliance_chapter, compliance_groups, "2") - chapters.append(compliance_chapter) - - # 3-7. 技术章节 - technical_chapters = [ - ("technical_solution", TechnicalCategory.TECHNICAL_SOLUTION, "3"), - ("equipment_spec", TechnicalCategory.EQUIPMENT_SPEC, "4"), - ("implementation", TechnicalCategory.IMPLEMENTATION, "5"), - ("quality_system", TechnicalCategory.QUALITY_SAFETY, "6"), - ("after_sales", TechnicalCategory.AFTER_SALES, "7") - ] - - for chapter_key, category, chapter_num in technical_chapters: - chapter = self._create_standard_chapter(chapter_key) - # 为每个技术章节添加二三级标题 - category_groups = self._group_scoring_items(scoring_criteria, category) - self._add_sub_chapters(chapter, category_groups, chapter_num) - chapters.append(chapter) - - # 8. 验收与绩效考核对应表(始终包含) - chapters.append(self._create_standard_chapter("contract_delivery")) - - return chapters - - def _create_standard_chapter(self, chapter_key: str) -> DocumentChapter: - """创建标准章节""" - template = ChapterTemplate.STANDARD_CHAPTERS[chapter_key] - return DocumentChapter( - id=template["id"], - title=template["title"], - level=template["level"], - template_placeholder=template["placeholder"] - ) - - def _map_criteria_to_chapters(self, bid_structure: BidStructure) -> None: - """将评分标准映射到对应章节""" - category_mapping = ChapterTemplate.get_category_chapter_mapping() - - # 创建章节ID映射表 - chapter_id_map = {} - for chapter in bid_structure.chapters: - # 从标准章节找到对应的category_key - for category_key, template_data in ChapterTemplate.STANDARD_CHAPTERS.items(): - if template_data["id"] == chapter.id: - chapter_id_map[category_key] = chapter.id - break - - # 映射评分项到对应章节 - for criteria in bid_structure.scoring_criteria: - category_chapter_key = category_mapping.get(criteria.category, "technical_solution") - criteria.chapter_id = chapter_id_map.get(category_chapter_key, "tech_solution") \ No newline at end of file diff --git a/uv.lock b/uv.lock index f323870..5eb7113 100644 --- a/uv.lock +++ b/uv.lock @@ -195,7 +195,7 @@ wheels = [ [[package]] name = "bidmaster-cli" version = "0.1.0" -source = { virtual = "." } +source = { editable = "." } dependencies = [ { name = "chromadb" }, { name = "click" },