homegraph 1.1.2 → 1.2.0

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 (361) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +268 -243
  3. package/dist/arkts/ohos-api-index.d.ts +15 -0
  4. package/dist/arkts/ohos-api-index.d.ts.map +1 -0
  5. package/dist/arkts/ohos-api-index.js +190 -0
  6. package/dist/arkts/ohos-api-index.js.map +1 -0
  7. package/dist/arkts/ohos-sdk-input.d.ts +36 -0
  8. package/dist/arkts/ohos-sdk-input.d.ts.map +1 -0
  9. package/dist/arkts/ohos-sdk-input.js +214 -0
  10. package/dist/arkts/ohos-sdk-input.js.map +1 -0
  11. package/dist/bin/command-supervision.d.ts +12 -0
  12. package/dist/bin/command-supervision.d.ts.map +1 -0
  13. package/dist/bin/command-supervision.js +86 -0
  14. package/dist/bin/command-supervision.js.map +1 -0
  15. package/dist/bin/homegraph.d.ts +1 -1
  16. package/dist/bin/homegraph.js +971 -71
  17. package/dist/bin/homegraph.js.map +1 -1
  18. package/dist/db/index.d.ts +20 -0
  19. package/dist/db/index.d.ts.map +1 -1
  20. package/dist/db/index.js +39 -0
  21. package/dist/db/index.js.map +1 -1
  22. package/dist/db/migrations.d.ts +1 -1
  23. package/dist/db/migrations.d.ts.map +1 -1
  24. package/dist/db/migrations.js +58 -19
  25. package/dist/db/migrations.js.map +1 -1
  26. package/dist/db/queries.d.ts +14 -0
  27. package/dist/db/queries.d.ts.map +1 -1
  28. package/dist/db/queries.js +314 -143
  29. package/dist/db/queries.js.map +1 -1
  30. package/dist/db/schema.sql +172 -152
  31. package/dist/directory.d.ts +32 -0
  32. package/dist/directory.d.ts.map +1 -1
  33. package/dist/directory.js +88 -5
  34. package/dist/directory.js.map +1 -1
  35. package/dist/extraction/arkts-batch-worker.d.ts +2 -0
  36. package/dist/extraction/arkts-batch-worker.d.ts.map +1 -0
  37. package/dist/extraction/arkts-batch-worker.js +28 -0
  38. package/dist/extraction/arkts-batch-worker.js.map +1 -0
  39. package/dist/extraction/context.d.ts +11 -0
  40. package/dist/extraction/context.d.ts.map +1 -1
  41. package/dist/extraction/context.js +20 -0
  42. package/dist/extraction/context.js.map +1 -1
  43. package/dist/extraction/index.d.ts +16 -2
  44. package/dist/extraction/index.d.ts.map +1 -1
  45. package/dist/extraction/index.js +619 -380
  46. package/dist/extraction/index.js.map +1 -1
  47. package/dist/extraction/languages/arkts-state-decorators.d.ts +13 -0
  48. package/dist/extraction/languages/arkts-state-decorators.d.ts.map +1 -0
  49. package/dist/extraction/languages/arkts-state-decorators.js +26 -0
  50. package/dist/extraction/languages/arkts-state-decorators.js.map +1 -0
  51. package/dist/extraction/languages/arkts-viewtree.d.ts +4 -2
  52. package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
  53. package/dist/extraction/languages/arkts-viewtree.js +21 -6
  54. package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
  55. package/dist/extraction/languages/arkts.d.ts +98 -2
  56. package/dist/extraction/languages/arkts.d.ts.map +1 -1
  57. package/dist/extraction/languages/arkts.js +1290 -61
  58. package/dist/extraction/languages/arkts.js.map +1 -1
  59. package/dist/extraction/languages/c-cpp.d.ts +56 -0
  60. package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  61. package/dist/extraction/languages/c-cpp.js +198 -1
  62. package/dist/extraction/languages/c-cpp.js.map +1 -1
  63. package/dist/extraction/languages/ohos-api-consumer.d.ts +34 -0
  64. package/dist/extraction/languages/ohos-api-consumer.d.ts.map +1 -0
  65. package/dist/extraction/languages/ohos-api-consumer.js +283 -0
  66. package/dist/extraction/languages/ohos-api-consumer.js.map +1 -0
  67. package/dist/extraction/parse-pool.d.ts +126 -0
  68. package/dist/extraction/parse-pool.d.ts.map +1 -0
  69. package/dist/extraction/parse-pool.js +319 -0
  70. package/dist/extraction/parse-pool.js.map +1 -0
  71. package/dist/extraction/tree-sitter-types.d.ts +17 -0
  72. package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  73. package/dist/extraction/tree-sitter.d.ts +21 -0
  74. package/dist/extraction/tree-sitter.d.ts.map +1 -1
  75. package/dist/extraction/tree-sitter.js +198 -27
  76. package/dist/extraction/tree-sitter.js.map +1 -1
  77. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  78. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  79. package/dist/graph/traversal.d.ts.map +1 -1
  80. package/dist/graph/traversal.js +76 -17
  81. package/dist/graph/traversal.js.map +1 -1
  82. package/dist/index.d.ts +25 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +78 -4
  85. package/dist/index.js.map +1 -1
  86. package/dist/installer/instructions-template.js +9 -9
  87. package/dist/installer/targets/shared.d.ts +5 -6
  88. package/dist/installer/targets/shared.d.ts.map +1 -1
  89. package/dist/installer/targets/shared.js +5 -6
  90. package/dist/installer/targets/shared.js.map +1 -1
  91. package/dist/mcp/daemon-paths.d.ts +30 -3
  92. package/dist/mcp/daemon-paths.d.ts.map +1 -1
  93. package/dist/mcp/daemon-paths.js +50 -10
  94. package/dist/mcp/daemon-paths.js.map +1 -1
  95. package/dist/mcp/daemon-registry.d.ts.map +1 -1
  96. package/dist/mcp/daemon-registry.js +7 -3
  97. package/dist/mcp/daemon-registry.js.map +1 -1
  98. package/dist/mcp/daemon.d.ts +48 -0
  99. package/dist/mcp/daemon.d.ts.map +1 -1
  100. package/dist/mcp/daemon.js +196 -32
  101. package/dist/mcp/daemon.js.map +1 -1
  102. package/dist/mcp/engine.d.ts +17 -0
  103. package/dist/mcp/engine.d.ts.map +1 -1
  104. package/dist/mcp/engine.js +73 -1
  105. package/dist/mcp/engine.js.map +1 -1
  106. package/dist/mcp/index.d.ts.map +1 -1
  107. package/dist/mcp/index.js +25 -43
  108. package/dist/mcp/index.js.map +1 -1
  109. package/dist/mcp/liveness-watchdog.js +16 -16
  110. package/dist/mcp/ppid-watchdog.d.ts +18 -0
  111. package/dist/mcp/ppid-watchdog.d.ts.map +1 -1
  112. package/dist/mcp/ppid-watchdog.js +37 -0
  113. package/dist/mcp/ppid-watchdog.js.map +1 -1
  114. package/dist/mcp/query-cache.d.ts +25 -0
  115. package/dist/mcp/query-cache.d.ts.map +1 -0
  116. package/dist/mcp/query-cache.js +191 -0
  117. package/dist/mcp/query-cache.js.map +1 -0
  118. package/dist/mcp/query-pool.d.ts +94 -0
  119. package/dist/mcp/query-pool.d.ts.map +1 -0
  120. package/dist/mcp/query-pool.js +297 -0
  121. package/dist/mcp/query-pool.js.map +1 -0
  122. package/dist/mcp/query-worker.d.ts +24 -0
  123. package/dist/mcp/query-worker.d.ts.map +1 -0
  124. package/dist/mcp/query-worker.js +87 -0
  125. package/dist/mcp/query-worker.js.map +1 -0
  126. package/dist/mcp/server-instructions.d.ts +5 -7
  127. package/dist/mcp/server-instructions.d.ts.map +1 -1
  128. package/dist/mcp/server-instructions.js +72 -74
  129. package/dist/mcp/server-instructions.js.map +1 -1
  130. package/dist/mcp/tools.d.ts +94 -4
  131. package/dist/mcp/tools.d.ts.map +1 -1
  132. package/dist/mcp/tools.js +877 -71
  133. package/dist/mcp/tools.js.map +1 -1
  134. package/dist/project-config.d.ts +20 -0
  135. package/dist/project-config.d.ts.map +1 -1
  136. package/dist/project-config.js +42 -2
  137. package/dist/project-config.js.map +1 -1
  138. package/dist/reasoning/login.js +1 -1
  139. package/dist/reasoning/login.js.map +1 -1
  140. package/dist/reasoning/reasoner.js +32 -32
  141. package/dist/resolution/c-fnptr-synthesizer.d.ts +0 -28
  142. package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
  143. package/dist/resolution/c-fnptr-synthesizer.js +765 -79
  144. package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
  145. package/dist/resolution/callback-synthesizer.d.ts +1 -1
  146. package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  147. package/dist/resolution/callback-synthesizer.js +72 -11
  148. package/dist/resolution/callback-synthesizer.js.map +1 -1
  149. package/dist/resolution/cooperative-yield.d.ts +32 -0
  150. package/dist/resolution/cooperative-yield.d.ts.map +1 -0
  151. package/dist/resolution/cooperative-yield.js +42 -0
  152. package/dist/resolution/cooperative-yield.js.map +1 -0
  153. package/dist/resolution/index.d.ts +11 -2
  154. package/dist/resolution/index.d.ts.map +1 -1
  155. package/dist/resolution/index.js +72 -4
  156. package/dist/resolution/index.js.map +1 -1
  157. package/dist/resolution/name-matcher.d.ts +22 -0
  158. package/dist/resolution/name-matcher.d.ts.map +1 -1
  159. package/dist/resolution/name-matcher.js +317 -20
  160. package/dist/resolution/name-matcher.js.map +1 -1
  161. package/dist/spec/config.d.ts +39 -0
  162. package/dist/spec/config.d.ts.map +1 -0
  163. package/dist/spec/config.js +304 -0
  164. package/dist/spec/config.js.map +1 -0
  165. package/dist/spec/db/commit-node.d.ts +23 -0
  166. package/dist/spec/db/commit-node.d.ts.map +1 -0
  167. package/dist/spec/db/commit-node.js +62 -0
  168. package/dist/spec/db/commit-node.js.map +1 -0
  169. package/dist/spec/db/fragment-node.d.ts +24 -0
  170. package/dist/spec/db/fragment-node.d.ts.map +1 -0
  171. package/dist/spec/db/fragment-node.js +128 -0
  172. package/dist/spec/db/fragment-node.js.map +1 -0
  173. package/dist/spec/db/fts.d.ts +74 -0
  174. package/dist/spec/db/fts.d.ts.map +1 -0
  175. package/dist/spec/db/fts.js +324 -0
  176. package/dist/spec/db/fts.js.map +1 -0
  177. package/dist/spec/db/index.d.ts +13 -0
  178. package/dist/spec/db/index.d.ts.map +1 -0
  179. package/dist/spec/db/index.js +50 -0
  180. package/dist/spec/db/index.js.map +1 -0
  181. package/dist/spec/db/relations.d.ts +55 -0
  182. package/dist/spec/db/relations.d.ts.map +1 -0
  183. package/dist/spec/db/relations.js +158 -0
  184. package/dist/spec/db/relations.js.map +1 -0
  185. package/dist/spec/db/schema.d.ts +33 -0
  186. package/dist/spec/db/schema.d.ts.map +1 -0
  187. package/dist/spec/db/schema.js +119 -0
  188. package/dist/spec/db/schema.js.map +1 -0
  189. package/dist/spec/db/schema.sql +117 -0
  190. package/dist/spec/db/spec-node.d.ts +41 -0
  191. package/dist/spec/db/spec-node.d.ts.map +1 -0
  192. package/dist/spec/db/spec-node.js +114 -0
  193. package/dist/spec/db/spec-node.js.map +1 -0
  194. package/dist/spec/evolve/impact-locator.d.ts +13 -0
  195. package/dist/spec/evolve/impact-locator.d.ts.map +1 -0
  196. package/dist/spec/evolve/impact-locator.js +25 -0
  197. package/dist/spec/evolve/impact-locator.js.map +1 -0
  198. package/dist/spec/evolve/llm-client.d.ts +50 -0
  199. package/dist/spec/evolve/llm-client.d.ts.map +1 -0
  200. package/dist/spec/evolve/llm-client.js +176 -0
  201. package/dist/spec/evolve/llm-client.js.map +1 -0
  202. package/dist/spec/evolve/logic-checker.d.ts +12 -0
  203. package/dist/spec/evolve/logic-checker.d.ts.map +1 -0
  204. package/dist/spec/evolve/logic-checker.js +24 -0
  205. package/dist/spec/evolve/logic-checker.js.map +1 -0
  206. package/dist/spec/evolve/pipeline.d.ts +42 -0
  207. package/dist/spec/evolve/pipeline.d.ts.map +1 -0
  208. package/dist/spec/evolve/pipeline.js +567 -0
  209. package/dist/spec/evolve/pipeline.js.map +1 -0
  210. package/dist/spec/evolve/spec-rewriter.d.ts +42 -0
  211. package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -0
  212. package/dist/spec/evolve/spec-rewriter.js +230 -0
  213. package/dist/spec/evolve/spec-rewriter.js.map +1 -0
  214. package/dist/spec/graph/queries.d.ts +155 -0
  215. package/dist/spec/graph/queries.d.ts.map +1 -0
  216. package/dist/spec/graph/queries.js +440 -0
  217. package/dist/spec/graph/queries.js.map +1 -0
  218. package/dist/spec/llm/client.d.ts +29 -0
  219. package/dist/spec/llm/client.d.ts.map +1 -0
  220. package/dist/spec/llm/client.js +123 -0
  221. package/dist/spec/llm/client.js.map +1 -0
  222. package/dist/spec/llm/index.d.ts +3 -0
  223. package/dist/spec/llm/index.d.ts.map +1 -0
  224. package/dist/spec/llm/index.js +11 -0
  225. package/dist/spec/llm/index.js.map +1 -0
  226. package/dist/spec/llm/prompts.d.ts +13 -0
  227. package/dist/spec/llm/prompts.d.ts.map +1 -0
  228. package/dist/spec/llm/prompts.js +75 -0
  229. package/dist/spec/llm/prompts.js.map +1 -0
  230. package/dist/spec/mining/diff-parser.d.ts +33 -0
  231. package/dist/spec/mining/diff-parser.d.ts.map +1 -0
  232. package/dist/spec/mining/diff-parser.js +166 -0
  233. package/dist/spec/mining/diff-parser.js.map +1 -0
  234. package/dist/spec/mining/git-scanner.d.ts +103 -0
  235. package/dist/spec/mining/git-scanner.d.ts.map +1 -0
  236. package/dist/spec/mining/git-scanner.js +307 -0
  237. package/dist/spec/mining/git-scanner.js.map +1 -0
  238. package/dist/spec/mining/pipeline.d.ts +53 -0
  239. package/dist/spec/mining/pipeline.d.ts.map +1 -0
  240. package/dist/spec/mining/pipeline.js +178 -0
  241. package/dist/spec/mining/pipeline.js.map +1 -0
  242. package/dist/spec/mining/scope-resolver.d.ts +45 -0
  243. package/dist/spec/mining/scope-resolver.d.ts.map +1 -0
  244. package/dist/spec/mining/scope-resolver.js +103 -0
  245. package/dist/spec/mining/scope-resolver.js.map +1 -0
  246. package/dist/spec/mining/spec-extractor.d.ts +69 -0
  247. package/dist/spec/mining/spec-extractor.d.ts.map +1 -0
  248. package/dist/spec/mining/spec-extractor.js +369 -0
  249. package/dist/spec/mining/spec-extractor.js.map +1 -0
  250. package/dist/spec/types.d.ts +149 -0
  251. package/dist/spec/types.d.ts.map +1 -0
  252. package/dist/spec/types.js +15 -0
  253. package/dist/spec/types.js.map +1 -0
  254. package/dist/spec/utils.d.ts +167 -0
  255. package/dist/spec/utils.d.ts.map +1 -0
  256. package/dist/spec/utils.js +463 -0
  257. package/dist/spec/utils.js.map +1 -0
  258. package/dist/sync/worktree.d.ts +9 -0
  259. package/dist/sync/worktree.d.ts.map +1 -1
  260. package/dist/sync/worktree.js +40 -0
  261. package/dist/sync/worktree.js.map +1 -1
  262. package/dist/types.d.ts +6 -1
  263. package/dist/types.d.ts.map +1 -1
  264. package/dist/ui/shimmer-progress.d.ts +2 -0
  265. package/dist/ui/shimmer-progress.d.ts.map +1 -1
  266. package/dist/ui/shimmer-progress.js +19 -2
  267. package/dist/ui/shimmer-progress.js.map +1 -1
  268. package/dist/upgrade/index.js +1 -1
  269. package/dist/upgrade/index.js.map +1 -1
  270. package/package.json +58 -57
  271. package/scripts/add-lang/bench.sh +60 -60
  272. package/scripts/add-lang/check-grammar.mjs +75 -75
  273. package/scripts/add-lang/dump-ast.mjs +103 -103
  274. package/scripts/add-lang/verify-extraction.mjs +70 -70
  275. package/scripts/agent-eval/ab-adoption.sh +91 -91
  276. package/scripts/agent-eval/ab-hook.sh +86 -86
  277. package/scripts/agent-eval/ab-impl.sh +78 -78
  278. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
  279. package/scripts/agent-eval/ab-sufficiency.sh +78 -78
  280. package/scripts/agent-eval/arms-F.sh +21 -21
  281. package/scripts/agent-eval/arms-matrix.sh +37 -37
  282. package/scripts/agent-eval/audit.sh +68 -68
  283. package/scripts/agent-eval/bench-readme.sh +28 -28
  284. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  285. package/scripts/agent-eval/block-read-hook.sh +19 -19
  286. package/scripts/agent-eval/hook-settings.json +15 -15
  287. package/scripts/agent-eval/itrun.sh +120 -120
  288. package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
  289. package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
  290. package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
  291. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
  292. package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
  293. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
  294. package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
  295. package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
  296. package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
  297. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
  298. package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
  299. package/scripts/agent-eval/offload-eval-setup.sh +24 -24
  300. package/scripts/agent-eval/offload-eval-styles.sh +71 -71
  301. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
  302. package/scripts/agent-eval/offload-eval.md +76 -76
  303. package/scripts/agent-eval/parse-arms.mjs +116 -116
  304. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  305. package/scripts/agent-eval/parse-run.mjs +45 -45
  306. package/scripts/agent-eval/parse-session.mjs +93 -93
  307. package/scripts/agent-eval/probe-context.mjs +21 -21
  308. package/scripts/agent-eval/probe-explore.mjs +40 -40
  309. package/scripts/agent-eval/probe-node.mjs +20 -20
  310. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  311. package/scripts/agent-eval/probe-trace.mjs +20 -20
  312. package/scripts/agent-eval/redirect-read-hook.sh +38 -38
  313. package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
  314. package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
  315. package/scripts/agent-eval/run-agent.sh +34 -34
  316. package/scripts/agent-eval/run-all.sh +69 -69
  317. package/scripts/agent-eval/run-arms.sh +56 -56
  318. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  319. package/scripts/build-bundle.sh +118 -118
  320. package/scripts/exp_boundary_eval/README.md +247 -0
  321. package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
  322. package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
  323. package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
  324. package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
  325. package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
  326. package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
  327. package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -0
  328. package/scripts/exp_boundary_eval/_test_stdin.py +8 -0
  329. package/scripts/exp_boundary_eval/_utils.py +1116 -0
  330. package/scripts/exp_boundary_eval/analyze.py +1313 -0
  331. package/scripts/exp_boundary_eval/data/agents.json +109 -0
  332. package/scripts/exp_boundary_eval/data/experiments.json +140 -0
  333. package/scripts/exp_boundary_eval/deveco_arm.py +519 -0
  334. package/scripts/exp_boundary_eval/run_all.py +378 -0
  335. package/scripts/exp_boundary_eval/run_one.py +165 -0
  336. package/scripts/exp_boundary_eval/run_session.py +158 -0
  337. package/scripts/exp_boundary_eval/setup.py +120 -0
  338. package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -0
  339. package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -0
  340. package/scripts/exp_boundary_eval/win_node_launcher.py +24 -0
  341. package/scripts/extract-release-notes.mjs +130 -130
  342. package/scripts/local-install.sh +41 -41
  343. package/scripts/npm-sdk.js +75 -75
  344. package/scripts/npm-shim.js +268 -246
  345. package/scripts/ohos-sdk-publish.mjs +133 -0
  346. package/scripts/pack-npm.sh +119 -119
  347. package/scripts/prepare-release.mjs +270 -270
  348. package/scripts/qa_eval/README.md +407 -404
  349. package/scripts/qa_eval/_test_deveco_probe.py +41 -41
  350. package/scripts/qa_eval/agent_runner.py +526 -526
  351. package/scripts/qa_eval/data/.gitignore +4 -4
  352. package/scripts/qa_eval/data/test-set.jsonl +2 -22
  353. package/scripts/qa_eval/eval_metrics.py +274 -233
  354. package/scripts/qa_eval/external_agent.py +976 -671
  355. package/scripts/qa_eval/llm_config.py +92 -92
  356. package/scripts/qa_eval/memory_monitor.py +132 -132
  357. package/scripts/qa_eval/my_answer_accuracy.py +187 -187
  358. package/scripts/qa_eval/requirements.txt +2 -2
  359. package/scripts/qa_eval/run_pipeline.py +804 -711
  360. package/scripts/qa_eval/stats_efficiency.py +279 -279
  361. package/scripts/qa_eval/stats_scores.py +207 -207
