@furongjun1999/dsh-memory 0.5.0 → 0.5.1

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.
Files changed (138) hide show
  1. package/README.md +552 -465
  2. package/docs/README.md +1 -0
  3. package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
  4. package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
  5. package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
  6. package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
  7. package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
  8. package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
  9. package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
  10. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
  11. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
  12. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
  13. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
  14. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
  15. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
  16. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
  17. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
  18. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
  19. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
  20. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
  21. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
  22. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
  23. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
  24. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
  25. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
  26. package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
  27. package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
  28. package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +19 -3
  29. package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
  30. package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
  31. package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
  32. package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
  33. package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
  34. package/lib/bridge.d.ts +9 -0
  35. package/lib/bridge.js +35 -0
  36. package/lib/index.js +7 -1
  37. package/lib/lib/roleplay_web.js +530 -443
  38. package/lib/lib/token_store.d.ts +7 -1
  39. package/lib/lib/token_store.js +12 -3
  40. package/md_cg/audit.py +12 -1
  41. package/md_cg/backfill.py +16 -15
  42. package/md_cg/backfill_bucket_zh.py +35 -0
  43. package/md_cg/bench_e2e_judge.py +532 -0
  44. package/md_cg/bench_e2e_locomo_qa.py +368 -0
  45. package/md_cg/bench_e2e_qa.py +256 -0
  46. package/md_cg/branches.py +18 -2
  47. package/md_cg/ccgc.py +3 -2
  48. package/md_cg/chain.py +19 -4
  49. package/md_cg/consolidate.py +7 -6
  50. package/md_cg/crosscheck.py +4 -3
  51. package/md_cg/crypto.py +439 -437
  52. package/md_cg/datapath.py +395 -335
  53. package/md_cg/evidence.py +582 -580
  54. package/md_cg/export.py +3 -1
  55. package/md_cg/forgetting.py +2 -2
  56. package/md_cg/fsutil.py +48 -0
  57. package/md_cg/hotcache.py +255 -238
  58. package/md_cg/interop.py +161 -22
  59. package/md_cg/judgment_manifest.py +177 -0
  60. package/md_cg/links.py +655 -622
  61. package/md_cg/mcp_server.py +280 -29
  62. package/md_cg/mdcg.py +616 -125
  63. package/md_cg/mdcos.py +430 -66
  64. package/md_cg/mreview/govern.py +5 -4
  65. package/md_cg/postings.py +4 -2
  66. package/md_cg/readcache.py +76 -18
  67. package/md_cg/reconcile.py +228 -0
  68. package/md_cg/review_cli.py +170 -0
  69. package/md_cg/routing.py +28 -0
  70. package/md_cg/run_tests.py +211 -0
  71. package/md_cg/scrub.py +862 -852
  72. package/md_cg/security.py +385 -275
  73. package/md_cg/selfreport.py +3 -2
  74. package/md_cg/signer.py +565 -562
  75. package/md_cg/sources.py +3 -2
  76. package/md_cg/stg.py +6 -0
  77. package/md_cg/sustain.py +1168 -1138
  78. package/md_cg/test_access_hints.py +147 -0
  79. package/md_cg/test_branch_discard_tombstone.py +136 -0
  80. package/md_cg/test_branches.py +259 -249
  81. package/md_cg/test_chain_read_isolate.py +168 -0
  82. package/md_cg/test_datapath_device_name.py +203 -0
  83. package/md_cg/test_emit_negtail_cache.py +156 -0
  84. package/md_cg/test_en_pipeline.py +186 -166
  85. package/md_cg/test_govern_directread.py +421 -0
  86. package/md_cg/test_i32_hotcache_env_key.py +218 -0
  87. package/md_cg/test_identity_attribution.py +228 -147
  88. package/md_cg/test_index_durability.py +238 -224
  89. package/md_cg/test_interop.py +4 -2
  90. package/md_cg/test_interop_judgment.py +228 -0
  91. package/md_cg/test_issue39_utf8_stdio.py +273 -0
  92. package/md_cg/test_links_concurrent_write.py +188 -0
  93. package/md_cg/test_merge_upsert.py +168 -0
  94. package/md_cg/test_n123_derive_expiry_chain.py +205 -0
  95. package/md_cg/test_n130_verify_falsified_protect.py +185 -0
  96. package/md_cg/test_n131_merge_gate.py +205 -0
  97. package/md_cg/test_p1x_ref_root.py +160 -0
  98. package/md_cg/test_p27_docindex.py +774 -765
  99. package/md_cg/test_p2_mcp.py +3 -0
  100. package/md_cg/test_p32_backfill.py +304 -298
  101. package/md_cg/test_p39_verify_flow.py +90 -50
  102. package/md_cg/test_p47_session_view.py +60 -25
  103. package/md_cg/test_propose_tail_index.py +157 -0
  104. package/md_cg/test_read_scope_b27.py +277 -0
  105. package/md_cg/test_readcache_default_on.py +168 -0
  106. package/md_cg/test_readcache_precise_inval.py +270 -0
  107. package/md_cg/test_readcache_prodpath.py +55 -7
  108. package/md_cg/test_reconcile_v0.py +294 -0
  109. package/md_cg/test_retr_s1.py +6 -2
  110. package/md_cg/test_retr_s1b.py +67 -0
  111. package/md_cg/test_retr_s7.py +8 -0
  112. package/md_cg/test_retr_s9_entity_ctx.py +181 -175
  113. package/md_cg/test_retr_score_once.py +208 -0
  114. package/md_cg/test_review_onepass.py +170 -0
  115. package/md_cg/test_rrf_graph_seed_cache.py +154 -0
  116. package/md_cg/test_security_audit.py +155 -0
  117. package/md_cg/test_security_audit_b26.py +161 -0
  118. package/md_cg/test_security_audit_v21.py +250 -0
  119. package/md_cg/test_semantic_canonical.py +255 -241
  120. package/md_cg/test_session_isolation.py +168 -0
  121. package/md_cg/test_snapshot_autoclose.py +187 -0
  122. package/md_cg/test_tail_watermark_race.py +208 -0
  123. package/md_cg/test_tenant_env_override_warn.py +139 -0
  124. package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
  125. package/md_cg/test_v14_fixes.py +415 -397
  126. package/md_cg/test_verify_dirty_reconcile.py +157 -0
  127. package/md_cg/theory.py +276 -273
  128. package/md_cg/tokens.py +734 -677
  129. package/md_cg/units.py +3 -2
  130. package/md_cg/vision_evidence.py +4 -3
  131. package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
  132. package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
  133. package/md_cg/writepipe.py +554 -550
  134. package/package.json +6 -2
  135. package/src/bridge.ts +434 -401
  136. package/src/index.ts +526 -518
  137. package/src/lib/roleplay_web.ts +1019 -932
  138. package/src/lib/token_store.ts +202 -192
