from pathlib import Path import json,hashlib,tarfile root=Path('C:/kefu');release=root/'deploy/knowledge-v3-field-fix-20260916';release.mkdir(exist_ok=True) p=root/'wechat_rpa/KNOWLEDGE.md';s=p.read_text(encoding='utf-8') section=''' ## 模型字段异常修复(2026-09-16) 模型返回空标题、分类、适用条件或非标准类型不再使整项任务失败:标题从有效问题生成,分类保留待分类,适用条件留空并要求人工补充,类型在校验后采用标准值。 标题可缩短至 160 字符;问题、答案和原始来源不静默截断。核心问答缺失、类型不正确、超过限制或 JSON 不完整时,该条转为保留原始脱敏问答的待审草稿,记录具体原因,后续候选继续处理。适用条件置空,未人工编辑补齐前不能审核或发布。格式异常次数、最近原因与输入输出字符量随单条结果一起保存。 网络、授权、模型限流、调用预算耗尽仍会暂停并报错,避免把服务故障误当作可用模型结果。待处理的旧任务继续兼容,无需重建或清零进度。 验证:`python -m unittest test_knowledge test_knowledge_tasks test_knowledge_model_output test_model_gateway -q`,外加本机隔离浏览器验收。真实失败响应未保存,无法还原具体缺失字段;线上只读检查与修复验收不重发真实聊天。 ''' if '## 模型字段异常修复(2026-09-16)' not in s: p.write_text(s+section,encoding='utf-8',newline='\n') files=[root/'wechat_rpa'/name for name in ['knowledge_worker.py','knowledge_model_output.py','test_knowledge_model_output.py','KNOWLEDGE.md']] files += [root/'admin-web/apps/web-antd/src'/name for name in ['api/knowledge.ts','views/knowledge/center.vue']] files += [p for p in (root/'admin-web/apps/web-antd/dist').rglob('*') if p.is_file()] manifest=[] with tarfile.open(release/'payload.tar.gz','w:gz') as tf: for path in files: name=path.relative_to(root).as_posix();data=path.read_bytes();tf.add(path,arcname=name) manifest.append({'path':name,'bytes':len(data),'sha256':hashlib.sha256(data).hexdigest()}) (release/'manifest.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8') previous=root/'deploy/knowledge-v3-20260916' for name in ['01-stage.sh','02-backup-build.sh','03-deploy.sh','04-verify.sh','Dockerfile.overlay']: text=(previous/name).read_text(encoding='utf-8').replace('knowledge-v3-20260916','knowledge-v3-field-fix-20260916') if name=='01-stage.sh': text=text.replace('sha256:c73e1952e9edcdb1ce5c516b0f54d728ce5b11f57de77e1bee31b1effc51d763','sha256:15bf0aa7a0041b5b79cee60c3fc21e888ca87d3268abf183e5644ac5efd784de') text=text.replace('/home/ps/knowledge-v2-20260916/manifest.json','/home/ps/knowledge-v3-20260916/manifest.json').replace('verified second release','verified third release') if name=='02-backup-build.sh': text=text.replace('test_knowledge test_knowledge_tasks test_model_gateway','test_knowledge test_knowledge_tasks test_knowledge_model_output test_model_gateway') (release/name).write_text(text,encoding='utf-8',newline='\n') # Previous V3 consumes the same durable pending queue, so normal code-only rollback is compatible. rollback=(root/'deploy/knowledge-v2-20260916/rollback.sh').read_text(encoding='utf-8').replace('knowledge-v2-20260916','knowledge-v3-field-fix-20260916') (release/'rollback.sh').write_text(rollback,encoding='utf-8',newline='\n') print(json.dumps({'files':len(manifest),'bytes':(release/'payload.tar.gz').stat().st_size}))