realtimex-deeptutor 0.5.0.post2__py3-none-any.whl → 0.5.0.post3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: realtimex-deeptutor
3
- Version: 0.5.0.post2
3
+ Version: 0.5.0.post3
4
4
  Summary: RealTimeX DeepTutor - Intelligent learning companion with multi-agent collaboration and LightRAG
5
5
  License: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -1,5 +1,14 @@
1
1
  realtimex_deeptutor/__init__.py,sha256=sSfuCLjJa6BnayszcU4azNl_sr1OzuKgLP10BAtdoh8,1567
2
- realtimex_deeptutor-0.5.0.post2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
2
+ realtimex_deeptutor-0.5.0.post3.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
3
+ scripts/__init__.py,sha256=mxMsCbci-Qon3qWU1JIi93-tYlHAy0NIUbDRmAPVcg0,54
4
+ scripts/audit_prompts.py,sha256=Ltuk7tvsjpKhiobVbYq1volgVFKiVLgSTaE_Is4MGaM,5651
5
+ scripts/check_install.py,sha256=GbApEcDLJ6r0QmYrCVHAFCOK4wolpSLwL3eBRmmD3og,13929
6
+ scripts/generate_roster.py,sha256=COsJ12bvZ5W9TI-wAvKpknKBgHr9uQTvJ_JCz2gVMVo,12369
7
+ scripts/install_all.py,sha256=u-A3eLhk1ua_KCjz8WZMkrVNJN6QdYs7NhGOcsm-Mks,23875
8
+ scripts/migrate_kb.py,sha256=uyJgplkJag35rT2RrwSiT37__gpB4TiA0xh5uVcWIa4,19667
9
+ scripts/start.py,sha256=EYbyjryor0DN_WcxQMSkKWCboM9UjMkv61fWhLyv63I,30300
10
+ scripts/start_web.py,sha256=vzn7TiW7g2RNpAKYPQjHVNtOt6G9MxokEnZE_YWfHu4,22980
11
+ scripts/sync_prompts_from_en.py,sha256=TkBSFilYSwnwo0a3cgRnJ84i02zByAIW12N3ePzBwE8,4677
3
12
  src/__init__.py,sha256=UNw3C20mbskiQF3rK3HhjglrG8snhfuiVthc5UsoHX0,1046
4
13
  src/agents/__init__.py,sha256=IPhP4RZnCH2kcUDBkdKHO_ciVdyWnuHUCG2flG5Ydcw,885
5
14
  src/agents/base_agent.py,sha256=9mntPOWGN9RRlqfy4MBm52TVEZCGBq-uP_zsvoJHbHo,22930
@@ -141,7 +150,7 @@ src/api/utils/notebook_manager.py,sha256=4zTn_J10BmWlCaCJo3bcNWiWUGgLw4hGR92sfj3
141
150
  src/api/utils/progress_broadcaster.py,sha256=u1cfxZ2Rek9tSP9sP1hdQMQkh6Dr_6fhzJjBUvFf-3I,2772
142
151
  src/api/utils/task_id_manager.py,sha256=E59dJ2rg-_qY7uACNT3Nmzey0fnpZgfMYerW-8QsaNM,3687
143
152
  src/cli/__init__.py,sha256=MQ18rJWUlLlk_keWk7lrCjOYW5c_kDfJr5roKDu5ZT8,269
144
- src/cli/start.py,sha256=Tr0Vyk7JzhLsZqkUpt20pSpb8laumHzPDuFVbNvk8iU,6600
153
+ src/cli/start.py,sha256=KNQ4ulAB4QCcS39Z5TcYWw4UtTzfEFCJg_yZOtg-Brw,6664
145
154
  src/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
155
  src/config/accessors.py,sha256=A06OaUK78MdgLu__6MRcKcVoog1ctDj5fHP4APOyRiI,534
147
156
  src/config/constants.py,sha256=C3370U6qkFExKkoNyDDLcf05FIJU0_5MHvpT6mvDQ7A,734
@@ -175,7 +184,7 @@ src/services/__init__.py,sha256=91ZEKiPyPtwFgYRtmkKBrdYAZKVnREUw43itPM5n-WM,1851
175
184
  src/services/config/__init__.py,sha256=Vjt0TORUt358yZvNCgoIVnuWJWVPuYiNA6ge9DV-Dyo,1792
176
185
  src/services/config/knowledge_base_config.py,sha256=l6QlAivVCBf1Q23YaEkHIHvq3TmsowPJmjDASezBf8c,7266
177
186
  src/services/config/loader.py,sha256=1PXImuGe8RpJ8UQpyGcsRhkq_YL9kWJq2f1ylQE4N3Y,8068
178
- src/services/config/unified_config.py,sha256=zflsAU_XiHNBbVe4uaQX1k1UqVUsGJyMNL8fnir5Hss,32370
187
+ src/services/config/unified_config.py,sha256=3sPs06oU0j6BjPZObh5Zoc1eLDusa1qa8HPGU9rncdY,32338
179
188
  src/services/embedding/__init__.py,sha256=ljDq50as6CkKNHK2sSQtX_iXu9TyOMhzzFNs2f7QYKs,1338
