from pathlib import Path import hashlib import json import shutil folder = Path(__file__).parent root = Path('C:/wechat_rpa') read = lambda name: json.loads((folder / name).read_text(encoding='utf-8-sig')) plan = read('review-voice-release-plan.json') tests = read('frozen-review-voice-tests.json') notifications = read('frozen-review-voice-notifications.json') frozen = read('frozen-release-qa.json') integrity = read('nsis-payload-integrity.json') asr = read('frozen-offline-asr.json') assert plan['finalized'] and plan['version'] == '1.4.27' assert tests['tests_run'] > 0 and not any(tests[k] for k in ('failures', 'errors', 'skipped', 'blocked_external_actions')) assert notifications['ok'] and notifications['passed'] == plan['notificationExpectedTests'] assert not notifications['skipped'] and not notifications['blocked_external_actions'] assert frozen['sourceManifestMatches'] and frozen['privateFilesExcluded'] and frozen['uiAssetsMatchSource'] assert integrity['crcPassed'] and integrity['completeDeflateStream'] and not integrity['missingFiles'] assert asr['ok'] and len(asr['results']) == 3 assert not asr['site_packages_leaks'] and not asr['escaped_dlls'] for name, digest in read('build-source-manifest.json').items(): assert hashlib.sha256((root / name).read_bytes()).hexdigest() == digest, name old = root / 'releases/甄AI客服-安装包-v1.4.26.exe' assert hashlib.sha256(old.read_bytes()).hexdigest() == plan['previousInstallerSha256'] installer = root / 'dist/installer/甄AI客服-安装包-v1.4.27.exe' release = root / 'releases' / installer.name digest = hashlib.sha256(installer.read_bytes()).hexdigest() assert digest == integrity['installerSha256'] if release.exists(): assert hashlib.sha256(release.read_bytes()).hexdigest() == digest else: shutil.copy2(installer, release) assert hashlib.sha256(release.read_bytes()).hexdigest() == digest report = {'version': '1.4.27', 'installer': str(release), 'bytes': release.stat().st_size, 'sha256': digest, 'frozenRegressionTests': tests['tests_run'], 'frozenNotificationTests': notifications['passed'], 'frozenAsrFormats': 3, 'realMessagesSent': 0, 'existingSettingsChanged': False, 'installed': False, 'cloudDeploymentNeeded': False, 'oldInstallerPreserved': True} (folder / 'release-v1.4.27.json').write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding='utf-8') (folder / 'RESULT.md').write_text(f'''# 审核提醒、人工完成与语音转文字 v1.4.27 待审核和需人工(包括模型失败、媒体无法读取、发送失败、回执待核对)统一进入绑定医疗助理提醒链路;相同待处理会话复用提醒,不重复发送结果未知的通知。当前托管账号直接回复客户后核验账号、会话、服务器消息及发送日志,任务显示“人工已完成”。旧 AI 草稿作废,后续来信重新生成并逐条风控;回复提醒本身不审批客户任务。 语音优先读取当前账号精确服务器消息 ID 对应的企业微信转写缓存;缺失时,仅对该消息精确引用的本账号本地音频进行离线识别。模型及 SILK/AMR/WAV 解码组件已内置,不运行时下载模型或上传音频。文字与同批补充内容共同进入问答和风控。转写变动时旧草稿和批准失效,重新生成。 索引与识别在后台执行。等待语音的任务让出主循环,其他会话继续处理;语音等待和人工状态持久化,数据库暂时繁忙或重启不会绕过等待/人工处理。180 秒仍未取得文字或识别失败时转需人工并提醒。没有本机音频且无转写缓存时不会编造语音内容。 最终源码集成 700 项通过。实际 EXE 内冻结模块回归 {tests['tests_run']} 项、提醒回归 {notifications['passed']} 项通过;实际包内依赖及模型对三格式合成中文音频离线识别成功,无构建环境依赖回退。安装包 CRC、压缩流、全部文件哈希及私有文件排除检查通过。 安装包:`{release}` SHA256:`{digest}` 两目录已定向修复;生产版本为 1.4.27,视觉源码目录保留自己的版本序列。旧 1.4.26 安装包保留。未自动安装、重启、修改用户配置/队列或发送真实消息;无需管理端部署。退出托盘中的旧客户端后安装新版并重新打开。现有绑定收件人和开启状态不自动更改。 ''', encoding='utf-8') print(json.dumps(report, ensure_ascii=False))