@@ -1,124 +1,128 @@
1
- # -*- coding: utf-8 -*-
2
- """multilang_ir.py · 多语言代码理解(第五阶段·统一 IR 跨语言)
3
- Python(ast 完整)+ JavaScript/Rust(轻量正则提取)→ 统一 IR
4
- → 复用 codegraph_white 调用图/影响分析(codegraph 38 语言矩阵的白箱零依赖版)。
5
- 诚实边界:JS/Rust 为轻量提取(light=True),非完整 AST。
6
- """
7
- import sys
8
- import re
9
- sys.stdout.reconfigure(encoding='utf-8')
10
- try:
11
- from codegraph_white import extract_code_ir
12
- except ImportError:
13
- from .codegraph_white import extract_code_ir
14
-
15
-
16
- def detect_language(source="", filename=""):
17
- """语言检测:扩展名优先,语法特征兜底"""
18
- if filename.endswith(".py"):
19
- return "python"
20
- if filename.endswith(".js") or filename.endswith(".mjs") or filename.endswith(".jsx"):
21
- return "javascript"
22
- if filename.endswith(".rs"):
23
- return "rust"
24
- if "fn " in source and "->" in source and "impl " in source:
25
- return "rust"
26
- if "function " in source or "=>" in source or "import " in source:
27
- return "javascript"
28
- if "def " in source:
29
- return "python"
30
- return "unknown"
31
-
32
-
33
- # ============ JS/Rust 轻量提取(正则结构化,诚实标注) ============
34
- _JS_KW = {"function", "if", "for", "while", "switch", "return", "const", "let",
35
- "var", "new", "typeof", "console", "import", "export", "from", "require",
36
- "async", "await", "class", "extends", "throw", "try", "catch", "else",
37
- "break", "continue", "do", "in", "of", "this", "super", "delete", "void"}
38
- _RUST_KW = {"fn", "if", "for", "while", "match", "return", "let", "mut", "impl",
39
- "struct", "use", "println", "print", "vec", "String", "str", "Box",
40
- "Some", "None", "Ok", "Err", "self", "Self", "pub", "mod", "enum",
41
- "trait", "where", "loop", "break", "continue", "async", "await",
42
- "move", "ref", "static", "unsafe", "extern", "type", "const"}
43
-
44
-
45
- def _calls_from(src, kws):
46
- """调用提取:\b(\w+)\( 匹配 → 过滤关键字(轻量,允许误抓)"""
47
- calls = [m.group(1) for m in re.finditer(r"\b([A-Za-z_]\w*)\s*\(", src)]
48
- return sorted({c for c in calls if c not in kws})
49
-
50
-
51
- def _extract_js(source, file_path):
52
- """JavaScript 轻量提取:function/箭头函数/class/import + 调用"""
53
- ir = {"file": file_path, "functions": [], "classes": [], "imports": [],
54
- "light": True}
55
- # 函数:function name( / const name = (args) => / name = function(
56
- for m in re.finditer(r"\bfunction\s+([A-Za-z_]\w*)\s*\(([^)]*)\)", source):
57
- body = source[m.end():m.end() + 600]
58
- ir["functions"].append({"name": m.group(1),
59
- "params": [p.strip() for p in m.group(2).split(",") if p.strip()],
60
- "calls": _calls_from(body, _JS_KW), "class_owner": None})
61
- for m in re.finditer(r"\bconst\s+([A-Za-z_]\w*)\s*=\s*\(([^)]*)\)\s*=>", source):
62
- body = source[m.end():m.end() + 600]
63
- ir["functions"].append({"name": m.group(1),
64
- "params": [p.strip() for p in m.group(2).split(",") if p.strip()],
65
- "calls": _calls_from(body, _JS_KW), "class_owner": None})
66
- for m in re.finditer(r"\bclass\s+([A-Za-z_]\w*)", source):
67
- ir["classes"].append({"name": m.group(1), "methods": [], "bases": []})
68
- for m in re.finditer(r"\bimport\s+(?:{[^}]*}\s+from\s+)?['\"]([^'\"]+)['\"]", source):
69
- ir["imports"].append({"module": m.group(1).split("/")[-1].replace(".js", ""),
70
- "names": []})
71
- return ir
72
-
73
-
74
- def _extract_rust(source, file_path):
75
- """Rust 轻量提取:fn/struct/impl/use + 调用"""
76
- ir = {"file": file_path, "functions": [], "classes": [], "imports": [],
77
- "light": True}
78
- for m in re.finditer(r"\bfn\s+([A-Za-z_]\w*)\s*\(([^)]*)\)", source):
79
- body = source[m.end():m.end() + 600]
80
- ir["functions"].append({"name": m.group(1),
81
- "params": [p.strip().split(":")[0] for p in m.group(2).split(",") if p.strip()],
82
- "calls": _calls_from(body, _RUST_KW), "class_owner": None})
83
- for m in re.finditer(r"\bstruct\s+([A-Za-z_]\w*)", source):
84
- ir["classes"].append({"name": m.group(1), "methods": [], "bases": []})
85
- for m in re.finditer(r"\buse\s+([A-Za-z_:]+)", source):
86
- ir["imports"].append({"module": m.group(1).split("::")[0], "names": []})
87
- return ir
88
-
89
-
90
- def extract_ir(source, filename):
91
- """多语言 → 统一 IR(与 codegraph_white.extract_code_ir 同结构)"""
92
- lang = detect_language(source, filename)
93
- if lang == "python":
94
- ir = extract_code_ir(source, filename)
95
- ir["lang"] = "python"
96
- return ir
97
- if lang == "javascript":
98
- ir = _extract_js(source, filename)
99
- ir["lang"] = "javascript"
100
- return ir
101
- if lang == "rust":
102
- ir = _extract_rust(source, filename)
103
- ir["lang"] = "rust"
104
- return ir
105
- return {"file": filename, "functions": [], "classes": [], "imports": [],
106
- "lang": lang, "light": True}
107
-
108
-
109
- if __name__ == "__main__":
110
- print("=== 多语言代码理解:统一 IR 跨语言(零 LLM)===\n")
111
- samples = {
112
- "sample.py": "def parse(data):\n return split(data)\n\ndef split(d):\n return d.split(',')\n",
113
- "sample.js": "import { fs } from 'fs'\n\nfunction parse(data) {\n return split(data);\n}\n\nconst split = (d) => d.split(',');\n",
114
- "sample.rs": "use std::collections::HashMap;\n\nfn parse(data: &str) -> Vec<&str> {\n split(data)\n}\n\nfn split(d: &str) -> Vec<&str> {\n d.split(',').collect()\n}\n",
115
- }
116
- ok_all = True
117
- for fname, src in samples.items():
118
- ir = extract_ir(src, fname)
119
- fns = [f["name"] for f in ir["functions"]]
120
- print(f"[{fname}] lang={ir['lang']} light={ir.get('light', False)} "
121
- f"函数={fns} 导入={[i['module'] for i in ir['imports']]}")
122
- if "parse" not in fns:
123
- ok_all = False
124
- print(f"\n=== 判定 ===\n统一 IR 跨语言: {'✔ 三语言函数提取成立' if ok_all else '✘'}")
1
+ # -*- coding: utf-8 -*-
2
+ """multilang_ir.py · 多语言代码理解(第五阶段·统一 IR 跨语言)
3
+ Python(ast 完整)+ JavaScript/Rust(轻量正则提取)→ 统一 IR
4
+ → 复用 codegraph_white 调用图/影响分析(codegraph 38 语言矩阵的白箱零依赖版)。
5
+ 诚实边界:JS/Rust 为轻量提取(light=True),非完整 AST。
6
+ """
7
+ import sys
8
+ import re
9
+ sys.stdout.reconfigure(encoding='utf-8')
10
+ try:
11
+ from codegraph_white import extract_code_ir
12
+ except ImportError:
13
+ from .codegraph_white import extract_code_ir
14
+
15
+
16
+ def detect_language(source="", filename=""):
17
+ """语言检测:扩展名优先,语法特征兜底"""
18
+ if filename.endswith(".py"):
19
+ return "python"
20
+ if filename.endswith(".js") or filename.endswith(".mjs") or filename.endswith(".jsx"):
21
+ return "javascript"
22
+ if filename.endswith(".rs"):
23
+ return "rust"
24
+ if "fn " in source and "->" in source and "impl " in source:
25
+ return "rust"
26
+ if "function " in source or "=>" in source or "import " in source:
27
+ return "javascript"
28
+ if "def " in source:
29
+ return "python"
30
+ return "unknown"
31
+
32
+
33
+ # ============ JS/Rust 轻量提取(正则结构化,诚实标注) ============
34
+ _JS_KW = {"function", "if", "for", "while", "switch", "return", "const", "let",
35
+ "var", "new", "typeof", "console", "import", "export", "from", "require",
36
+ "async", "await", "class", "extends", "throw", "try", "catch", "else",
37
+ "break", "continue", "do", "in", "of", "this", "super", "delete", "void"}
38
+ _RUST_KW = {"fn", "if", "for", "while", "match", "return", "let", "mut", "impl",
39
+ "struct", "use", "println", "print", "vec", "String", "str", "Box",
40
+ "Some", "None", "Ok", "Err", "self", "Self", "pub", "mod", "enum",
41
+ "trait", "where", "loop", "break", "continue", "async", "await",
42
+ "move", "ref", "static", "unsafe", "extern", "type", "const"}
43
+
44
+
45
+ def _calls_from(src, kws):
46
+ r"""调用提取:\b(\w+)\( 匹配 → 过滤关键字(轻量,允许误抓)
47
+
48
+ 注意 docstring 用 r-prefix:`\w` 是**故意**的字面反斜杠+w(正则示意),
49
+ 不加 raw 会被 Python 当非法转义并报 SyntaxWarning(2026-09-24 修)。
50
+ """
51
+ calls = [m.group(1) for m in re.finditer(r"\b([A-Za-z_]\w*)\s*\(", src)]
52
+ return sorted({c for c in calls if c not in kws})
53
+
54
+
55
+ def _extract_js(source, file_path):
56
+ """JavaScript 轻量提取:function/箭头函数/class/import + 调用"""
57
+ ir = {"file": file_path, "functions": [], "classes": [], "imports": [],
58
+ "light": True}
59
+ # 函数:function name( / const name = (args) => / name = function(
60
+ for m in re.finditer(r"\bfunction\s+([A-Za-z_]\w*)\s*\(([^)]*)\)", source):
61
+ body = source[m.end():m.end() + 600]
62
+ ir["functions"].append({"name": m.group(1),
63
+ "params": [p.strip() for p in m.group(2).split(",") if p.strip()],
64
+ "calls": _calls_from(body, _JS_KW), "class_owner": None})
65
+ for m in re.finditer(r"\bconst\s+([A-Za-z_]\w*)\s*=\s*\(([^)]*)\)\s*=>", source):
66
+ body = source[m.end():m.end() + 600]
67
+ ir["functions"].append({"name": m.group(1),
68
+ "params": [p.strip() for p in m.group(2).split(",") if p.strip()],
69
+ "calls": _calls_from(body, _JS_KW), "class_owner": None})
70
+ for m in re.finditer(r"\bclass\s+([A-Za-z_]\w*)", source):
71
+ ir["classes"].append({"name": m.group(1), "methods": [], "bases": []})
72
+ for m in re.finditer(r"\bimport\s+(?:{[^}]*}\s+from\s+)?['\"]([^'\"]+)['\"]", source):
73
+ ir["imports"].append({"module": m.group(1).split("/")[-1].replace(".js", ""),
74
+ "names": []})
75
+ return ir
76
+
77
+
78
+ def _extract_rust(source, file_path):
79
+ """Rust 轻量提取:fn/struct/impl/use + 调用"""
80
+ ir = {"file": file_path, "functions": [], "classes": [], "imports": [],
81
+ "light": True}
82
+ for m in re.finditer(r"\bfn\s+([A-Za-z_]\w*)\s*\(([^)]*)\)", source):
83
+ body = source[m.end():m.end() + 600]
84
+ ir["functions"].append({"name": m.group(1),
85
+ "params": [p.strip().split(":")[0] for p in m.group(2).split(",") if p.strip()],
86
+ "calls": _calls_from(body, _RUST_KW), "class_owner": None})
87
+ for m in re.finditer(r"\bstruct\s+([A-Za-z_]\w*)", source):
88
+ ir["classes"].append({"name": m.group(1), "methods": [], "bases": []})
89
+ for m in re.finditer(r"\buse\s+([A-Za-z_:]+)", source):
90
+ ir["imports"].append({"module": m.group(1).split("::")[0], "names": []})
91
+ return ir
92
+
93
+
94
+ def extract_ir(source, filename):
95
+ """多语言 → 统一 IR(与 codegraph_white.extract_code_ir 同结构)"""
96
+ lang = detect_language(source, filename)
97
+ if lang == "python":
98
+ ir = extract_code_ir(source, filename)
99
+ ir["lang"] = "python"
100
+ return ir
101
+ if lang == "javascript":
102
+ ir = _extract_js(source, filename)
103
+ ir["lang"] = "javascript"
104
+ return ir
105
+ if lang == "rust":
106
+ ir = _extract_rust(source, filename)
107
+ ir["lang"] = "rust"
108
+ return ir
109
+ return {"file": filename, "functions": [], "classes": [], "imports": [],
110
+ "lang": lang, "light": True}
111
+
112
+
113
+ if __name__ == "__main__":
114
+ print("=== 多语言代码理解:统一 IR 跨语言(零 LLM)===\n")
115
+ samples = {
116
+ "sample.py": "def parse(data):\n return split(data)\n\ndef split(d):\n return d.split(',')\n",
117
+ "sample.js": "import { fs } from 'fs'\n\nfunction parse(data) {\n return split(data);\n}\n\nconst split = (d) => d.split(',');\n",
118
+ "sample.rs": "use std::collections::HashMap;\n\nfn parse(data: &str) -> Vec<&str> {\n split(data)\n}\n\nfn split(d: &str) -> Vec<&str> {\n d.split(',').collect()\n}\n",
119
+ }
120
+ ok_all = True
121
+ for fname, src in samples.items():
122
+ ir = extract_ir(src, fname)
123
+ fns = [f["name"] for f in ir["functions"]]
124
+ print(f"[{fname}] lang={ir['lang']} light={ir.get('light', False)} "
125
+ f"函数={fns} 导入={[i['module'] for i in ir['imports']]}")
126
+ if "parse" not in fns:
127
+ ok_all = False
128
+ print(f"\n=== 判定 ===\n统一 IR 跨语言: {'✔ 三语言函数提取成立' if ok_all else '✘'}")