"""Read-only state/config diagnosis; output no tokens, names or conversation text.""" from pathlib import Path import sys, json, os, collections sys.dont_write_bytecode = True sys.path.insert(0, 'C:/wechat_rpa') import backend_client root = Path(os.environ['LOCALAPPDATA']) / 'ZhenYangTangRPA' read = lambda p: json.loads(p.read_text(encoding='utf-8-sig')) connection = read(root / 'backend_connection.json') settings = read(root / 'app_settings.json') config = read(root / 'ai_settings.json') summary = { 'installed': {'send_mode': settings.get('send_mode'), 'transport': settings.get('reply_transport'), 'last_sync_at': connection.get('last_sync_at'), 'config_version': connection.get('last_version'), 'sync_error_present': bool(connection.get('last_error')), 'judge_enabled': config.get('AI_JUDGE_ENABLED'), 'judge_mode': config.get('AI_JUDGE_MODE'), 'review_rules_enabled': [r.get('enabled') for r in config.get('AI_REVIEW_RULES', [])], 'gateway_judge_mode': (connection.get('model_plan', {}).get('roles') or {}).get('judge_mode')}, } protocol = read(root / 'pending_replies.protocol.json') summary['installed']['pending_protocol_conversations'] = len(protocol.get('pending') or {}) try: token = backend_client._unprotect_secret(connection.get('desktop_token_protected')) if not token: raise RuntimeError('No cached desktop token') response, path = backend_client._fetch_desktop_config(connection.get('server_url') or backend_client.DEFAULT_SERVER_URL, token, 10) c = response.get('config') or {} summary['server'] = {'config_version': response.get('version'), 'judge_enabled': c.get('AI_JUDGE_ENABLED'), 'judge_mode': c.get('AI_JUDGE_MODE'), 'review_rules_enabled': [r.get('enabled') for r in c.get('AI_REVIEW_RULES', [])], 'gateway_judge_mode': (response.get('roles') or {}).get('judge_mode'), 'read_only_path': path} except Exception as exc: summary['server'] = {'read_error_type': type(exc).__name__, 'http_status': getattr(exc, 'status', None)} categories = {'shadow_high_risk': '模型裁判评估为高风险', 'keyword_rule': '命中审核规则', 'global_review': '人工审核后点击', 'receipt_check': '发送结果待人工核对'} counts = collections.Counter() for path in (root / 'logs').rglob('*.log'): # Bounded scan of the recent tail only. Do not output raw log messages. with path.open('rb') as handle: handle.seek(max(0, path.stat().st_size - 2_000_000)) lines = handle.read().decode('utf-8', errors='replace').splitlines() for line in lines: for label, needle in categories.items(): if needle in line: counts[label] += 1 summary['recent_log_reason_mentions'] = dict(counts) destination = Path(__file__).parent / 'review-diagnosis.json' destination.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding='utf-8') print(json.dumps(summary, ensure_ascii=False, indent=2))