@@ -1,187 +1,187 @@
1
- """LLM-as-Judge Answer Accuracy (0–1), dual-prompt average — standalone, no ragas."""
2
-
3
- from __future__ import annotations
4
-
5
- import logging
6
- import math
7
- import re
8
- from dataclasses import dataclass
9
-
10
- from openai import AsyncOpenAI
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- TEMPLATE_ACCURACY1 = (
15
- "Instruction: You are an assistant for rating a User Answer given a Question. "
16
- "The Question is fully answered by the Reference Answer.\n"
17
- "Focus on whether the User Answer captures the key meaning and intent of the Reference Answer. "
18
- "Minor wording differences, alternative phrasing, or extra irrelevant information should not lower the rating.\n"
19
- "Say 5, if the User Answer conveys the same overall meaning and essential content as the Reference Answer.\n"
20
- "Say 4, if the User Answer is mostly correct, broadly aligned with the Reference Answer, with only small omissions or slight issues.\n"
21
- "Say 3, if the User Answer is reasonably correct, covering several important aspects of the Reference Answer, even if incomplete.\n"
22
- "Say 2, if the User Answer shows some overlap, but misses many essential aspects.\n"
23
- "Say 1, if the User Answer has very little overlap with the Reference Answer.\n"
24
- "Say 0, if the User Answer does not address the question at all.\n"
25
- "Do not explain or justify your rating. Your rating must be a single integer 0–5.\n"
26
- "If the User Answer is empty, the rating is 0.\n"
27
- "### Question: {query}\n"
28
- "### {answer0}: {sentence_inference}\n"
29
- "### {answer1}: {sentence_true}\n"
30
- "The rating is:\n"
31
- )
32
-
33
- TEMPLATE_ACCURACY2 = (
34
- "I will rate the User Answer in comparison to the Reference Answer for a given Question.\n"
35
- "The evaluation must focus mainly on whether the User Answer conveys the essential meaning and intent of the Reference Answer. "
36
- "Minor details, alternative phrasing, or extra content should not strongly affect the rating.\n"
37
- "If the User Answer is empty, the rating is 0.\n"
38
- "The scale is 0 to 5:\n"
39
- "0 = Does not address the question at all\n"
40
- "1 = Very limited overlap with the Reference Answer\n"
41
- "2 = Some overlap, but misses many essential aspects\n"
42
- "3 = Reasonably correct, covers several important aspects but incomplete\n"
43
- "4 = Mostly correct, broadly aligned with the Reference Answer with only small gaps\n"
44
- "5 = Fully correct, conveys the same overall meaning and essential content as the Reference Answer\n"
45
- "I will provide the rating as a single integer 0–5 without explanation.\n\n"
46
- "Question: {query}\n\n"
47
- "{answer0}: {sentence_inference}\n\n"
48
- "{answer1}: {sentence_true}\n\n"
49
- "Rating: "
50
- )
51
-
52
-
53
- def remove_tool_calls(text: str) -> str:
54
- """Strip --- ... --- blocks that contain agent tool invocations before judging."""
55
- pattern = re.compile(
56
- r"---\s*[\s\S]*?"
57
- r"(ReadFile|SearchText|ReadManyFiles|ReadFolder|SemanticSearch|FindFiles|Custom|HomegraphQuery|HomegraphExplore)"
58
- r"[\s\S]*?---",
59
- re.MULTILINE,
60
- )
61
- cleaned = re.sub(pattern, "", text)
62
- return re.sub(r"\n{3,}", "\n\n", cleaned).strip()
63
-
64
-
65
- def extract_json_blocks_answerbyCOT(text: str) -> str:
66
- """Remove redacted_thinking blocks from chain-of-thought model output."""
67
- cleaned = re.sub(
68
- r"<think>.*?</think>",
69
- "",
70
- text,
71
- flags=re.DOTALL | re.IGNORECASE,
72
- )
73
- return cleaned.strip()
74
-
75
-
76
- def process_score(response: str) -> float:
77
- for i in range(6):
78
- if str(i) in response.strip():
79
- return i / 5
80
- return math.nan
81
-
82
-
83
- def average_scores(score0: float, score1: float) -> float:
84
- if not math.isnan(score0) and not math.isnan(score1):
85
- return (score0 + score1) / 2
86
- if math.isnan(score0) and math.isnan(score1):
87
- return math.nan
88
- return score0 if math.isnan(score1) else score1
89
-
90
-
91
- @dataclass
92
- class MyAnswerAccuracy:
93
- """Dual-template LLM judge; scores normalized to 0–1."""
94
-
95
- client: AsyncOpenAI
96
- model: str
97
- retry: int = 5
98
- extra_body: dict | None = None
99
-
100
- @classmethod
101
- def create(
102
- cls,
103
- *,
104
- api_key: str,
105
- base_url: str,
106
- model: str,
107
- timeout_sec: float = 1800,
108
- extra_body: dict | None = None,
109
- ) -> MyAnswerAccuracy:
110
- client = AsyncOpenAI(api_key=api_key, base_url=base_url, timeout=timeout_sec)
111
- return cls(client=client, model=model, extra_body=extra_body)
112
-
113
- async def _chat(self, prompt: str) -> str:
114
- kwargs: dict = {
115
- "model": self.model,
116
- "messages": [{"role": "user", "content": prompt}],
117
- "temperature": 0.10,
118
- }
119
- if self.extra_body:
120
- kwargs["extra_body"] = self.extra_body
121
- resp = await self.client.chat.completions.create(**kwargs)
122
- return (resp.choices[0].message.content or "").strip()
123
-
124
- async def _rate(self, prompt: str) -> float:
125
- for attempt in range(self.retry):
126
- try:
127
- text = await self._chat(prompt)
128
- score = process_score(text)
129
- if not math.isnan(score):
130
- return score
131
- except Exception as e:
132
- logger.warning("Judge call failed (attempt %s): %s", attempt + 1, e)
133
- logger.warning("Judge retry (invalid rating): %s", attempt + 1)
134
- return math.nan
135
-
136
- async def single_turn_ascore(
137
- self,
138
- *,
139
- user_input: str,
140
- response: str,
141
- reference: str,
142
- ) -> float:
143
- prompt1 = TEMPLATE_ACCURACY1.format(
144
- query=user_input,
145
- answer0="User Answer",
146
- answer1="Reference Answer",
147
- sentence_inference=response,
148
- sentence_true=reference,
149
- )
150
- prompt2 = TEMPLATE_ACCURACY2.format(
151
- query=user_input,
152
- answer0="Reference Answer",
153
- answer1="User Answer",
154
- sentence_inference=reference,
155
- sentence_true=response,
156
- )
157
- try:
158
- s0 = await self._rate(prompt1)
159
- s1 = await self._rate(prompt2)
160
- return average_scores(s0, s1)
161
- except Exception as e:
162
- logger.warning("Judge error: %s", e)
163
- return math.nan
164
-
165
- async def evaluate_answer_accuracy_single(self, sample_data: dict) -> dict:
166
- result = sample_data.copy()
167
- try:
168
- raw = str(sample_data.get("output_answer", ""))
169
- raw = extract_json_blocks_answerbyCOT(raw)
170
- response = remove_tool_calls(raw)
171
- score = await self.single_turn_ascore(
172
- user_input=str(sample_data.get("query", "")),
173
- response=response,
174
- reference=str(sample_data.get("reference_answer", "")),
175
- )
176
- result["answer_accuracy_score"] = float(score) if not math.isnan(score) else 0.0
177
- result["evaluation_status"] = "success" if not math.isnan(score) else "failed"
178
- if math.isnan(score):
179
- result["error_message"] = "Judge 未返回有效 0–5 分数"
180
- except Exception as e:
181
- logger.error("评估答案准确性时出错: %s", e)
182
- result["answer_accuracy_score"] = 0.0
183
- result["evaluation_status"] = "error"
184
- result["error_message"] = str(e)
185
-
186
- result.pop("evaluation", None)
187
- return result
1
+ """LLM-as-Judge Answer Accuracy (0–1), dual-prompt average — standalone, no ragas."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import math
7
+ import re
8
+ from dataclasses import dataclass
9
+
10
+ from openai import AsyncOpenAI
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ TEMPLATE_ACCURACY1 = (
15
+ "Instruction: You are an assistant for rating a User Answer given a Question. "
16
+ "The Question is fully answered by the Reference Answer.\n"
17
+ "Focus on whether the User Answer captures the key meaning and intent of the Reference Answer. "
18
+ "Minor wording differences, alternative phrasing, or extra irrelevant information should not lower the rating.\n"
19
+ "Say 5, if the User Answer conveys the same overall meaning and essential content as the Reference Answer.\n"
20
+ "Say 4, if the User Answer is mostly correct, broadly aligned with the Reference Answer, with only small omissions or slight issues.\n"
21
+ "Say 3, if the User Answer is reasonably correct, covering several important aspects of the Reference Answer, even if incomplete.\n"
22
+ "Say 2, if the User Answer shows some overlap, but misses many essential aspects.\n"
23
+ "Say 1, if the User Answer has very little overlap with the Reference Answer.\n"
24
+ "Say 0, if the User Answer does not address the question at all.\n"
25
+ "Do not explain or justify your rating. Your rating must be a single integer 0–5.\n"
26
+ "If the User Answer is empty, the rating is 0.\n"
27
+ "### Question: {query}\n"
28
+ "### {answer0}: {sentence_inference}\n"
29
+ "### {answer1}: {sentence_true}\n"
30
+ "The rating is:\n"
31
+ )
32
+
33
+ TEMPLATE_ACCURACY2 = (
34
+ "I will rate the User Answer in comparison to the Reference Answer for a given Question.\n"
35
+ "The evaluation must focus mainly on whether the User Answer conveys the essential meaning and intent of the Reference Answer. "
36
+ "Minor details, alternative phrasing, or extra content should not strongly affect the rating.\n"
37
+ "If the User Answer is empty, the rating is 0.\n"
38
+ "The scale is 0 to 5:\n"
39
+ "0 = Does not address the question at all\n"
40
+ "1 = Very limited overlap with the Reference Answer\n"
41
+ "2 = Some overlap, but misses many essential aspects\n"
42
+ "3 = Reasonably correct, covers several important aspects but incomplete\n"
43
+ "4 = Mostly correct, broadly aligned with the Reference Answer with only small gaps\n"
44
+ "5 = Fully correct, conveys the same overall meaning and essential content as the Reference Answer\n"
45
+ "I will provide the rating as a single integer 0–5 without explanation.\n\n"
46
+ "Question: {query}\n\n"
47
+ "{answer0}: {sentence_inference}\n\n"
48
+ "{answer1}: {sentence_true}\n\n"
49
+ "Rating: "
50
+ )
51
+
52
+
53
+ def remove_tool_calls(text: str) -> str:
54
+ """Strip --- ... --- blocks that contain agent tool invocations before judging."""
55
+ pattern = re.compile(
56
+ r"---\s*[\s\S]*?"
57
+ r"(ReadFile|SearchText|ReadManyFiles|ReadFolder|SemanticSearch|FindFiles|Custom|HomegraphQuery|HomegraphExplore)"
58
+ r"[\s\S]*?---",
59
+ re.MULTILINE,
60
+ )
61
+ cleaned = re.sub(pattern, "", text)
62
+ return re.sub(r"\n{3,}", "\n\n", cleaned).strip()
63
+
64
+
65
+ def extract_json_blocks_answerbyCOT(text: str) -> str:
66
+ """Remove redacted_thinking blocks from chain-of-thought model output."""
67
+ cleaned = re.sub(
68
+ r"<think>.*?</think>",
69
+ "",
70
+ text,
71
+ flags=re.DOTALL | re.IGNORECASE,
72
+ )
73
+ return cleaned.strip()
74
+
75
+
76
+ def process_score(response: str) -> float:
77
+ for i in range(6):
78
+ if str(i) in response.strip():
79
+ return i / 5
80
+ return math.nan
81
+
82
+
83
+ def average_scores(score0: float, score1: float) -> float:
84
+ if not math.isnan(score0) and not math.isnan(score1):
85
+ return (score0 + score1) / 2
86
+ if math.isnan(score0) and math.isnan(score1):
87
+ return math.nan
88
+ return score0 if math.isnan(score1) else score1
89
+
90
+
91
+ @dataclass
92
+ class MyAnswerAccuracy:
93
+ """Dual-template LLM judge; scores normalized to 0–1."""
94
+
95
+ client: AsyncOpenAI
96
+ model: str
97
+ retry: int = 5
98
+ extra_body: dict | None = None
99
+
100
+ @classmethod
101
+ def create(
102
+ cls,
103
+ *,
104
+ api_key: str,
105
+ base_url: str,
106
+ model: str,
107
+ timeout_sec: float = 1800,
108
+ extra_body: dict | None = None,
109
+ ) -> MyAnswerAccuracy:
110
+ client = AsyncOpenAI(api_key=api_key, base_url=base_url, timeout=timeout_sec)
111
+ return cls(client=client, model=model, extra_body=extra_body)
112
+
113
+ async def _chat(self, prompt: str) -> str:
114
+ kwargs: dict = {
115
+ "model": self.model,
116
+ "messages": [{"role": "user", "content": prompt}],
117
+ "temperature": 0.10,
118
+ }
119
+ if self.extra_body:
120
+ kwargs["extra_body"] = self.extra_body
121
+ resp = await self.client.chat.completions.create(**kwargs)
122
+ return (resp.choices[0].message.content or "").strip()
123
+
124
+ async def _rate(self, prompt: str) -> float:
125
+ for attempt in range(self.retry):
126
+ try:
127
+ text = await self._chat(prompt)
128
+ score = process_score(text)
129
+ if not math.isnan(score):
130
+ return score
131
+ except Exception as e:
132
+ logger.warning("Judge call failed (attempt %s): %s", attempt + 1, e)
133
+ logger.warning("Judge retry (invalid rating): %s", attempt + 1)
134
+ return math.nan
135
+
136
+ async def single_turn_ascore(
137
+ self,
138
+ *,
139
+ user_input: str,
140
+ response: str,
141
+ reference: str,
142
+ ) -> float:
143
+ prompt1 = TEMPLATE_ACCURACY1.format(
144
+ query=user_input,
145
+ answer0="User Answer",
146
+ answer1="Reference Answer",
147
+ sentence_inference=response,
148
+ sentence_true=reference,
149
+ )
150
+ prompt2 = TEMPLATE_ACCURACY2.format(
151
+ query=user_input,
152
+ answer0="Reference Answer",
153
+ answer1="User Answer",
154
+ sentence_inference=reference,
155
+ sentence_true=response,
156
+ )
157
+ try:
158
+ s0 = await self._rate(prompt1)
159
+ s1 = await self._rate(prompt2)
160
+ return average_scores(s0, s1)
161
+ except Exception as e:
162
+ logger.warning("Judge error: %s", e)
163
+ return math.nan
164
+
165
+ async def evaluate_answer_accuracy_single(self, sample_data: dict) -> dict:
166
+ result = sample_data.copy()
167
+ try:
168
+ raw = str(sample_data.get("output_answer", ""))
169
+ raw = extract_json_blocks_answerbyCOT(raw)
170
+ response = remove_tool_calls(raw)
171
+ score = await self.single_turn_ascore(
172
+ user_input=str(sample_data.get("query", "")),
173
+ response=response,
174
+ reference=str(sample_data.get("reference_answer", "")),
175
+ )
176
+ result["answer_accuracy_score"] = float(score) if not math.isnan(score) else 0.0
177
+ result["evaluation_status"] = "success" if not math.isnan(score) else "failed"
178
+ if math.isnan(score):
179
+ result["error_message"] = "Judge 未返回有效 0–5 分数"
180
+ except Exception as e:
181
+ logger.error("评估答案准确性时出错: %s", e)
182
+ result["answer_accuracy_score"] = 0.0
183
+ result["evaluation_status"] = "error"
184
+ result["error_message"] = str(e)
185
+
186
+ result.pop("evaluation", None)
187
+ return result
@@ -1,2 +1,2 @@
1
- openai>=1.40.0
2
- tqdm>=4.66.0
1
+ openai>=1.40.0
2
+ tqdm>=4.66.0