180
189
  src/services/embedding/client.py,sha256=X5iUbGuXjtk_6Nkl7N4eRXjbL5hPY46JcTfi65UZWus,6003
181
190
  src/services/embedding/config.py,sha256=vBJjsTcYLsIpy0bmR7V8etu8eAXdRShjQIYIMcqwIgU,5368
@@ -280,8 +289,8 @@ src/utils/error_utils.py,sha256=ME_9q-DlmxFl-Xvv3ETPZE_iP705x6MXiuAREgWYsjM,2262
280
289
  src/utils/json_parser.py,sha256=M_KfrsrNvQPSiFvpKHQV79Aj85_MEcLVc6hnKzvTV58,3243
281
290
  src/utils/realtimex.py,sha256=WlGeZ7d-ymXIJ6ZYK2nhjqxArV_7rVHHJLCqaNkcOUw,8648
282
291
  src/utils/network/circuit_breaker.py,sha256=BtjogK5R3tG8fuJniS5-PJKZMtwD5P2SkP2JFiQ9sRA,2722
283
- realtimex_deeptutor-0.5.0.post2.dist-info/METADATA,sha256=TdThltCbaHHOVYhU14uyDrVjtPaZNU95PEVd5n6QcCM,58304
284
- realtimex_deeptutor-0.5.0.post2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
285
- realtimex_deeptutor-0.5.0.post2.dist-info/entry_points.txt,sha256=slNAzwRLUpqiMtDRZBQIkXbU2vGMHL_om6-o19gYdh8,134
286
- realtimex_deeptutor-0.5.0.post2.dist-info/top_level.txt,sha256=gmpYj9KuYOk3tTiHiVMhkL2kJYHDR0lejS47k5ROBU4,24
287
- realtimex_deeptutor-0.5.0.post2.dist-info/RECORD,,
292
+ realtimex_deeptutor-0.5.0.post3.dist-info/METADATA,sha256=cPG-bhP_0bk97uBwQaN9OzVTH9YiVceBLDrNM4_yv8Q,58304
293
+ realtimex_deeptutor-0.5.0.post3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
294
+ realtimex_deeptutor-0.5.0.post3.dist-info/entry_points.txt,sha256=slNAzwRLUpqiMtDRZBQIkXbU2vGMHL_om6-o19gYdh8,134
295
+ realtimex_deeptutor-0.5.0.post3.dist-info/top_level.txt,sha256=zUAd6V7jDYhdL7bvg2S38YCM-gVhvd36WqkjxrT-02I,32
296
+ realtimex_deeptutor-0.5.0.post3.dist-info/RECORD,,
scripts/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # Scripts package - included for package distribution
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Audit prompt parity between prompts/en and prompts/zh|prompts/cn.
6
+
7
+ Checks:
8
+ - Missing/extra keys (recursive)
9
+ - Placeholder drift in string templates (e.g. {question}, {context})
10
+
11
+ Usage:
12
+ python scripts/audit_prompts.py
13
+ python scripts/audit_prompts.py --fail
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ from dataclasses import dataclass
20
+ from pathlib import Path
21
+ import re
22
+ import sys
23
+ from typing import Any, Iterable
24
+
25
+ import yaml
26
+
27
+ PROJECT_ROOT = Path(__file__).resolve().parents[1]
28
+ AGENTS_DIR = PROJECT_ROOT / "src" / "agents"
29
+
30
+ # Template placeholders are expected to be like {topic}, {knowledge_title}, etc.
31
+ # Avoid false positives from LaTeX (\frac{1}{3}) and Mermaid (B{{Processing}}).
32
+ PLACEHOLDER_RE = re.compile(r"(?<!\{)\{[A-Za-z_][A-Za-z0-9_]*\}(?!\})")
33
+
34
+
35
+ def _load_yaml(path: Path) -> Any:
36
+ with open(path, encoding="utf-8") as f:
37
+ return yaml.safe_load(f) or {}
38
+
39
+
40
+ def _iter_yaml_files(root: Path) -> Iterable[Path]:
41
+ if not root.exists():
42
+ return []
43
+ return sorted([p for p in root.rglob("*.yaml") if p.is_file()])
44
+
45
+
46
+ def _get_placeholders(value: Any) -> set[str]:
47
+ found: set[str] = set()
48
+ if isinstance(value, str):
49
+ found |= set(PLACEHOLDER_RE.findall(value))
50
+ elif isinstance(value, dict):
51
+ for v in value.values():
52
+ found |= _get_placeholders(v)
53
+ elif isinstance(value, list):
54
+ for v in value:
55
+ found |= _get_placeholders(v)
56
+ return found
57
+
58
+
59
+ def _collect_keys(value: Any, prefix: str = "") -> set[str]:
60
+ """
61
+ Collect dotted key paths for all dict nodes.
62
+ Leaves (non-dict) are also included as paths.
63
+ """
64
+ keys: set[str] = set()
65
+ if isinstance(value, dict):
66
+ for k, v in value.items():
67
+ path = f"{prefix}.{k}" if prefix else str(k)
68
+ keys.add(path)
69
+ keys |= _collect_keys(v, path)
70
+ elif isinstance(value, list):
71
+ # Lists: we don't expand indices; still consider it a leaf container.
72
+ if prefix:
73
+ keys.add(prefix)
74
+ else:
75
+ if prefix:
76
+ keys.add(prefix)
77
+ return keys
78
+
79
+
80
+ @dataclass
81
+ class Diff:
82
+ missing_zh: list[str]
83
+ extra_zh: list[str]
84
+ placeholder_missing_zh: list[str]
85
+ placeholder_extra_zh: list[str]
86
+
87
+
88
+ def _diff(en_obj: Any, zh_obj: Any) -> Diff:
89
+ en_keys = _collect_keys(en_obj)
90
+ zh_keys = _collect_keys(zh_obj)
91
+
92
+ en_ph = _get_placeholders(en_obj)
93
+ zh_ph = _get_placeholders(zh_obj)
94
+
95
+ return Diff(
96
+ missing_zh=sorted(en_keys - zh_keys),
97
+ extra_zh=sorted(zh_keys - en_keys),
98
+ placeholder_missing_zh=sorted(en_ph - zh_ph),
99
+ placeholder_extra_zh=sorted(zh_ph - en_ph),
100
+ )
101
+
102
+
103
+ def main() -> int:
104
+ parser = argparse.ArgumentParser()
105
+ parser.add_argument("--fail", action="store_true", help="exit non-zero on any issue")
106
+ args = parser.parse_args()
107
+
108
+ if not AGENTS_DIR.exists():
109
+ print(f"Agents directory not found: {AGENTS_DIR}", file=sys.stderr)
110
+ return 2
111
+
112
+ issues = 0
113
+
114
+ for module_dir in sorted([p for p in AGENTS_DIR.iterdir() if p.is_dir()]):
115
+ prompts_dir = module_dir / "prompts"
116
+ en_dir = prompts_dir / "en"
117
+ if not en_dir.exists():
118
+ continue
119
+
120
+ # Prefer zh if exists, else cn if exists (but we also compare against cn if present)
121
+ zh_dir = prompts_dir / "zh"
122
+ cn_dir = prompts_dir / "cn"
123
+
124
+ for en_file in _iter_yaml_files(en_dir):
125
+ rel = en_file.relative_to(en_dir)
126
+ candidates = []
127
+ if zh_dir.exists():
128
+ candidates.append(("zh", zh_dir / rel))
129
+ if cn_dir.exists():
130
+ candidates.append(("cn", cn_dir / rel))
131
+
132
+ if not candidates:
133
+ continue
134
+
135
+ en_obj = _load_yaml(en_file)
136
+
137
+ for lang_name, zh_file in candidates:
138
+ if not zh_file.exists():
139
+ issues += 1
140
+ print(f"[MISSING {lang_name}] {module_dir.name}: {rel.as_posix()}")
141
+ continue
142
+
143
+ zh_obj = _load_yaml(zh_file)
144
+ d = _diff(en_obj, zh_obj)
145
+
146
+ if d.missing_zh or d.extra_zh or d.placeholder_missing_zh or d.placeholder_extra_zh:
147
+ issues += 1
148
+ print(f"[DIFF {lang_name}] {module_dir.name}: {rel.as_posix()}")
149
+ if d.missing_zh:
150
+ print(" - missing keys:")
151
+ for k in d.missing_zh[:50]:
152
+ print(f" - {k}")
153
+ if len(d.missing_zh) > 50:
154
+ print(f" ... ({len(d.missing_zh) - 50} more)")
155
+ if d.extra_zh:
156
+ print(" - extra keys:")
157
+ for k in d.extra_zh[:50]:
158
+ print(f" - {k}")
159
+ if len(d.extra_zh) > 50:
160
+ print(f" ... ({len(d.extra_zh) - 50} more)")
161
+ if d.placeholder_missing_zh:
162
+ print(" - missing placeholders:")
163
+ for p in d.placeholder_missing_zh:
164
+ print(f" - {p}")
165
+ if d.placeholder_extra_zh:
166
+ print(" - extra placeholders:")
167
+ for p in d.placeholder_extra_zh:
168
+ print(f" - {p}")
169
+
170
+ if issues == 0:
171
+ print("OK: prompts are structurally aligned (keys/placeholders).")
172
+ return 0
173
+
174
+ print(f"Found {issues} prompt parity issue(s).")
175
+ return 1 if args.fail else 0
176
+
177
+
178
+ if __name__ == "__main__":
179
+ raise SystemExit(main())