noteconnection 1.7.0 → 1.9.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 (328) hide show
  1. package/LICENSE +674 -21
  2. package/README.md +260 -1626
  3. package/dist/src/agent_workspace.contract.parity.test.js +159 -0
  4. package/dist/src/agent_workspace.frontend.test.js +10388 -0
  5. package/dist/src/agent_workspace.locale.contract.test.js +95 -0
  6. package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
  7. package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
  8. package/dist/src/appimage.patchelf.test.js +113 -0
  9. package/dist/src/appimage.portability.test.js +156 -0
  10. package/dist/src/backend/FileLoader.js +18 -4
  11. package/dist/src/backend/FileLoader.test.js +125 -0
  12. package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
  13. package/dist/src/backend/GraphBuilder.js +66 -18
  14. package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
  15. package/dist/src/backend/GraphMetrics.js +0 -3
  16. package/dist/src/backend/ResourceIdentity.js +155 -0
  17. package/dist/src/backend/ResourceIdentity.test.js +113 -0
  18. package/dist/src/backend/algorithms/CycleDetection.js +0 -1
  19. package/dist/src/backend/algorithms/HybridEngine.js +0 -3
  20. package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
  21. package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
  22. package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
  23. package/dist/src/backend/build_dag.js +0 -1
  24. package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
  25. package/dist/src/capacitor.runtime.contract.test.js +11 -2
  26. package/dist/src/copy.assets.contract.test.js +130 -0
  27. package/dist/src/core/Graph.js +138 -42
  28. package/dist/src/core/Graph.test.js +74 -0
  29. package/dist/src/core/NoteConnection.js +2 -2
  30. package/dist/src/core/PathBridge.js +293 -5
  31. package/dist/src/core/ResourceReference.js +17 -0
  32. package/dist/src/desktop.godot.pack.test.js +142 -0
  33. package/dist/src/desktop.runtime.graph.test.js +66 -0
  34. package/dist/src/export/WorkspaceExportBundle.js +1174 -0
  35. package/dist/src/export/WorkspaceExportBundle.test.js +1541 -0
  36. package/dist/src/export/index.js +18 -0
  37. package/dist/src/export/types.js +2 -0
  38. package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
  39. package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
  40. package/dist/src/foundation.release.evidence.contract.test.js +524 -0
  41. package/dist/src/foundation.sqlite.runtime.contract.test.js +88 -0
  42. package/dist/src/frontend/README.md +260 -1626
  43. package/dist/src/frontend/agent_workspace.js +6011 -0
  44. package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
  45. package/dist/src/frontend/analysis.js +31 -4
  46. package/dist/src/frontend/app.js +2178 -62
  47. package/dist/src/frontend/focus_mode_interactions.js +33 -0
  48. package/dist/src/frontend/godot_future_path_renderer.js +540 -0
  49. package/dist/src/frontend/godot_tree_interactions.js +178 -0
  50. package/dist/src/frontend/graph_state.mjs +105 -0
  51. package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
  52. package/dist/src/frontend/i18n.mjs +186 -0
  53. package/dist/src/frontend/index.html +672 -268
  54. package/dist/src/frontend/knowledge_projection_contract.js +230 -0
  55. package/dist/src/frontend/knowledge_projection_store.js +214 -0
  56. package/dist/src/frontend/layout_gpu.js +12 -4
  57. package/dist/src/frontend/libs/path_core.js +158 -42
  58. package/dist/src/frontend/locales/en.json +753 -5
  59. package/dist/src/frontend/locales/zh.json +753 -5
  60. package/dist/src/frontend/main.mjs +60 -0
  61. package/dist/src/frontend/markdown_runtime.js +827 -0
  62. package/dist/src/frontend/mobile_budget_runtime.js +33 -0
  63. package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
  64. package/dist/src/frontend/mobile_identity_contract.js +221 -0
  65. package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
  66. package/dist/src/frontend/notemd.css +49 -0
  67. package/dist/src/frontend/notemd.html +7 -1
  68. package/dist/src/frontend/notemd.js +64 -0
  69. package/dist/src/frontend/path.html +113 -2
  70. package/dist/src/frontend/path_app.js +2108 -130
  71. package/dist/src/frontend/path_layout.mjs +143 -0
  72. package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
  73. package/dist/src/frontend/path_modules_bridge.js +486 -0
  74. package/dist/src/frontend/path_state.mjs +118 -0
  75. package/dist/src/frontend/path_styles.css +146 -0
  76. package/dist/src/frontend/path_worker_bridge.mjs +85 -0
  77. package/dist/src/frontend/reader.js +393 -33
  78. package/dist/src/frontend/runtime_bridge.js +67 -54
  79. package/dist/src/frontend/runtime_bridge.mjs +279 -0
  80. package/dist/src/frontend/settings.js +130 -12
  81. package/dist/src/frontend/simulationWorker.js +1 -1
  82. package/dist/src/frontend/source_manager.js +297 -22
  83. package/dist/src/frontend/storage_provider.js +661 -71
  84. package/dist/src/frontend/styles.css +2814 -72
  85. package/dist/src/frontend/workbench_state.mjs +101 -0
  86. package/dist/src/frontend/workspace_panes.js +10272 -0
  87. package/dist/src/frontend.locale.contract.test.js +62 -0
  88. package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
  89. package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
  90. package/dist/src/graph.answer.operator.contract.test.js +72 -0
  91. package/dist/src/index.js +6 -2
  92. package/dist/src/index.knowledge-root.test.js +118 -0
  93. package/dist/src/indexing/IndexLifecycle.js +217 -0
  94. package/dist/src/indexing/IndexLifecycle.test.js +73 -0
  95. package/dist/src/indexing/SegmentBuilder.js +64 -0
  96. package/dist/src/indexing/UnitBuilder.js +48 -0
  97. package/dist/src/indexing/types.js +2 -0
  98. package/dist/src/knowledge.api.contract.test.js +172 -0
  99. package/dist/src/knowledge_projection.contract.test.js +134 -0
  100. package/dist/src/knowledge_projection_store.test.js +200 -0
  101. package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
  102. package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
  103. package/dist/src/learning/KnowledgeLearningPlatform.js +11181 -0
  104. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +745 -0
  105. package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
  106. package/dist/src/learning/KnowledgeLearningPlatform.test.js +3208 -0
  107. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2998 -0
  108. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3936 -0
  109. package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
  110. package/dist/src/learning/PublicAnswerContract.test.js +85 -0
  111. package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
  112. package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
  113. package/dist/src/learning/agentConversationExecution.js +211 -0
  114. package/dist/src/learning/agentConversationExecution.test.js +209 -0
  115. package/dist/src/learning/agentConversationSerialization.js +266 -0
  116. package/dist/src/learning/agentConversationSerialization.test.js +165 -0
  117. package/dist/src/learning/agentResponseBudget.js +179 -0
  118. package/dist/src/learning/agentResponseBudget.test.js +97 -0
  119. package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
  120. package/dist/src/learning/answerReleaseReview.js +5260 -0
  121. package/dist/src/learning/answerReleaseReview.test.js +4174 -0
  122. package/dist/src/learning/answerTaskPlan.js +473 -0
  123. package/dist/src/learning/api.js +2 -0
  124. package/dist/src/learning/conversationComposer.js +1721 -0
  125. package/dist/src/learning/conversationComposer.test.js +3220 -0
  126. package/dist/src/learning/domains/ConversationManager.js +53 -0
  127. package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
  128. package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
  129. package/dist/src/learning/domains/MasteryEngine.js +387 -0
  130. package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
  131. package/dist/src/learning/domains/QualityEvaluator.js +307 -0
  132. package/dist/src/learning/domains/TutorRouter.js +313 -0
  133. package/dist/src/learning/domains/index.js +33 -0
  134. package/dist/src/learning/domains/types.js +7 -0
  135. package/dist/src/learning/errors.js +29 -0
  136. package/dist/src/learning/evidenceContextAssembler.js +1368 -0
  137. package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
  138. package/dist/src/learning/graphAnswerCoverage.js +37 -0
  139. package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
  140. package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
  141. package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
  142. package/dist/src/learning/graphAnswerFacts.js +94 -0
  143. package/dist/src/learning/graphAnswerFacts.test.js +39 -0
  144. package/dist/src/learning/graphAnswerPlan.js +908 -0
  145. package/dist/src/learning/graphAnswerPlan.test.js +907 -0
  146. package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
  147. package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
  148. package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
  149. package/dist/src/learning/graphClaimMatcher.js +104 -0
  150. package/dist/src/learning/graphConditionedContext.js +109 -0
  151. package/dist/src/learning/graphConditionedContext.test.js +99 -0
  152. package/dist/src/learning/graphContextAssembler.js +860 -0
  153. package/dist/src/learning/graphContextAssembler.test.js +1033 -0
  154. package/dist/src/learning/graphExpansionPolicy.js +22 -0
  155. package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
  156. package/dist/src/learning/identityMetadata.test.js +26 -0
  157. package/dist/src/learning/index.js +29 -0
  158. package/dist/src/learning/mobileAnswerProjection.js +104 -0
  159. package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
  160. package/dist/src/learning/queryBackend.js +1922 -0
  161. package/dist/src/learning/queryBackend.test.js +976 -0
  162. package/dist/src/learning/ragContextPack.js +356 -0
  163. package/dist/src/learning/ragContextPack.test.js +311 -0
  164. package/dist/src/learning/ragEvidenceQuality.js +96 -0
  165. package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
  166. package/dist/src/learning/ragPublicText.js +101 -0
  167. package/dist/src/learning/ragPublicText.test.js +57 -0
  168. package/dist/src/learning/ragSufficiencyJudge.js +171 -0
  169. package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
  170. package/dist/src/learning/ragSufficiencyProviderJudge.js +217 -0
  171. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +207 -0
  172. package/dist/src/learning/requestNormalization.js +304 -0
  173. package/dist/src/learning/requestNormalization.test.js +101 -0
  174. package/dist/src/learning/runtimeCapability.js +4677 -0
  175. package/dist/src/learning/runtimeCapability.test.js +3635 -0
  176. package/dist/src/learning/store.js +1344 -0
  177. package/dist/src/learning/store.test.js +1425 -0
  178. package/dist/src/learning/tutorAdapter.js +2 -0
  179. package/dist/src/learning/types.js +2 -0
  180. package/dist/src/learning/vectorAccelerationAdapter.js +958 -0
  181. package/dist/src/learning/vectorAccelerationAdapter.test.js +412 -0
  182. package/dist/src/learning/workspaceHydration.js +168 -0
  183. package/dist/src/learning/workspaceHydration.test.js +30 -0
  184. package/dist/src/lfs.asset.policy.contract.test.js +153 -0
  185. package/dist/src/license.policy.contract.test.js +71 -0
  186. package/dist/src/markdown/MarkdownGateway.js +4 -0
  187. package/dist/src/markdown/MarkdownGateway.test.js +59 -0
  188. package/dist/src/memory/MemoryGovernance.js +74 -0
  189. package/dist/src/memory/MemoryGovernance.test.js +46 -0
  190. package/dist/src/memory/types.js +2 -0
  191. package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
  192. package/dist/src/middleware/SseResponseWriter.js +122 -0
  193. package/dist/src/middleware/SseResponseWriter.test.js +54 -0
  194. package/dist/src/middleware/auth.js +38 -0
  195. package/dist/src/middleware/auth.test.js +33 -0
  196. package/dist/src/middleware/body-parser.js +45 -0
  197. package/dist/src/middleware/cors.js +44 -0
  198. package/dist/src/middleware/index.js +22 -0
  199. package/dist/src/middleware/request-trace.js +96 -0
  200. package/dist/src/mobile.android.evidence.contract.test.js +146 -0
  201. package/dist/src/mobile.android.signing.contract.test.js +66 -0
  202. package/dist/src/mobile.artifact.contract.test.js +144 -0
  203. package/dist/src/mobile.budget.contract.test.js +90 -0
  204. package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
  205. package/dist/src/mobile.graph.parity.contract.test.js +207 -0
  206. package/dist/src/mobile.identity.contract.test.js +66 -0
  207. package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
  208. package/dist/src/mobile.identity.corpus.test.js +40 -0
  209. package/dist/src/mobile.native.recovery.contract.test.js +64 -0
  210. package/dist/src/mobile.pipeline.test.js +11 -1
  211. package/dist/src/mobile.profile.contract.test.js +225 -0
  212. package/dist/src/mobile.semantic.parity.test.js +92 -0
  213. package/dist/src/mobile_exact_analyzer.test.js +113 -0
  214. package/dist/src/notemd/AppConfigToml.js +6 -4
  215. package/dist/src/notemd/ContentGenerator.js +4 -9
  216. package/dist/src/notemd/FileProcessor.js +4 -9
  217. package/dist/src/notemd/MermaidProcessor.js +400 -50
  218. package/dist/src/notemd/NotemdService.js +506 -26
  219. package/dist/src/notemd/PromptManager.js +15 -0
  220. package/dist/src/notemd/Translator.js +4 -9
  221. package/dist/src/notemd/cli/commands.js +357 -0
  222. package/dist/src/notemd/cli/dispatcher.js +225 -0
  223. package/dist/src/notemd/cli/index.js +169 -0
  224. package/dist/src/notemd/cli/parser.js +68 -0
  225. package/dist/src/notemd/cli/types.js +2 -0
  226. package/dist/src/notemd/constants.js +43 -0
  227. package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
  228. package/dist/src/notemd/diagram/diagramSpec.js +79 -0
  229. package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
  230. package/dist/src/notemd/diagram/intent.js +95 -0
  231. package/dist/src/notemd/diagram/planner.js +71 -0
  232. package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
  233. package/dist/src/notemd/diagram/types.js +18 -0
  234. package/dist/src/notemd/index.js +26 -0
  235. package/dist/src/notemd/operations/capabilityManifest.js +23 -0
  236. package/dist/src/notemd/operations/cliContracts.js +17 -0
  237. package/dist/src/notemd/operations/configProfileCommands.js +85 -0
  238. package/dist/src/notemd/operations/registry.contract.test.js +95 -0
  239. package/dist/src/notemd/operations/registry.js +991 -0
  240. package/dist/src/notemd/operations/types.js +2 -0
  241. package/dist/src/notemd/progressReporter.js +9 -0
  242. package/dist/src/notemd/providerDiagnostics.js +220 -0
  243. package/dist/src/notemd/providerProfiles.js +42 -0
  244. package/dist/src/notemd/providerTemplates.js +231 -0
  245. package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
  246. package/dist/src/notemd/search/SearchManager.js +13 -0
  247. package/dist/src/notemd/search/SearchProvider.js +2 -0
  248. package/dist/src/notemd/search/TavilyProvider.js +44 -0
  249. package/dist/src/notemd.agent.manifest.test.js +85 -0
  250. package/dist/src/notemd.api.contract.test.js +14 -1
  251. package/dist/src/notemd.app_config_toml.test.js +2 -1
  252. package/dist/src/notemd.batch.workflow.test.js +117 -0
  253. package/dist/src/notemd.cli.e2e.test.js +136 -0
  254. package/dist/src/notemd.core.test.js +51 -0
  255. package/dist/src/notemd.diagram.pipeline.test.js +233 -0
  256. package/dist/src/notemd.providerTemplates.test.js +34 -0
  257. package/dist/src/notemd.server.integration.test.js +262 -39
  258. package/dist/src/notemd.workflow.pipeline.test.js +162 -0
  259. package/dist/src/pathbridge.handshake.contract.test.js +45 -2
  260. package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
  261. package/dist/src/pathcore.bundle.contract.test.js +8 -0
  262. package/dist/src/pathmode.background.contract.test.js +69 -0
  263. package/dist/src/pathmode.settings.api.contract.test.js +9 -0
  264. package/dist/src/pkg.sidecar.contract.test.js +9 -3
  265. package/dist/src/platform/ExportProfile.js +86 -0
  266. package/dist/src/platform/MobileBudget.js +11 -0
  267. package/dist/src/platform/PlatformCapabilities.js +59 -0
  268. package/dist/src/platform/PlatformCapabilities.test.js +36 -0
  269. package/dist/src/platform/RenderMaterializer.js +33 -0
  270. package/dist/src/platform/RenderMaterializer.test.js +32 -0
  271. package/dist/src/query_backend.external_http.integration.test.js +410 -0
  272. package/dist/src/reader_renderer.js +404 -3
  273. package/dist/src/reader_renderer.test.js +87 -0
  274. package/dist/src/release.godot.mirror.contract.test.js +97 -0
  275. package/dist/src/resources/ResourceRegistry.js +263 -0
  276. package/dist/src/resources/ResourceRegistry.test.js +97 -0
  277. package/dist/src/resources/types.js +2 -0
  278. package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
  279. package/dist/src/routes/index.js +19 -0
  280. package/dist/src/routes/knowledge.js +981 -0
  281. package/dist/src/routes/knowledgePayload.js +185 -0
  282. package/dist/src/routes/knowledgePayload.test.js +53 -0
  283. package/dist/src/routes/markdown.js +295 -0
  284. package/dist/src/routes/notemd.js +1321 -0
  285. package/dist/src/routes/registry.contract.test.js +133 -0
  286. package/dist/src/routes/registry.shadow.contract.test.js +22 -0
  287. package/dist/src/routes/render.js +248 -0
  288. package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
  289. package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
  290. package/dist/src/routes/settings.js +6 -0
  291. package/dist/src/routes/staticFiles.js +94 -0
  292. package/dist/src/routes/types.js +2 -0
  293. package/dist/src/runtime.capabilities.test.js +18 -2
  294. package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
  295. package/dist/src/server.js +10342 -1325
  296. package/dist/src/server.migration.test.js +584 -10
  297. package/dist/src/server.port.fallback.contract.test.js +63 -0
  298. package/dist/src/session/SessionStateStore.js +81 -0
  299. package/dist/src/session/SessionStateStore.test.js +58 -0
  300. package/dist/src/session/types.js +2 -0
  301. package/dist/src/settings.runtime.contract.test.js +50 -0
  302. package/dist/src/shared/types.contract.test.js +107 -0
  303. package/dist/src/shared/types.js +22 -0
  304. package/dist/src/sidecar.build.lock.contract.test.js +201 -0
  305. package/dist/src/sidecar.freshness.contract.test.js +184 -0
  306. package/dist/src/sidecar.replacement.boundary.contract.test.js +131 -0
  307. package/dist/src/sidecar.supply.readiness.contract.test.js +155 -0
  308. package/dist/src/simulation.worker.offline.test.js +104 -0
  309. package/dist/src/source_manager.loadflow.test.js +46 -0
  310. package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
  311. package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
  312. package/dist/src/storage.provider.contract.test.js +152 -1
  313. package/dist/src/tauri.frontend.build.contract.test.js +68 -0
  314. package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
  315. package/dist/src/tauri.window.evidence.execution.test.js +68 -0
  316. package/dist/src/utils/RuntimePaths.js +10 -13
  317. package/dist/src/utils/RuntimePaths.test.js +27 -0
  318. package/dist/src/utils/platform.js +153 -0
  319. package/dist/src/windows.installer.build.test.js +109 -0
  320. package/dist/src/windows.installer.payload.test.js +76 -0
  321. package/dist/src/windows.installer.runtime.test.js +69 -0
  322. package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
  323. package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
  324. package/dist/src/workflows/types.js +2 -0
  325. package/dist/src/workspace/WorkspaceRegistry.js +135 -0
  326. package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
  327. package/dist/src/workspace/types.js +2 -0
  328. package/package.json +80 -15
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS = exports.GRAPH_ANSWER_QUALITY_POLICY_VERSION = void 0;
4
+ exports.evaluateGraphAnswerQualityCalibration = evaluateGraphAnswerQualityCalibration;
5
+ const graphAnswerCoverageCalibration_1 = require("./graphAnswerCoverageCalibration");
6
+ const graphClaimMatcher_1 = require("./graphClaimMatcher");
7
+ const graphAnswerQualityPolicy_1 = require("./graphAnswerQualityPolicy");
8
+ const ragEvidenceQuality_1 = require("./ragEvidenceQuality");
9
+ const ragPublicText_1 = require("./ragPublicText");
10
+ var graphAnswerQualityPolicy_2 = require("./graphAnswerQualityPolicy");
11
+ Object.defineProperty(exports, "GRAPH_ANSWER_QUALITY_POLICY_VERSION", { enumerable: true, get: function () { return graphAnswerQualityPolicy_2.GRAPH_ANSWER_QUALITY_POLICY_VERSION; } });
12
+ exports.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS = {
13
+ version: graphAnswerQualityPolicy_1.GRAPH_ANSWER_QUALITY_POLICY_VERSION,
14
+ coverageCases: graphAnswerCoverageCalibration_1.DEFAULT_GRAPH_ANSWER_COVERAGE_CALIBRATION_CASES,
15
+ sourceQualityCases: [
16
+ {
17
+ caseId: 'source_quality_equation_over_documentary_en',
18
+ preferredClause: 'The thermal flux is q = kA(T1 - T2) / L, so thickness changes the exchange rate.',
19
+ rejectedClause: 'This document will explain the following table as requested.',
20
+ },
21
+ {
22
+ caseId: 'source_quality_complete_fact_over_heading_en',
23
+ preferredClause: 'Glass conducts heat through the wall before the liquid temperature changes.',
24
+ rejectedClause: 'Thermal transfer:',
25
+ },
26
+ {
27
+ caseId: 'source_quality_complete_fact_over_meta_zh',
28
+ preferredClause: '热量穿过杯壁后,液体温度会上升。',
29
+ rejectedClause: '本文档旨在说明以下表格。',
30
+ },
31
+ {
32
+ caseId: 'source_quality_balanced_formula_over_fragment_en',
33
+ preferredClause: 'The pressure is P = rho g h, and the wall stress remains below the material limit.',
34
+ rejectedClause: 'The pressure is P = rho g h (',
35
+ },
36
+ ],
37
+ deduplicationCases: [
38
+ {
39
+ caseId: 'dedup_paraphrase_en',
40
+ left: 'A water glass is a transparent vessel used to hold water.',
41
+ right: 'A water glass is a transparent container used to hold water.',
42
+ expectedDuplicate: true,
43
+ },
44
+ {
45
+ caseId: 'dedup_paraphrase_zh',
46
+ left: '水杯是用于盛水的透明容器。',
47
+ right: '水杯是一种透明的盛水器皿。',
48
+ expectedDuplicate: true,
49
+ },
50
+ {
51
+ caseId: 'dedup_conflicting_value_en',
52
+ left: 'The release date is 2026-07-01.',
53
+ right: 'The release date is 2026-08-15.',
54
+ expectedDuplicate: false,
55
+ },
56
+ {
57
+ caseId: 'dedup_polarity_conflict_en',
58
+ left: 'Glass conducts heat through the wall.',
59
+ right: 'Glass does not conduct heat through the wall.',
60
+ expectedDuplicate: false,
61
+ },
62
+ {
63
+ caseId: 'dedup_distinct_mechanisms_en',
64
+ left: 'Heat passes through the wall by conduction.',
65
+ right: 'The curved vessel changes the path of incoming light.',
66
+ expectedDuplicate: false,
67
+ },
68
+ {
69
+ caseId: 'dedup_same_fact_with_heading_en',
70
+ left: 'The glass wall separates the liquid from the environment.',
71
+ right: 'The glass wall separates liquid from the environment.',
72
+ expectedDuplicate: true,
73
+ },
74
+ ],
75
+ branchCoverageCases: [
76
+ {
77
+ caseId: 'branch_compare_glass_plastic_en',
78
+ answer: 'Plastic is the comparison material, and compared with it, glass conducts heat better and remains more rigid.',
79
+ requiredBranchStatements: ['Glass conducts heat better.', 'Plastic is the comparison material.'],
80
+ },
81
+ {
82
+ caseId: 'branch_compare_glass_plastic_zh',
83
+ answer: '与塑料相比,玻璃导热更快。',
84
+ requiredBranchStatements: ['玻璃导热。', '塑料是比较对象。'],
85
+ },
86
+ {
87
+ caseId: 'branch_compare_environment_versions_en',
88
+ answer: 'Version 1 applies in staging, while version 2 applies in production.',
89
+ requiredBranchStatements: ['Version 1 applies in staging.', 'Version 2 applies in production.'],
90
+ },
91
+ {
92
+ caseId: 'branch_compare_material_boundary_zh',
93
+ answer: '玻璃是透明非晶态固体,塑料杯则是聚合物容器。',
94
+ requiredBranchStatements: ['玻璃是透明固体。', '塑料是聚合物容器。'],
95
+ },
96
+ ],
97
+ languageConsistencyCases: [
98
+ { caseId: 'language_en_definition', query: 'what is a water glass?', answer: 'A water glass is a transparent vessel for water.', expectedConsistent: true },
99
+ { caseId: 'language_zh_definition', query: '什么是水杯?', answer: '水杯是用于盛水的透明容器。', expectedConsistent: true },
100
+ { caseId: 'language_en_compare', query: 'compare glass and plastic', answer: 'Glass conducts heat better than plastic.', expectedConsistent: true },
101
+ { caseId: 'language_zh_compare', query: '比较玻璃和塑料', answer: '与塑料相比,玻璃导热更快。', expectedConsistent: true },
102
+ { caseId: 'language_en_math', query: 'what is the pressure?', answer: 'The pressure is P = rho g h.', expectedConsistent: true },
103
+ { caseId: 'language_mismatch_en_query_zh_answer', query: 'what is a water glass?', answer: '水杯是用于盛水的透明容器。', expectedConsistent: false },
104
+ { caseId: 'language_mismatch_zh_query_en_answer', query: '什么是水杯?', answer: 'A water glass is a transparent vessel for water.', expectedConsistent: false },
105
+ ],
106
+ readabilityCases: [
107
+ { caseId: 'readability_complete_en', answer: 'A water glass is a transparent vessel used to hold water.', expectedReadable: true },
108
+ { caseId: 'readability_complete_zh', answer: '水杯是用于盛水的透明容器。', expectedReadable: true },
109
+ { caseId: 'readability_balanced_math_en', answer: 'The pressure is P = rho g h, so a taller water column increases the load.', expectedReadable: true },
110
+ { caseId: 'readability_two_claims_en', answer: 'Glass conducts heat through the wall. The liquid temperature rises afterward.', expectedReadable: true },
111
+ { caseId: 'readability_two_claims_zh', answer: '热量穿过杯壁后,液体温度会上升。玻璃壁仍然把液体与环境分隔开。', expectedReadable: true },
112
+ { caseId: 'readability_reject_documentary_en', answer: 'This document will explain the following table as requested.', expectedReadable: false },
113
+ { caseId: 'readability_reject_unbalanced_formula_en', answer: 'The pressure is P = rho g h (.', expectedReadable: false },
114
+ { caseId: 'readability_reject_authoring_zh', answer: '本技术文档旨在说明下表。', expectedReadable: false },
115
+ { caseId: 'readability_reject_dangling_heading_en', answer: 'Thermal transfer:', expectedReadable: false },
116
+ ],
117
+ };
118
+ function metricFromOutcomes(outcomes) {
119
+ const passedCount = outcomes.filter((outcome) => outcome.passed).length;
120
+ return {
121
+ sampleCount: outcomes.length,
122
+ passedCount,
123
+ failedCaseIds: outcomes.filter((outcome) => !outcome.passed).map((outcome) => outcome.caseId),
124
+ accuracy: outcomes.length > 0 ? Number((passedCount / outcomes.length).toFixed(4)) : 0,
125
+ };
126
+ }
127
+ function detectLanguage(value) {
128
+ const cjkCount = (String(value || '').match(/[\u3400-\u9fff]/gu) || []).length;
129
+ const latinCount = (String(value || '').match(/[A-Za-z]/gu) || []).length;
130
+ return cjkCount > latinCount ? 'zh' : 'en';
131
+ }
132
+ function evaluateSourceQuality(cases) {
133
+ const margins = [];
134
+ const outcomes = cases.map((item) => {
135
+ const margin = (0, ragEvidenceQuality_1.scoreRagEvidenceClause)(item.preferredClause).score
136
+ - (0, ragEvidenceQuality_1.scoreRagEvidenceClause)(item.rejectedClause).score;
137
+ margins.push(margin);
138
+ return { caseId: item.caseId, passed: margin > 0 };
139
+ });
140
+ const metric = metricFromOutcomes(outcomes);
141
+ return {
142
+ ...metric,
143
+ pairwiseAccuracy: metric.accuracy,
144
+ minimumObservedMargin: margins.length > 0
145
+ ? Number(Math.min(...margins).toFixed(4))
146
+ : 0,
147
+ };
148
+ }
149
+ function evaluateDeduplication(cases) {
150
+ const outcomes = cases.map((item) => {
151
+ const observedDuplicate = (0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)(item.left, item.right);
152
+ return { caseId: item.caseId, passed: observedDuplicate === item.expectedDuplicate };
153
+ });
154
+ return {
155
+ ...metricFromOutcomes(outcomes),
156
+ similarityThreshold: graphAnswerQualityPolicy_1.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD,
157
+ };
158
+ }
159
+ function evaluateBranchCoverage(cases) {
160
+ const outcomes = [];
161
+ let requiredBranchCount = 0;
162
+ let coveredBranchCount = 0;
163
+ cases.forEach((item) => {
164
+ const branchResults = item.requiredBranchStatements.map((statement) => (0, graphClaimMatcher_1.matchGraphAnswerClaim)(item.answer, statement).covered);
165
+ const covered = branchResults.filter(Boolean).length;
166
+ requiredBranchCount += branchResults.length;
167
+ coveredBranchCount += covered;
168
+ const passed = covered === branchResults.length;
169
+ outcomes.push({ caseId: item.caseId, passed });
170
+ });
171
+ const metric = metricFromOutcomes(outcomes);
172
+ return {
173
+ ...metric,
174
+ requiredBranchCount,
175
+ coveredBranchCount,
176
+ recall: requiredBranchCount > 0 ? Number((coveredBranchCount / requiredBranchCount).toFixed(4)) : 0,
177
+ };
178
+ }
179
+ function evaluateLanguageConsistency(cases) {
180
+ const outcomes = cases.map((item) => {
181
+ const observedConsistent = detectLanguage(item.answer) === detectLanguage(item.query);
182
+ return { caseId: item.caseId, passed: observedConsistent === item.expectedConsistent };
183
+ });
184
+ return metricFromOutcomes(outcomes);
185
+ }
186
+ function evaluateReadability(cases) {
187
+ const minimumAcceptedScore = graphAnswerQualityPolicy_1.MINIMUM_READABILITY_SCORE;
188
+ const observedScores = [];
189
+ const outcomes = cases.map((item) => {
190
+ const clauses = (0, ragEvidenceQuality_1.segmentRagEvidenceClauses)(item.answer);
191
+ const qualities = clauses.map((clause) => ({
192
+ clause,
193
+ quality: (0, ragEvidenceQuality_1.scoreRagEvidenceClause)(clause),
194
+ }));
195
+ if (item.expectedReadable) {
196
+ qualities.forEach(({ quality }) => observedScores.push(quality.score));
197
+ }
198
+ const observedReadable = qualities.length > 0 && qualities.every(({ clause, quality }) => {
199
+ return quality.score >= minimumAcceptedScore
200
+ && quality.hasBalancedDelimiters
201
+ && !(0, ragPublicText_1.shouldRejectPublicEvidenceClause)(clause)
202
+ && !/[::]$/u.test(clause);
203
+ });
204
+ return { caseId: item.caseId, passed: observedReadable === item.expectedReadable };
205
+ });
206
+ return {
207
+ ...metricFromOutcomes(outcomes),
208
+ minimumAcceptedScore,
209
+ minimumObservedScore: observedScores.length > 0
210
+ ? Number(Math.min(...observedScores).toFixed(4))
211
+ : 0,
212
+ };
213
+ }
214
+ function evaluateGraphAnswerQualityCalibration(corpus = exports.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS) {
215
+ const coverage = (0, graphAnswerCoverageCalibration_1.evaluateGraphAnswerCoverageCalibration)(corpus.coverageCases);
216
+ const sourceQuality = evaluateSourceQuality(corpus.sourceQualityCases);
217
+ const deduplication = evaluateDeduplication(corpus.deduplicationCases);
218
+ const branchCoverage = evaluateBranchCoverage(corpus.branchCoverageCases);
219
+ const languageConsistency = evaluateLanguageConsistency(corpus.languageConsistencyCases);
220
+ const readability = evaluateReadability(corpus.readabilityCases);
221
+ const versionCompatible = corpus.version === graphAnswerQualityPolicy_1.GRAPH_ANSWER_QUALITY_POLICY_VERSION;
222
+ const emptyCalibrationDimensions = [
223
+ ['coverage', corpus.coverageCases],
224
+ ['source_quality', corpus.sourceQualityCases],
225
+ ['deduplication', corpus.deduplicationCases],
226
+ ['branch_coverage', corpus.branchCoverageCases],
227
+ ['language_consistency', corpus.languageConsistencyCases],
228
+ ['readability', corpus.readabilityCases],
229
+ ]
230
+ .filter(([, cases]) => cases.length === 0)
231
+ .map(([dimension]) => `corpus_empty:${dimension}`);
232
+ const failedCaseIds = Array.from(new Set([
233
+ ...(versionCompatible ? [] : ['corpus_policy_version_mismatch']),
234
+ ...emptyCalibrationDimensions,
235
+ ...coverage.falsePositiveCaseIds,
236
+ ...coverage.falseNegativeCaseIds,
237
+ ...sourceQuality.failedCaseIds,
238
+ ...deduplication.failedCaseIds,
239
+ ...branchCoverage.failedCaseIds,
240
+ ...languageConsistency.failedCaseIds,
241
+ ...readability.failedCaseIds,
242
+ ]));
243
+ return {
244
+ version: corpus.version,
245
+ versionCompatible,
246
+ coverage,
247
+ sourceQuality,
248
+ deduplication,
249
+ branchCoverage,
250
+ languageConsistency,
251
+ readability,
252
+ failedCaseIds,
253
+ jointPass: versionCompatible && emptyCalibrationDimensions.length === 0 && failedCaseIds.length === 0,
254
+ };
255
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphAnswerQualityCalibration_1 = require("./graphAnswerQualityCalibration");
4
+ const graphAnswerQualityPolicy_1 = require("./graphAnswerQualityPolicy");
5
+ describe('graph answer quality calibration', () => {
6
+ test('uses an explicit versioned policy and preserves contradictory claims', () => {
7
+ expect(graphAnswerQualityCalibration_1.GRAPH_ANSWER_QUALITY_POLICY_VERSION).toBe('2026-07-23.v2');
8
+ expect(graphAnswerQualityPolicy_1.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD).toBe(0.86);
9
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('Glass is transparent and conducts heat.', 'The glass is transparent and conducts heat.')).toBe(true);
10
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('Glass is transparent and conducts heat.', 'Glass is not transparent and does not conduct heat.')).toBe(false);
11
+ });
12
+ test('keeps signed and unit-qualified numeric facts distinct', () => {
13
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('The temperature is -5 C.', 'The temperature is 5 C.')).toBe(false);
14
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('The wall is 5 cm thick.', 'The wall is 5 mm thick.')).toBe(false);
15
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('The wall is 5 cm thick.', 'The wall is 5 cm thick.')).toBe(true);
16
+ expect((0, graphAnswerQualityPolicy_1.isPolaritySafeSemanticDuplicate)('玻璃壁厚为5厘米。', '玻璃壁厚为5毫米。')).toBe(false);
17
+ });
18
+ test('reports all quality dimensions and exact failures for the default corpus', () => {
19
+ const report = (0, graphAnswerQualityCalibration_1.evaluateGraphAnswerQualityCalibration)(graphAnswerQualityCalibration_1.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS);
20
+ expect(report.version).toBe(graphAnswerQualityCalibration_1.GRAPH_ANSWER_QUALITY_POLICY_VERSION);
21
+ expect(report.coverage.sampleCount).toBeGreaterThanOrEqual(24);
22
+ expect(report.sourceQuality.sampleCount).toBeGreaterThanOrEqual(4);
23
+ expect(report.deduplication.sampleCount).toBeGreaterThanOrEqual(4);
24
+ expect(report.branchCoverage.sampleCount).toBeGreaterThanOrEqual(4);
25
+ expect(report.languageConsistency.sampleCount).toBeGreaterThanOrEqual(7);
26
+ expect(report.readability.sampleCount).toBeGreaterThanOrEqual(8);
27
+ expect(report.failedCaseIds).toEqual([]);
28
+ expect(report.jointPass).toBe(true);
29
+ expect(report.sourceQuality.pairwiseAccuracy).toBeGreaterThanOrEqual(0.95);
30
+ expect(report.sourceQuality.minimumObservedMargin).toBeGreaterThan(0);
31
+ expect(report.deduplication.accuracy).toBeGreaterThanOrEqual(0.95);
32
+ expect(report.deduplication.similarityThreshold).toBe(graphAnswerQualityPolicy_1.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD);
33
+ expect(report.branchCoverage.recall).toBeGreaterThanOrEqual(0.95);
34
+ expect(report.languageConsistency.accuracy).toBeGreaterThanOrEqual(0.95);
35
+ expect(report.readability.accuracy).toBeGreaterThanOrEqual(0.95);
36
+ expect(report.readability.minimumAcceptedScore).toBe(graphAnswerQualityPolicy_1.MINIMUM_READABILITY_SCORE);
37
+ expect(report.readability.minimumObservedScore).toBeGreaterThanOrEqual(graphAnswerQualityPolicy_1.MINIMUM_READABILITY_SCORE);
38
+ });
39
+ test('does not hide dimension-specific failures behind a single aggregate score', () => {
40
+ const report = (0, graphAnswerQualityCalibration_1.evaluateGraphAnswerQualityCalibration)({
41
+ ...graphAnswerQualityCalibration_1.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS,
42
+ sourceQualityCases: [
43
+ {
44
+ caseId: 'source_quality_failure',
45
+ preferredClause: 'This document contains a table.',
46
+ rejectedClause: 'Glass conducts heat through the wall.',
47
+ },
48
+ ],
49
+ });
50
+ expect(report.jointPass).toBe(false);
51
+ expect(report.sourceQuality.failedCaseIds).toEqual(['source_quality_failure']);
52
+ expect(report.failedCaseIds).toContain('source_quality_failure');
53
+ });
54
+ test('fails closed when the corpus version drifts from the production policy', () => {
55
+ const report = (0, graphAnswerQualityCalibration_1.evaluateGraphAnswerQualityCalibration)({
56
+ ...graphAnswerQualityCalibration_1.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS,
57
+ version: '2026-07-23.stale',
58
+ });
59
+ expect(report.versionCompatible).toBe(false);
60
+ expect(report.jointPass).toBe(false);
61
+ expect(report.failedCaseIds).toContain('corpus_policy_version_mismatch');
62
+ });
63
+ test('fails closed when a calibration dimension has no cases', () => {
64
+ const report = (0, graphAnswerQualityCalibration_1.evaluateGraphAnswerQualityCalibration)({
65
+ ...graphAnswerQualityCalibration_1.DEFAULT_GRAPH_ANSWER_QUALITY_CORPUS,
66
+ readabilityCases: [],
67
+ });
68
+ expect(report.readability.accuracy).toBe(0);
69
+ expect(report.failedCaseIds).toContain('corpus_empty:readability');
70
+ expect(report.jointPass).toBe(false);
71
+ });
72
+ });
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MINIMUM_READABILITY_SCORE = exports.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD = exports.GRAPH_ANSWER_QUALITY_POLICY_VERSION = void 0;
4
+ exports.graphClaimsCanShareCoverage = graphClaimsCanShareCoverage;
5
+ exports.isPolaritySafeSemanticDuplicate = isPolaritySafeSemanticDuplicate;
6
+ const graphClaimMatcher_1 = require("./graphClaimMatcher");
7
+ exports.GRAPH_ANSWER_QUALITY_POLICY_VERSION = '2026-07-23.v2';
8
+ exports.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD = 0.86;
9
+ exports.MINIMUM_READABILITY_SCORE = 0.5;
10
+ // Keep signs and common measurement suffixes in the fact key so distinct values
11
+ // cannot be collapsed by lexical similarity alone.
12
+ const NUMERIC_FACT_PATTERN = /([+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:e[+-]?\d+)?)(?:\s*(%|°[cfk]|days?|weeks?|months?|years?|milliseconds?|ms|min|hours?|hr|h|seconds?|s|km|cm|mm|nm|um|m|in|ft|yd|mi|kg|mg|lb|oz|kpa|mpa|pa|bar|kj|kw|hz|kb|mb|gb|tb|usd|eur|cny|rmb|c|f|k|g|j|w|v|a|\u6beb\u79d2|\u5206\u949f|\u5c0f\u65f6|\u5929|\u5468|\u6708|\u5e74|\u6beb\u7c73|\u5398\u7c73|\u5343\u7c73|\u7c73|\u6beb\u514b|\u5343\u514b|\u514b|\u5146\u5e15|\u5343\u5e15|\u5e15|\u6444\u6c0f\u5ea6|\u534e\u6c0f\u5ea6|\u5143|\u7f8e\u5143|\u6b27\u5143))?(?![\p{L}\p{N}_])/giu;
13
+ function numericFacts(value) {
14
+ return Array.from(new Set(Array.from(String(value || '').matchAll(NUMERIC_FACT_PATTERN), (match) => (`${match[1].toLowerCase()}|${(match[2] || '').toLowerCase()}`)))).sort();
15
+ }
16
+ function graphClaimsCanShareCoverage(left, right) {
17
+ if ((0, graphClaimMatcher_1.isGraphClaimNegated)(left) !== (0, graphClaimMatcher_1.isGraphClaimNegated)(right)) {
18
+ return false;
19
+ }
20
+ const leftNumbers = numericFacts(left);
21
+ const rightNumbers = numericFacts(right);
22
+ if (leftNumbers.length > 0 && rightNumbers.length > 0 && leftNumbers.join('|') !== rightNumbers.join('|')) {
23
+ return false;
24
+ }
25
+ return true;
26
+ }
27
+ function isPolaritySafeSemanticDuplicate(left, right) {
28
+ return graphClaimsCanShareCoverage(left, right)
29
+ && (0, graphClaimMatcher_1.graphClaimSemanticSimilarity)(left, right) >= exports.SUPPLEMENTAL_DEDUP_SIMILARITY_THRESHOLD;
30
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isGraphClaimNegated = isGraphClaimNegated;
4
+ exports.semanticFeatures = semanticFeatures;
5
+ exports.graphClaimSemanticSimilarity = graphClaimSemanticSimilarity;
6
+ exports.matchGraphAnswerClaim = matchGraphAnswerClaim;
7
+ const STOPWORDS = new Set([
8
+ 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'between', 'by', 'for', 'from', 'in', 'is', 'it',
9
+ 'of', 'on', 'or', 'that', 'the', 'their', 'this', 'through', 'to', 'with', 'its', 'will',
10
+ ]);
11
+ const CONCEPT_PATTERNS = [
12
+ ['transparent', /\btransparent\b|透明/u],
13
+ ['container', /\b(?:container|vessel|cup|water\s+glass)\b|容器|水杯|杯子/u],
14
+ ['glass_material', /\bglass\b|玻璃/u],
15
+ ['plastic', /\bplastic\b|塑料/u],
16
+ ['comparison', /\b(?:compare|compared|than|versus)\b|相比|比/u],
17
+ ['water', /\b(?:water|liquid)\b|水|液体/u],
18
+ ['drink', /\b(?:drink|drinking)\b|饮用|喝水/u],
19
+ ['wall', /\b(?:glass\s+)?wall\b|杯壁|玻璃壁|实体壁/u],
20
+ ['boundary', /\b(?:boundary|separate|separates|separated|divide|divides)\b|边界|隔开|分隔/u],
21
+ ['environment', /\b(?:environment|surroundings?|outside|external)\b|环境|外部|周围/u],
22
+ ['heat', /\b(?:heat|heating|thermal(?:\s+energy)?)\b|加热|受热|热量|热能|导热|热交换|换热/u],
23
+ ['transfer', /\b(?:move|moves|pass|passes|conduct|conducts|transfer|exchange)\b|穿过|传递|经由|交换|换热/u],
24
+ ['thickness', /\bthickness\b|厚度|壁厚/u],
25
+ ['affect', /\b(?:affect|affects|change|changes|influence|influences)\b|影响|改变/u],
26
+ ['cause', /\b(?:because|cause|causes|lead|leads|result|results)\b|导致|造成|引起/u],
27
+ ['rise', /\b(?:rise|rises|rising|raise|raises|increase|increases)\b|上升|升高|提高/u],
28
+ ['apply', /\b(?:apply|applies|effective|valid)\b|生效|适用|有效/u],
29
+ ['before', /\b(?:before|prior|prerequisite)\b|之前|前置|先/u],
30
+ ['after', /\b(?:after|then|subsequent)\b|之后|以后|随后|再/u],
31
+ ];
32
+ const NEGATION_PATTERN = /\b(?:not|no|never|neither|without|cannot|can't|doesn't|does\s+not|isn't|is\s+not|has\s+no)\b|不(?:会|能|是|再|把|影响|改变|导致|造成|传递|穿过|隔开|分隔)?|并非|没有|无法|不能|不会|无关/u;
33
+ function isGraphClaimNegated(value) {
34
+ return NEGATION_PATTERN.test(String(value || ''));
35
+ }
36
+ function normalize(value) {
37
+ return String(value || '').toLowerCase().replace(/[^\p{L}\p{N}]+/gu, ' ').replace(/\s+/g, ' ').trim();
38
+ }
39
+ function lexicalTerms(value) {
40
+ return normalize(value)
41
+ .split(' ')
42
+ .filter((term) => term.length >= 3 && !STOPWORDS.has(term));
43
+ }
44
+ function semanticFeatures(value) {
45
+ const normalized = normalize(value);
46
+ const concepts = CONCEPT_PATTERNS
47
+ .filter(([, pattern]) => pattern.test(normalized))
48
+ .map(([concept]) => `concept:${concept}`);
49
+ const lexical = lexicalTerms(normalized)
50
+ .filter((term) => !CONCEPT_PATTERNS.some(([, pattern]) => pattern.test(term)))
51
+ .map((term) => `term:${term}`);
52
+ return Array.from(new Set([...concepts, ...lexical]));
53
+ }
54
+ function graphClaimSemanticSimilarity(left, right) {
55
+ const leftFeatures = new Set(semanticFeatures(left));
56
+ const rightFeatures = new Set(semanticFeatures(right));
57
+ if (leftFeatures.size === 0 || rightFeatures.size === 0)
58
+ return 0;
59
+ const intersection = Array.from(leftFeatures).filter((feature) => rightFeatures.has(feature)).length;
60
+ return Number((intersection / Math.max(leftFeatures.size, rightFeatures.size)).toFixed(4));
61
+ }
62
+ function clauses(value) {
63
+ const normalizedValue = String(value || '').trim();
64
+ const splitClauses = normalizedValue
65
+ .split(/(?<=[.!?。!?;;])|[,,]\s*/u)
66
+ .map((clause) => clause.trim())
67
+ .filter(Boolean);
68
+ return splitClauses.length > 1 ? [...splitClauses, normalizedValue] : splitClauses;
69
+ }
70
+ function matchClause(statementFeatures, statementNegated, clause) {
71
+ const clauseFeatures = new Set(semanticFeatures(clause));
72
+ const matchedConcepts = statementFeatures.filter((feature) => clauseFeatures.has(feature));
73
+ const missingConcepts = statementFeatures.filter((feature) => !clauseFeatures.has(feature));
74
+ const score = statementFeatures.length > 0 ? matchedConcepts.length / statementFeatures.length : 0;
75
+ const minimumMatches = Math.min(statementFeatures.length, Math.max(2, Math.ceil(statementFeatures.length * 0.55)));
76
+ const polarityConflict = matchedConcepts.length >= minimumMatches && statementNegated !== isGraphClaimNegated(clause);
77
+ return {
78
+ covered: !polarityConflict && matchedConcepts.length >= minimumMatches && score >= 0.55,
79
+ score: Number(score.toFixed(4)),
80
+ matchedConcepts,
81
+ missingConcepts,
82
+ polarityConflict,
83
+ };
84
+ }
85
+ function matchGraphAnswerClaim(answer, statement) {
86
+ const normalizedStatement = normalize(statement);
87
+ if (!normalizedStatement) {
88
+ return { covered: false, score: 0, matchedConcepts: [], missingConcepts: [], polarityConflict: false };
89
+ }
90
+ const normalizedAnswer = normalize(answer);
91
+ const statementNegated = NEGATION_PATTERN.test(statement);
92
+ if (normalizedAnswer.includes(normalizedStatement) && statementNegated === isGraphClaimNegated(answer)) {
93
+ const features = semanticFeatures(statement);
94
+ return { covered: true, score: 1, matchedConcepts: features, missingConcepts: [], polarityConflict: false };
95
+ }
96
+ const features = semanticFeatures(statement);
97
+ if (features.length === 0) {
98
+ return { covered: false, score: 0, matchedConcepts: [], missingConcepts: [], polarityConflict: false };
99
+ }
100
+ return clauses(answer)
101
+ .map((clause) => matchClause(features, statementNegated, clause))
102
+ .sort((left, right) => Number(right.covered) - Number(left.covered) || right.score - left.score)[0]
103
+ || { covered: false, score: 0, matchedConcepts: [], missingConcepts: features, polarityConflict: false };
104
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.conditionRagFragmentsByGraphPlan = conditionRagFragmentsByGraphPlan;
4
+ function claimAtomIds(claim, anchorAtomId) {
5
+ return new Set([
6
+ anchorAtomId,
7
+ claim.subjectAtomId,
8
+ ...claim.supportingAtomIds,
9
+ ...claim.evidenceRefs.map((evidence) => evidence.atomId || ''),
10
+ ].filter(Boolean));
11
+ }
12
+ function matchFragmentToClaim(fragment, claim, anchorAtomId) {
13
+ const atomIds = claimAtomIds(claim, anchorAtomId);
14
+ if (fragment.atomId && atomIds.has(fragment.atomId)) {
15
+ return true;
16
+ }
17
+ const edgeIds = new Set(claim.supportingEdgeIds);
18
+ return (fragment.relationEdgeIds || []).some((edgeId) => edgeIds.has(edgeId));
19
+ }
20
+ function conditionRagFragmentsByGraphPlan(params) {
21
+ const fragments = Array.isArray(params.fragments) ? params.fragments : [];
22
+ const plan = params.graphAnswerPlan;
23
+ if (!plan) {
24
+ return {
25
+ fragmentOrder: fragments.map((fragment) => fragment.fragmentId),
26
+ trace: {
27
+ strategy: 'none',
28
+ matchedClaimCount: 0,
29
+ matchedFragmentCount: 0,
30
+ selectedAtomIds: [],
31
+ selectedEdgeIds: [],
32
+ fallbackReason: 'no_graph_answer_plan',
33
+ },
34
+ };
35
+ }
36
+ if (plan.claims.length <= 0) {
37
+ return {
38
+ fragmentOrder: fragments.map((fragment) => fragment.fragmentId),
39
+ trace: {
40
+ strategy: 'none',
41
+ matchedClaimCount: 0,
42
+ matchedFragmentCount: 0,
43
+ selectedAtomIds: [],
44
+ selectedEdgeIds: [],
45
+ fallbackReason: 'empty_graph_answer_plan',
46
+ },
47
+ };
48
+ }
49
+ const matches = new Map();
50
+ const matchedClaims = new Set();
51
+ const selectedAtomIds = new Set();
52
+ const selectedEdgeIds = new Set();
53
+ fragments.forEach((fragment) => {
54
+ const match = {
55
+ claimIds: new Set(),
56
+ priority: 0,
57
+ required: false,
58
+ };
59
+ plan.claims.forEach((claim) => {
60
+ if (!matchFragmentToClaim(fragment, claim, plan.anchorAtomId)) {
61
+ return;
62
+ }
63
+ match.claimIds.add(claim.claimId);
64
+ match.priority = Math.max(match.priority, claim.priority);
65
+ match.required = match.required || claim.required;
66
+ matchedClaims.add(claim.claimId);
67
+ });
68
+ if (match.claimIds.size <= 0) {
69
+ return;
70
+ }
71
+ matches.set(fragment.fragmentId, match);
72
+ if (fragment.atomId) {
73
+ selectedAtomIds.add(fragment.atomId);
74
+ }
75
+ (fragment.relationEdgeIds || []).forEach((edgeId) => {
76
+ if (plan.claims.some((claim) => claim.supportingEdgeIds.includes(edgeId))) {
77
+ selectedEdgeIds.add(edgeId);
78
+ }
79
+ });
80
+ });
81
+ const originalOrder = new Map(fragments.map((fragment, index) => [fragment.fragmentId, index]));
82
+ const fragmentOrder = fragments
83
+ .slice()
84
+ .sort((left, right) => {
85
+ const leftMatch = matches.get(left.fragmentId);
86
+ const rightMatch = matches.get(right.fragmentId);
87
+ const leftRank = leftMatch ? (leftMatch.required ? 0 : 1) : 2;
88
+ const rightRank = rightMatch ? (rightMatch.required ? 0 : 1) : 2;
89
+ if (leftRank !== rightRank) {
90
+ return leftRank - rightRank;
91
+ }
92
+ const priorityDelta = (rightMatch?.priority || 0) - (leftMatch?.priority || 0);
93
+ if (priorityDelta !== 0) {
94
+ return priorityDelta;
95
+ }
96
+ return (originalOrder.get(left.fragmentId) || 0) - (originalOrder.get(right.fragmentId) || 0);
97
+ })
98
+ .map((fragment) => fragment.fragmentId);
99
+ return {
100
+ fragmentOrder,
101
+ trace: {
102
+ strategy: 'graph_answer_plan',
103
+ matchedClaimCount: matchedClaims.size,
104
+ matchedFragmentCount: matches.size,
105
+ selectedAtomIds: Array.from(selectedAtomIds).sort(),
106
+ selectedEdgeIds: Array.from(selectedEdgeIds).sort(),
107
+ },
108
+ };
109
+ }