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,1033 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphContextAssembler_1 = require("./graphContextAssembler");
4
+ class InMemoryOpsStore {
5
+ constructor(atoms, relationEdges) {
6
+ this.atoms = atoms;
7
+ this.relationEdges = relationEdges;
8
+ }
9
+ async loadSnapshot() {
10
+ return null;
11
+ }
12
+ async saveSnapshot(_snapshot) {
13
+ }
14
+ getDiagnostics() {
15
+ return {
16
+ storeType: 'memory',
17
+ exists: true,
18
+ loaded: true,
19
+ };
20
+ }
21
+ getCapabilities() {
22
+ return {
23
+ snapshotSupported: true,
24
+ nodeQuerySupported: true,
25
+ edgeQuerySupported: true,
26
+ pathQuerySupported: true,
27
+ writeSupported: true,
28
+ serverSideQuery: false,
29
+ };
30
+ }
31
+ async getNode(atomId) {
32
+ return this.atoms.find((atom) => atom.id === atomId || atom.stableKey === atomId) || null;
33
+ }
34
+ async queryNodes(filter) {
35
+ if (Array.isArray(filter.nodeIds) && filter.nodeIds.length > 0) {
36
+ const nodeIdSet = new Set(filter.nodeIds);
37
+ return this.atoms.filter((atom) => nodeIdSet.has(atom.id) || nodeIdSet.has(atom.stableKey));
38
+ }
39
+ return this.atoms.slice(0, filter.limit || this.atoms.length);
40
+ }
41
+ async queryEdges(filter) {
42
+ return this.relationEdges.filter((edge) => {
43
+ if (filter.fromNodeId && edge.sourceAtomId !== filter.fromNodeId) {
44
+ return false;
45
+ }
46
+ if (filter.toNodeId && edge.targetAtomId !== filter.toNodeId) {
47
+ return false;
48
+ }
49
+ if (filter.relationKind && edge.relationKind !== filter.relationKind) {
50
+ return false;
51
+ }
52
+ return true;
53
+ }).slice(0, filter.limit || this.relationEdges.length);
54
+ }
55
+ async findPath(sourceId, targetId, maxDepth = 10) {
56
+ const adjacency = new Map();
57
+ this.relationEdges.forEach((edge) => {
58
+ const nextEdges = adjacency.get(edge.sourceAtomId) || [];
59
+ nextEdges.push({
60
+ to: edge.targetAtomId,
61
+ edge,
62
+ });
63
+ adjacency.set(edge.sourceAtomId, nextEdges);
64
+ });
65
+ const queue = [
66
+ { atomId: sourceId, path: [sourceId], edges: [] },
67
+ ];
68
+ const visited = new Set([sourceId]);
69
+ while (queue.length > 0) {
70
+ const current = queue.shift();
71
+ if (!current) {
72
+ continue;
73
+ }
74
+ if (current.path.length > maxDepth) {
75
+ continue;
76
+ }
77
+ if (current.atomId === targetId) {
78
+ return {
79
+ path: current.path,
80
+ length: current.path.length - 1,
81
+ edges: current.edges,
82
+ found: true,
83
+ };
84
+ }
85
+ const neighbors = adjacency.get(current.atomId) || [];
86
+ neighbors.forEach((neighbor) => {
87
+ if (visited.has(neighbor.to)) {
88
+ return;
89
+ }
90
+ visited.add(neighbor.to);
91
+ queue.push({
92
+ atomId: neighbor.to,
93
+ path: [...current.path, neighbor.to],
94
+ edges: [
95
+ ...current.edges,
96
+ {
97
+ from: neighbor.edge.sourceAtomId,
98
+ to: neighbor.edge.targetAtomId,
99
+ relation: neighbor.edge.relationKind,
100
+ },
101
+ ],
102
+ });
103
+ });
104
+ }
105
+ return {
106
+ path: [],
107
+ length: 0,
108
+ edges: [],
109
+ found: false,
110
+ };
111
+ }
112
+ }
113
+ const globalScope = {
114
+ source: 'global',
115
+ workspaceId: null,
116
+ corpusId: null,
117
+ documentIds: [],
118
+ atomIds: [],
119
+ sourcePathPrefixes: [],
120
+ languages: [],
121
+ matchedAtomCount: 3,
122
+ scopeSource: 'global_default',
123
+ };
124
+ function createKnowledgePoint(overrides) {
125
+ return {
126
+ atomId: 'atom_default',
127
+ atomIds: ['atom_default'],
128
+ documentId: 'doc_default',
129
+ sourcePath: 'Knowledge_Base/default.md',
130
+ title: 'Default Point',
131
+ summary: 'Default point summary.',
132
+ evidenceSnippet: 'Default point summary.',
133
+ score: 0.5,
134
+ citation: null,
135
+ citations: [],
136
+ matchedSpans: [],
137
+ matchCount: 0,
138
+ relationPath: [],
139
+ relationPathAtomIds: [],
140
+ relationKinds: [],
141
+ temporalValidity: {
142
+ isValid: true,
143
+ checkedAt: '2026-06-17T00:00:00.000Z',
144
+ reasons: [],
145
+ details: [],
146
+ },
147
+ capabilities: [],
148
+ ...overrides,
149
+ };
150
+ }
151
+ function createAtom(overrides) {
152
+ const id = String(overrides.id || 'atom_default');
153
+ return {
154
+ id,
155
+ stableKey: id,
156
+ documentId: 'doc_default',
157
+ sourcePath: `Knowledge_Base/${id}.md`,
158
+ title: id,
159
+ content: `${id} content.`,
160
+ representationType: 'text',
161
+ keywords: [],
162
+ evidenceSpanIds: [],
163
+ createdAt: '2026-06-17T00:00:00.000Z',
164
+ updatedAt: '2026-06-17T00:00:00.000Z',
165
+ metadata: {
166
+ sectionPath: [],
167
+ version: 1,
168
+ sourceHash: id,
169
+ language: 'en',
170
+ },
171
+ ...overrides,
172
+ };
173
+ }
174
+ describe('assembleAgentConversationGraphContext', () => {
175
+ test('selects a title-mentioned anchor and enriches bounded graph windows before answer synthesis', async () => {
176
+ const atoms = [
177
+ {
178
+ id: 'atom_foundation',
179
+ stableKey: 'foundation',
180
+ documentId: 'doc_foundation',
181
+ sourcePath: 'Knowledge_Base/optics/foundation.md',
182
+ title: 'Foundation Note',
183
+ content: 'Foundation note stabilizes the chain.',
184
+ representationType: 'text',
185
+ keywords: [],
186
+ evidenceSpanIds: [],
187
+ createdAt: '2026-06-17T00:00:00.000Z',
188
+ updatedAt: '2026-06-17T00:00:00.000Z',
189
+ metadata: {
190
+ sectionPath: [],
191
+ version: 1,
192
+ sourceHash: 'foundation',
193
+ language: 'en',
194
+ },
195
+ },
196
+ {
197
+ id: 'atom_bridge',
198
+ stableKey: 'bridge',
199
+ documentId: 'doc_bridge',
200
+ sourcePath: 'Knowledge_Base/optics/bridge.md',
201
+ title: 'Bridge Layer',
202
+ content: 'Bridge layer connects foundation to ground state.',
203
+ representationType: 'text',
204
+ keywords: [],
205
+ evidenceSpanIds: [],
206
+ createdAt: '2026-06-17T00:00:00.000Z',
207
+ updatedAt: '2026-06-17T00:00:00.000Z',
208
+ metadata: {
209
+ sectionPath: [],
210
+ version: 1,
211
+ sourceHash: 'bridge',
212
+ language: 'en',
213
+ },
214
+ },
215
+ {
216
+ id: 'atom_ground',
217
+ stableKey: 'ground',
218
+ documentId: 'doc_ground',
219
+ sourcePath: 'Knowledge_Base/optics/ground.md',
220
+ title: 'Ground State',
221
+ content: 'Ground state is the target optical state.',
222
+ representationType: 'text',
223
+ keywords: [],
224
+ evidenceSpanIds: [],
225
+ createdAt: '2026-06-17T00:00:00.000Z',
226
+ updatedAt: '2026-06-17T00:00:00.000Z',
227
+ metadata: {
228
+ sectionPath: [],
229
+ version: 1,
230
+ sourceHash: 'ground',
231
+ language: 'en',
232
+ },
233
+ },
234
+ {
235
+ id: 'atom_application',
236
+ stableKey: 'application',
237
+ documentId: 'doc_application',
238
+ sourcePath: 'Knowledge_Base/optics/application.md',
239
+ title: 'Application Example',
240
+ content: 'Application example extends the ground state into execution.',
241
+ representationType: 'text',
242
+ keywords: [],
243
+ evidenceSpanIds: [],
244
+ createdAt: '2026-06-17T00:00:00.000Z',
245
+ updatedAt: '2026-06-17T00:00:00.000Z',
246
+ metadata: {
247
+ sectionPath: [],
248
+ version: 1,
249
+ sourceHash: 'application',
250
+ language: 'en',
251
+ },
252
+ },
253
+ ];
254
+ const edges = [
255
+ {
256
+ id: 'edge_foundation_bridge',
257
+ sourceAtomId: 'atom_foundation',
258
+ targetAtomId: 'atom_bridge',
259
+ relationKind: 'prerequisite',
260
+ provenance: 'fact',
261
+ confidence: 0.91,
262
+ evidenceSpanIds: [],
263
+ temporal: {
264
+ validFrom: '2026-06-17T00:00:00.000Z',
265
+ },
266
+ },
267
+ {
268
+ id: 'edge_bridge_ground',
269
+ sourceAtomId: 'atom_bridge',
270
+ targetAtomId: 'atom_ground',
271
+ relationKind: 'reference',
272
+ provenance: 'fact',
273
+ confidence: 0.88,
274
+ evidenceSpanIds: [],
275
+ temporal: {
276
+ validFrom: '2026-06-17T00:00:00.000Z',
277
+ },
278
+ },
279
+ {
280
+ id: 'edge_ground_application',
281
+ sourceAtomId: 'atom_ground',
282
+ targetAtomId: 'atom_application',
283
+ relationKind: 'sequence',
284
+ provenance: 'fact',
285
+ confidence: 0.74,
286
+ evidenceSpanIds: [],
287
+ temporal: {
288
+ validFrom: '2026-06-17T00:00:00.000Z',
289
+ },
290
+ },
291
+ ];
292
+ const knowledgePoints = [
293
+ createKnowledgePoint({
294
+ atomId: 'atom_foundation',
295
+ atomIds: ['atom_foundation'],
296
+ documentId: 'doc_foundation',
297
+ sourcePath: 'Knowledge_Base/optics/foundation.md',
298
+ title: 'Foundation Note',
299
+ summary: 'Foundation note stabilizes the optics chain.',
300
+ evidenceSnippet: 'Foundation note stabilizes the optics chain.',
301
+ score: 0.94,
302
+ citation: {
303
+ citationId: 'citation_foundation',
304
+ atomId: 'atom_foundation',
305
+ documentId: 'doc_foundation',
306
+ sourcePath: 'Knowledge_Base/optics/foundation.md',
307
+ title: 'Foundation Note',
308
+ snippet: 'Foundation note stabilizes the optics chain.',
309
+ startLine: 4,
310
+ endLine: 4,
311
+ score: 0.94,
312
+ },
313
+ citations: [
314
+ {
315
+ citationId: 'citation_foundation',
316
+ atomId: 'atom_foundation',
317
+ documentId: 'doc_foundation',
318
+ sourcePath: 'Knowledge_Base/optics/foundation.md',
319
+ title: 'Foundation Note',
320
+ snippet: 'Foundation note stabilizes the optics chain.',
321
+ startLine: 4,
322
+ endLine: 4,
323
+ score: 0.94,
324
+ },
325
+ ],
326
+ }),
327
+ createKnowledgePoint({
328
+ atomId: 'atom_ground',
329
+ atomIds: ['atom_ground'],
330
+ documentId: 'doc_ground',
331
+ sourcePath: 'Knowledge_Base/optics/ground.md',
332
+ title: 'Ground State',
333
+ summary: 'Ground state is the target optical state.',
334
+ evidenceSnippet: 'Ground state is the target optical state.',
335
+ score: 0.91,
336
+ citation: {
337
+ citationId: 'citation_ground',
338
+ atomId: 'atom_ground',
339
+ documentId: 'doc_ground',
340
+ sourcePath: 'Knowledge_Base/optics/ground.md',
341
+ title: 'Ground State',
342
+ snippet: 'Ground state is the target optical state.',
343
+ startLine: 8,
344
+ endLine: 8,
345
+ score: 0.91,
346
+ },
347
+ citations: [
348
+ {
349
+ citationId: 'citation_ground',
350
+ atomId: 'atom_ground',
351
+ documentId: 'doc_ground',
352
+ sourcePath: 'Knowledge_Base/optics/ground.md',
353
+ title: 'Ground State',
354
+ snippet: 'Ground state is the target optical state.',
355
+ startLine: 8,
356
+ endLine: 8,
357
+ score: 0.91,
358
+ },
359
+ ],
360
+ }),
361
+ createKnowledgePoint({
362
+ atomId: 'atom_application',
363
+ atomIds: ['atom_application'],
364
+ documentId: 'doc_application',
365
+ sourcePath: 'Knowledge_Base/optics/application.md',
366
+ title: 'Application Example',
367
+ summary: 'Application example extends the ground state into execution.',
368
+ evidenceSnippet: 'Application example extends the ground state into execution.',
369
+ score: 0.73,
370
+ }),
371
+ ];
372
+ const store = new InMemoryOpsStore(atoms, edges);
373
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
374
+ message: 'how to calibrate ground state',
375
+ usedScope: globalScope,
376
+ knowledgePoints,
377
+ store,
378
+ });
379
+ expect(result.knowledgePoints[0].title).toBe('Ground State');
380
+ expect(result.graphContext).not.toBeNull();
381
+ expect(result.graphContext).toEqual(expect.objectContaining({
382
+ anchorAtomId: 'atom_ground',
383
+ anchorTitle: 'Ground State',
384
+ evidenceSourceRefs: expect.arrayContaining([
385
+ 'Knowledge_Base/optics/foundation.md:4',
386
+ 'Knowledge_Base/optics/ground.md:8',
387
+ ]),
388
+ diagnostics: expect.objectContaining({
389
+ graphOpsAvailable: true,
390
+ selectedAnchorReason: 'title_mention',
391
+ candidateCount: 3,
392
+ }),
393
+ }));
394
+ expect(result.graphContext.connectionPaths).toEqual(expect.arrayContaining([
395
+ expect.objectContaining({
396
+ sourceTitle: 'Foundation Note',
397
+ targetTitle: 'Ground State',
398
+ pathTitles: ['Foundation Note', 'Bridge Layer', 'Ground State'],
399
+ }),
400
+ ]));
401
+ expect(result.graphContext.predecessorWindow).toEqual(expect.arrayContaining([
402
+ expect.objectContaining({
403
+ atomId: 'atom_bridge',
404
+ title: 'Bridge Layer',
405
+ relationKind: 'reference',
406
+ }),
407
+ ]));
408
+ expect(result.graphContext.successorWindow).toEqual(expect.arrayContaining([
409
+ expect.objectContaining({
410
+ atomId: 'atom_application',
411
+ title: 'Application Example',
412
+ relationKind: 'sequence',
413
+ }),
414
+ ]));
415
+ });
416
+ test('filters anchor-equivalent graph neighbors before reporting windows and local degree', async () => {
417
+ const atoms = [
418
+ createAtom({
419
+ id: 'atom_water_glass',
420
+ stableKey: 'water_glass',
421
+ title: 'Water Glass',
422
+ }),
423
+ createAtom({
424
+ id: 'atom_water_glass_alias',
425
+ stableKey: 'water_glass_alias',
426
+ title: 'Water Glass',
427
+ }),
428
+ createAtom({
429
+ id: 'atom_container_physics',
430
+ stableKey: 'container_physics',
431
+ title: 'Container Physics',
432
+ }),
433
+ createAtom({
434
+ id: 'atom_mathematical_basis',
435
+ stableKey: 'mathematical_basis',
436
+ title: 'Mathematical Basis',
437
+ }),
438
+ ];
439
+ const edges = [
440
+ {
441
+ id: 'edge_anchor_self',
442
+ sourceAtomId: 'atom_water_glass',
443
+ targetAtomId: 'atom_water_glass',
444
+ relationKind: 'reference',
445
+ provenance: 'fact',
446
+ confidence: 0.99,
447
+ evidenceSpanIds: [],
448
+ temporal: {
449
+ validFrom: '2026-06-17T00:00:00.000Z',
450
+ },
451
+ },
452
+ {
453
+ id: 'edge_alias_anchor',
454
+ sourceAtomId: 'atom_water_glass_alias',
455
+ targetAtomId: 'atom_water_glass',
456
+ relationKind: 'reference',
457
+ provenance: 'fact',
458
+ confidence: 0.98,
459
+ evidenceSpanIds: [],
460
+ temporal: {
461
+ validFrom: '2026-06-17T00:00:00.000Z',
462
+ },
463
+ },
464
+ {
465
+ id: 'edge_container_anchor',
466
+ sourceAtomId: 'atom_container_physics',
467
+ targetAtomId: 'atom_water_glass',
468
+ relationKind: 'prerequisite',
469
+ provenance: 'fact',
470
+ confidence: 0.92,
471
+ evidenceSpanIds: [],
472
+ temporal: {
473
+ validFrom: '2026-06-17T00:00:00.000Z',
474
+ },
475
+ },
476
+ {
477
+ id: 'edge_anchor_math',
478
+ sourceAtomId: 'atom_water_glass',
479
+ targetAtomId: 'atom_mathematical_basis',
480
+ relationKind: 'sequence',
481
+ provenance: 'fact',
482
+ confidence: 0.9,
483
+ evidenceSpanIds: [],
484
+ temporal: {
485
+ validFrom: '2026-06-17T00:00:00.000Z',
486
+ },
487
+ },
488
+ {
489
+ id: 'edge_anchor_math_duplicate',
490
+ sourceAtomId: 'atom_water_glass',
491
+ targetAtomId: 'atom_mathematical_basis',
492
+ relationKind: 'reference',
493
+ provenance: 'fact',
494
+ confidence: 0.82,
495
+ evidenceSpanIds: [],
496
+ temporal: {
497
+ validFrom: '2026-06-17T00:00:00.000Z',
498
+ },
499
+ },
500
+ ];
501
+ const store = new InMemoryOpsStore(atoms, edges);
502
+ const knowledgePoints = [
503
+ createKnowledgePoint({
504
+ atomId: 'atom_water_glass',
505
+ atomIds: ['atom_water_glass'],
506
+ documentId: 'doc_water_glass',
507
+ sourcePath: 'Knowledge_Base/waterglass/water-glass.md',
508
+ title: 'Water Glass',
509
+ summary: 'A water glass is a physical system made of a transparent container and water.',
510
+ evidenceSnippet: 'A water glass is a physical system made of a transparent container and water.',
511
+ score: 0.96,
512
+ }),
513
+ ];
514
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
515
+ message: 'what is waterglass?',
516
+ usedScope: globalScope,
517
+ knowledgePoints,
518
+ store,
519
+ budget: {
520
+ maxPredecessors: 3,
521
+ maxSuccessors: 3,
522
+ },
523
+ });
524
+ expect(result.graphContext?.predecessorWindow).toEqual([
525
+ expect.objectContaining({
526
+ atomId: 'atom_container_physics',
527
+ title: 'Container Physics',
528
+ relationKind: 'prerequisite',
529
+ }),
530
+ ]);
531
+ expect(result.graphContext?.successorWindow).toEqual([
532
+ expect.objectContaining({
533
+ atomId: 'atom_mathematical_basis',
534
+ title: 'Mathematical Basis',
535
+ relationKind: 'sequence',
536
+ }),
537
+ ]);
538
+ expect(result.graphContext?.anchorGraphProfile).toEqual(expect.objectContaining({
539
+ atomId: 'atom_water_glass',
540
+ title: 'Water Glass',
541
+ inDegree: 1,
542
+ outDegree: 1,
543
+ }));
544
+ });
545
+ test('builds graph windows from every atom grouped under the matched knowledge point', async () => {
546
+ const atoms = [
547
+ createAtom({
548
+ id: 'atom_water_glass_heading',
549
+ stableKey: 'water_glass_heading',
550
+ title: 'Water Glass',
551
+ }),
552
+ createAtom({
553
+ id: 'atom_water_glass_physics',
554
+ stableKey: 'water_glass_physics',
555
+ title: 'Water Glass Physics',
556
+ }),
557
+ createAtom({
558
+ id: 'atom_material_science',
559
+ stableKey: 'material_science',
560
+ title: 'Material Science',
561
+ }),
562
+ createAtom({
563
+ id: 'atom_thermal_model',
564
+ stableKey: 'thermal_model',
565
+ title: 'Thermal Model',
566
+ }),
567
+ ];
568
+ const edges = [
569
+ {
570
+ id: 'edge_material_to_secondary',
571
+ sourceAtomId: 'atom_material_science',
572
+ targetAtomId: 'atom_water_glass_physics',
573
+ relationKind: 'prerequisite',
574
+ provenance: 'fact',
575
+ confidence: 0.93,
576
+ evidenceSpanIds: [],
577
+ temporal: {
578
+ validFrom: '2026-06-17T00:00:00.000Z',
579
+ },
580
+ },
581
+ {
582
+ id: 'edge_secondary_to_thermal',
583
+ sourceAtomId: 'atom_water_glass_physics',
584
+ targetAtomId: 'atom_thermal_model',
585
+ relationKind: 'sequence',
586
+ provenance: 'fact',
587
+ confidence: 0.91,
588
+ evidenceSpanIds: [],
589
+ temporal: {
590
+ validFrom: '2026-06-17T00:00:00.000Z',
591
+ },
592
+ },
593
+ ];
594
+ const knowledgePoints = [
595
+ createKnowledgePoint({
596
+ atomId: 'atom_water_glass_heading',
597
+ atomIds: ['atom_water_glass_heading', 'atom_water_glass_physics'],
598
+ documentId: 'doc_water_glass',
599
+ sourcePath: 'Knowledge_Base/waterglass/water-glass.md',
600
+ title: 'Water Glass',
601
+ summary: 'A water glass is a physical system made of a transparent container and water.',
602
+ evidenceSnippet: 'A water glass is a physical system made of a transparent container and water.',
603
+ score: 0.96,
604
+ }),
605
+ ];
606
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
607
+ message: 'what is waterglass?',
608
+ usedScope: globalScope,
609
+ knowledgePoints,
610
+ store: new InMemoryOpsStore(atoms, edges),
611
+ budget: {
612
+ maxPredecessors: 3,
613
+ maxSuccessors: 3,
614
+ },
615
+ });
616
+ expect(result.graphContext?.predecessorWindow).toEqual([
617
+ expect.objectContaining({
618
+ atomId: 'atom_material_science',
619
+ title: 'Material Science',
620
+ relationKind: 'prerequisite',
621
+ }),
622
+ ]);
623
+ expect(result.graphContext?.successorWindow).toEqual([
624
+ expect.objectContaining({
625
+ atomId: 'atom_thermal_model',
626
+ title: 'Thermal Model',
627
+ relationKind: 'sequence',
628
+ }),
629
+ ]);
630
+ expect(result.graphContext?.anchorGraphProfile).toEqual(expect.objectContaining({
631
+ atomId: 'atom_water_glass_heading',
632
+ inDegree: 1,
633
+ outDegree: 1,
634
+ }));
635
+ });
636
+ test('prioritizes structural graph neighbors over bibliography-style reference successors for definition answers', async () => {
637
+ const atoms = [
638
+ createAtom({
639
+ id: 'atom_water_glass_heading',
640
+ stableKey: 'water_glass_heading',
641
+ title: 'Water Glass',
642
+ }),
643
+ createAtom({
644
+ id: 'atom_water_glass_thermal',
645
+ stableKey: 'water_glass_thermal',
646
+ title: 'Thermodynamics',
647
+ }),
648
+ createAtom({
649
+ id: 'atom_core_concepts',
650
+ stableKey: 'core_concepts',
651
+ title: 'Core Concepts and Mathematical Basis',
652
+ }),
653
+ createAtom({
654
+ id: 'atom_references',
655
+ stableKey: 'references',
656
+ title: 'References',
657
+ }),
658
+ ];
659
+ const edges = [
660
+ {
661
+ id: 'edge_thermal_references',
662
+ sourceAtomId: 'atom_water_glass_thermal',
663
+ targetAtomId: 'atom_references',
664
+ relationKind: 'reference',
665
+ provenance: 'fact',
666
+ confidence: 0.99,
667
+ evidenceSpanIds: [],
668
+ temporal: {
669
+ validFrom: '2026-06-17T00:00:00.000Z',
670
+ },
671
+ },
672
+ {
673
+ id: 'edge_heading_core_concepts',
674
+ sourceAtomId: 'atom_water_glass_heading',
675
+ targetAtomId: 'atom_core_concepts',
676
+ relationKind: 'sequence',
677
+ provenance: 'fact',
678
+ confidence: 0.71,
679
+ evidenceSpanIds: [],
680
+ temporal: {
681
+ validFrom: '2026-06-17T00:00:00.000Z',
682
+ },
683
+ },
684
+ ];
685
+ const knowledgePoints = [
686
+ createKnowledgePoint({
687
+ atomId: 'atom_water_glass_heading',
688
+ atomIds: ['atom_water_glass_heading', 'atom_water_glass_thermal'],
689
+ documentId: 'doc_water_glass',
690
+ sourcePath: 'Knowledge_Base/waterglass/water-glass.md',
691
+ title: 'Water Glass',
692
+ summary: 'A water glass is a physical system made of a transparent container and water.',
693
+ evidenceSnippet: 'A water glass is a physical system made of a transparent container and water.',
694
+ score: 0.96,
695
+ }),
696
+ ];
697
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
698
+ message: 'what is waterglass?',
699
+ usedScope: globalScope,
700
+ knowledgePoints,
701
+ store: new InMemoryOpsStore(atoms, edges),
702
+ budget: {
703
+ maxPredecessors: 3,
704
+ maxSuccessors: 1,
705
+ },
706
+ });
707
+ expect(result.graphContext?.successorWindow).toEqual([
708
+ expect.objectContaining({
709
+ atomId: 'atom_core_concepts',
710
+ title: 'Core Concepts and Mathematical Basis',
711
+ relationKind: 'sequence',
712
+ }),
713
+ ]);
714
+ expect(result.graphContext?.successorWindow).not.toEqual(expect.arrayContaining([
715
+ expect.objectContaining({
716
+ atomId: 'atom_references',
717
+ title: 'References',
718
+ }),
719
+ ]));
720
+ expect(result.graphContext?.anchorGraphProfile).toEqual(expect.objectContaining({
721
+ atomId: 'atom_water_glass_heading',
722
+ outDegree: 2,
723
+ }));
724
+ });
725
+ test.each(['compare water glass and plastic cup', '比较 water glass 和 plastic cup'])('prioritizes contrast successors over procedural sequence nodes: %s', async (message) => {
726
+ const atoms = [
727
+ createAtom({
728
+ id: 'atom_water_glass',
729
+ stableKey: 'water_glass',
730
+ title: 'Water Glass',
731
+ }),
732
+ createAtom({
733
+ id: 'atom_usage_sequence',
734
+ stableKey: 'usage_sequence',
735
+ title: 'Usage Sequence',
736
+ }),
737
+ createAtom({
738
+ id: 'atom_plastic_cup_contrast',
739
+ stableKey: 'plastic_cup_contrast',
740
+ title: 'Plastic Cup Contrast',
741
+ }),
742
+ ];
743
+ const edges = [
744
+ {
745
+ id: 'edge_water_glass_usage_sequence',
746
+ sourceAtomId: 'atom_water_glass',
747
+ targetAtomId: 'atom_usage_sequence',
748
+ relationKind: 'sequence',
749
+ provenance: 'fact',
750
+ confidence: 0.96,
751
+ evidenceSpanIds: [],
752
+ temporal: {
753
+ validFrom: '2026-07-05T00:00:00.000Z',
754
+ },
755
+ },
756
+ {
757
+ id: 'edge_water_glass_plastic_contrast',
758
+ sourceAtomId: 'atom_water_glass',
759
+ targetAtomId: 'atom_plastic_cup_contrast',
760
+ relationKind: 'contrast',
761
+ provenance: 'fact',
762
+ confidence: 0.62,
763
+ evidenceSpanIds: [],
764
+ temporal: {
765
+ validFrom: '2026-07-05T00:00:00.000Z',
766
+ },
767
+ },
768
+ ];
769
+ const knowledgePoints = [
770
+ createKnowledgePoint({
771
+ atomId: 'atom_water_glass',
772
+ atomIds: ['atom_water_glass'],
773
+ documentId: 'doc_water_glass',
774
+ sourcePath: 'Knowledge_Base/waterglass/water-glass.md',
775
+ title: 'Water Glass',
776
+ summary: 'A water glass is a transparent vessel for water.',
777
+ evidenceSnippet: 'A water glass is a transparent vessel for water.',
778
+ score: 0.96,
779
+ }),
780
+ ];
781
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
782
+ message,
783
+ usedScope: globalScope,
784
+ knowledgePoints,
785
+ store: new InMemoryOpsStore(atoms, edges),
786
+ budget: {
787
+ maxSuccessors: 1,
788
+ },
789
+ });
790
+ expect(result.graphContext?.successorWindow).toEqual([
791
+ expect.objectContaining({
792
+ atomId: 'atom_plastic_cup_contrast',
793
+ title: 'Plastic Cup Contrast',
794
+ relationKind: 'contrast',
795
+ }),
796
+ ]);
797
+ expect(result.graphContext?.successorWindow).not.toEqual(expect.arrayContaining([
798
+ expect.objectContaining({
799
+ atomId: 'atom_usage_sequence',
800
+ }),
801
+ ]));
802
+ });
803
+ test('filters intent-misaligned structural successors when compare-aligned neighbors exist', async () => {
804
+ const atoms = [
805
+ createAtom({
806
+ id: 'atom_brittle_glass',
807
+ stableKey: 'brittle_glass',
808
+ title: 'Brittle Glass Vessel',
809
+ }),
810
+ createAtom({
811
+ id: 'atom_setup_sequence',
812
+ stableKey: 'setup_sequence',
813
+ title: 'Setup Sequence',
814
+ }),
815
+ createAtom({
816
+ id: 'atom_prior_material_lesson',
817
+ stableKey: 'prior_material_lesson',
818
+ title: 'Prior Material Lesson',
819
+ }),
820
+ createAtom({
821
+ id: 'atom_polymer_contrast',
822
+ stableKey: 'polymer_contrast',
823
+ title: 'Polymer Contrast',
824
+ }),
825
+ ];
826
+ const edges = [
827
+ {
828
+ id: 'edge_brittle_setup_sequence',
829
+ sourceAtomId: 'atom_brittle_glass',
830
+ targetAtomId: 'atom_setup_sequence',
831
+ relationKind: 'sequence',
832
+ provenance: 'fact',
833
+ confidence: 0.99,
834
+ evidenceSpanIds: [],
835
+ temporal: {
836
+ validFrom: '2026-07-05T00:00:00.000Z',
837
+ },
838
+ },
839
+ {
840
+ id: 'edge_brittle_prior_lesson',
841
+ sourceAtomId: 'atom_brittle_glass',
842
+ targetAtomId: 'atom_prior_material_lesson',
843
+ relationKind: 'prerequisite',
844
+ provenance: 'fact',
845
+ confidence: 0.98,
846
+ evidenceSpanIds: [],
847
+ temporal: {
848
+ validFrom: '2026-07-05T00:00:00.000Z',
849
+ },
850
+ },
851
+ {
852
+ id: 'edge_brittle_polymer_contrast',
853
+ sourceAtomId: 'atom_brittle_glass',
854
+ targetAtomId: 'atom_polymer_contrast',
855
+ relationKind: 'contrast',
856
+ provenance: 'fact',
857
+ confidence: 0.51,
858
+ evidenceSpanIds: [],
859
+ temporal: {
860
+ validFrom: '2026-07-05T00:00:00.000Z',
861
+ },
862
+ },
863
+ ];
864
+ const knowledgePoints = [
865
+ createKnowledgePoint({
866
+ atomId: 'atom_brittle_glass',
867
+ atomIds: ['atom_brittle_glass'],
868
+ documentId: 'doc_brittle_glass',
869
+ sourcePath: 'Knowledge_Base/graphintent/brittle-glass.md',
870
+ title: 'Brittle Glass Vessel',
871
+ summary: 'Brittle glass vessel compares material behavior with polymer vessels.',
872
+ evidenceSnippet: 'Brittle glass vessel compares material behavior with polymer vessels.',
873
+ score: 0.96,
874
+ }),
875
+ ];
876
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
877
+ message: 'compare brittle glass vessel with polymer cup material behavior',
878
+ usedScope: globalScope,
879
+ knowledgePoints,
880
+ store: new InMemoryOpsStore(atoms, edges),
881
+ budget: {
882
+ maxSuccessors: 3,
883
+ },
884
+ });
885
+ expect(result.graphContext?.successorWindow).toEqual([
886
+ expect.objectContaining({
887
+ atomId: 'atom_polymer_contrast',
888
+ title: 'Polymer Contrast',
889
+ relationKind: 'contrast',
890
+ }),
891
+ ]);
892
+ expect(result.graphContext?.successorWindow).not.toEqual(expect.arrayContaining([
893
+ expect.objectContaining({
894
+ atomId: 'atom_setup_sequence',
895
+ }),
896
+ expect.objectContaining({
897
+ atomId: 'atom_prior_material_lesson',
898
+ }),
899
+ ]));
900
+ expect(result.graphContext?.diagnostics).toEqual(expect.objectContaining({
901
+ intentAlignedSuccessorCandidateCount: 1,
902
+ intentMisalignedSuccessorCandidateCount: 2,
903
+ usedIntentMisalignedSuccessorFallback: false,
904
+ }));
905
+ });
906
+ test('fails open to structural successors when compare intent has no aligned graph neighbor', async () => {
907
+ const atoms = [
908
+ createAtom({
909
+ id: 'atom_brittle_glass',
910
+ stableKey: 'brittle_glass',
911
+ title: 'Brittle Glass Vessel',
912
+ }),
913
+ createAtom({
914
+ id: 'atom_setup_sequence',
915
+ stableKey: 'setup_sequence',
916
+ title: 'Setup Sequence',
917
+ }),
918
+ ];
919
+ const edges = [
920
+ {
921
+ id: 'edge_brittle_setup_sequence',
922
+ sourceAtomId: 'atom_brittle_glass',
923
+ targetAtomId: 'atom_setup_sequence',
924
+ relationKind: 'sequence',
925
+ provenance: 'fact',
926
+ confidence: 0.99,
927
+ evidenceSpanIds: [],
928
+ temporal: {
929
+ validFrom: '2026-07-05T00:00:00.000Z',
930
+ },
931
+ },
932
+ ];
933
+ const knowledgePoints = [
934
+ createKnowledgePoint({
935
+ atomId: 'atom_brittle_glass',
936
+ atomIds: ['atom_brittle_glass'],
937
+ documentId: 'doc_brittle_glass',
938
+ sourcePath: 'Knowledge_Base/graphintent/brittle-glass.md',
939
+ title: 'Brittle Glass Vessel',
940
+ summary: 'Brittle glass vessel compares material behavior with polymer vessels.',
941
+ evidenceSnippet: 'Brittle glass vessel compares material behavior with polymer vessels.',
942
+ score: 0.96,
943
+ }),
944
+ ];
945
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
946
+ message: 'compare brittle glass vessel with polymer cup material behavior',
947
+ usedScope: globalScope,
948
+ knowledgePoints,
949
+ store: new InMemoryOpsStore(atoms, edges),
950
+ budget: {
951
+ maxSuccessors: 1,
952
+ },
953
+ });
954
+ expect(result.graphContext?.successorWindow).toEqual([
955
+ expect.objectContaining({
956
+ atomId: 'atom_setup_sequence',
957
+ relationKind: 'sequence',
958
+ }),
959
+ ]);
960
+ expect(result.graphContext?.diagnostics).toEqual(expect.objectContaining({
961
+ intentAlignedSuccessorCandidateCount: 0,
962
+ intentMisalignedSuccessorCandidateCount: 1,
963
+ usedIntentMisalignedSuccessorFallback: true,
964
+ }));
965
+ });
966
+ test('fails open to retrieval-shaped graph context when graph ops are unavailable', async () => {
967
+ const knowledgePoints = [
968
+ createKnowledgePoint({
969
+ atomId: 'atom_generic',
970
+ atomIds: ['atom_generic'],
971
+ documentId: 'doc_generic',
972
+ sourcePath: 'Knowledge_Base/notes/generic.md',
973
+ title: 'Generic Note',
974
+ summary: 'Generic note is broad and highly connected.',
975
+ evidenceSnippet: 'Generic note is broad and highly connected.',
976
+ score: 0.92,
977
+ }),
978
+ createKnowledgePoint({
979
+ atomId: 'atom_ground',
980
+ atomIds: ['atom_ground'],
981
+ documentId: 'doc_ground',
982
+ sourcePath: 'Knowledge_Base/notes/ground.md',
983
+ title: 'Ground State',
984
+ summary: 'Ground state is the target optical state.',
985
+ evidenceSnippet: 'Ground state is the target optical state.',
986
+ score: 0.84,
987
+ citation: {
988
+ citationId: 'citation_ground',
989
+ atomId: 'atom_ground',
990
+ documentId: 'doc_ground',
991
+ sourcePath: 'Knowledge_Base/notes/ground.md',
992
+ title: 'Ground State',
993
+ snippet: 'Ground state is the target optical state.',
994
+ startLine: 11,
995
+ endLine: 11,
996
+ score: 0.84,
997
+ },
998
+ citations: [
999
+ {
1000
+ citationId: 'citation_ground',
1001
+ atomId: 'atom_ground',
1002
+ documentId: 'doc_ground',
1003
+ sourcePath: 'Knowledge_Base/notes/ground.md',
1004
+ title: 'Ground State',
1005
+ snippet: 'Ground state is the target optical state.',
1006
+ startLine: 11,
1007
+ endLine: 11,
1008
+ score: 0.84,
1009
+ },
1010
+ ],
1011
+ }),
1012
+ ];
1013
+ const result = await (0, graphContextAssembler_1.assembleAgentConversationGraphContext)({
1014
+ message: 'explain ground state',
1015
+ usedScope: globalScope,
1016
+ knowledgePoints,
1017
+ store: null,
1018
+ });
1019
+ expect(result.knowledgePoints[0].title).toBe('Ground State');
1020
+ expect(result.graphContext).toEqual(expect.objectContaining({
1021
+ anchorTitle: 'Ground State',
1022
+ evidenceSourceRefs: ['Knowledge_Base/notes/ground.md:11'],
1023
+ diagnostics: expect.objectContaining({
1024
+ graphOpsAvailable: false,
1025
+ usedFallback: true,
1026
+ selectedAnchorReason: 'title_mention',
1027
+ }),
1028
+ }));
1029
+ expect(result.graphContext.connectionPaths || []).toEqual([]);
1030
+ expect(result.graphContext.predecessorWindow || []).toEqual([]);
1031
+ expect(result.graphContext.successorWindow || []).toEqual([]);
1032
+ });
1033
+ });