1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
import json
from typing import Any, Dict, List
from .base import BaseRenderer
class JSONRenderer(BaseRenderer):
def __init__(self, pretty: bool = True, indent: int = 2, sort_keys: bool = False):
super().__init__()
self.pretty = pretty
self.indent = indent if pretty else None
self.sort_keys = sort_keys
self.style = {}
def render(self, data: Any) -> str:
if self.pretty and isinstance(data, list):
output = {
"metadata": {
"total_entries": len(data),
"renderer": "ConventionalRP JSONRenderer",
"version": "1.0.0",
},
"statistics": self._calculate_stats(data),
"data": data,
}
else:
output = data
return json.dumps(
output,
ensure_ascii=False,
indent=self.indent,
sort_keys=self.sort_keys,
)
def _calculate_stats(self, data: List[Dict[str, Any]]) -> Dict[str, Any]:
stats = {
"dialogue": 0,
"dice": 0,
"narration": 0,
"system": 0,
"success": 0,
"failure": 0,
"other": 0,
}
speakers = set()
for item in data:
if not isinstance(item, dict):
continue
token_type = item.get("type", "unknown")
if token_type in stats:
stats[token_type] += 1
else:
stats["other"] += 1
if "speaker" in item and item["speaker"]:
speakers.add(item["speaker"])
stats["unique_speakers"] = len(speakers)
stats["speakers"] = sorted(list(speakers))
return stats
def set_style(self, style):
self.style = style
# 从 style 中提取设置
if isinstance(style, dict):
if "pretty" in style:
self.pretty = style["pretty"]
self.indent = 2 if self.pretty else None
if "indent" in style:
self.indent = style["indent"]
if "sort_keys" in style:
self.sort_keys = style["sort_keys"]
|