noteconnection 1.8.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 (195) hide show
  1. package/README.md +257 -1803
  2. package/dist/src/agent_workspace.contract.parity.test.js +105 -421
  3. package/dist/src/agent_workspace.frontend.test.js +410 -11
  4. package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
  5. package/dist/src/appimage.patchelf.test.js +113 -0
  6. package/dist/src/appimage.portability.test.js +156 -0
  7. package/dist/src/backend/FileLoader.js +18 -4
  8. package/dist/src/backend/FileLoader.test.js +125 -0
  9. package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
  10. package/dist/src/backend/GraphBuilder.js +66 -18
  11. package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
  12. package/dist/src/backend/GraphMetrics.js +0 -3
  13. package/dist/src/backend/ResourceIdentity.js +155 -0
  14. package/dist/src/backend/ResourceIdentity.test.js +113 -0
  15. package/dist/src/backend/algorithms/CycleDetection.js +0 -1
  16. package/dist/src/backend/algorithms/HybridEngine.js +0 -3
  17. package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
  18. package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
  19. package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
  20. package/dist/src/backend/build_dag.js +0 -1
  21. package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
  22. package/dist/src/capacitor.runtime.contract.test.js +11 -2
  23. package/dist/src/core/Graph.js +138 -42
  24. package/dist/src/core/Graph.test.js +74 -0
  25. package/dist/src/core/NoteConnection.js +2 -2
  26. package/dist/src/core/PathBridge.js +265 -2
  27. package/dist/src/core/ResourceReference.js +17 -0
  28. package/dist/src/desktop.godot.pack.test.js +142 -0
  29. package/dist/src/desktop.runtime.graph.test.js +66 -0
  30. package/dist/src/export/WorkspaceExportBundle.js +44 -0
  31. package/dist/src/export/WorkspaceExportBundle.test.js +61 -0
  32. package/dist/src/foundation.release.evidence.contract.test.js +127 -9
  33. package/dist/src/foundation.sqlite.runtime.contract.test.js +6 -0
  34. package/dist/src/frontend/README.md +257 -1803
  35. package/dist/src/frontend/agent_workspace.js +665 -7
  36. package/dist/src/frontend/index.html +31 -2
  37. package/dist/src/frontend/knowledge_projection_contract.js +230 -0
  38. package/dist/src/frontend/knowledge_projection_store.js +214 -0
  39. package/dist/src/frontend/libs/path_core.js +158 -42
  40. package/dist/src/frontend/locales/en.json +32 -0
  41. package/dist/src/frontend/locales/zh.json +32 -0
  42. package/dist/src/frontend/mobile_budget_runtime.js +33 -0
  43. package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
  44. package/dist/src/frontend/mobile_identity_contract.js +221 -0
  45. package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
  46. package/dist/src/frontend/path.html +6 -2
  47. package/dist/src/frontend/simulationWorker.js +1 -1
  48. package/dist/src/frontend/source_manager.js +110 -4
  49. package/dist/src/frontend/storage_provider.js +661 -71
  50. package/dist/src/frontend/styles.css +107 -13
  51. package/dist/src/frontend/workspace_panes.js +111 -7
  52. package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
  53. package/dist/src/graph.answer.operator.contract.test.js +72 -0
  54. package/dist/src/index.js +6 -2
  55. package/dist/src/index.knowledge-root.test.js +118 -0
  56. package/dist/src/indexing/IndexLifecycle.js +22 -0
  57. package/dist/src/indexing/IndexLifecycle.test.js +24 -0
  58. package/dist/src/knowledge.api.contract.test.js +4 -2
  59. package/dist/src/knowledge_projection.contract.test.js +134 -0
  60. package/dist/src/knowledge_projection_store.test.js +200 -0
  61. package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
  62. package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
  63. package/dist/src/learning/KnowledgeLearningPlatform.js +4687 -3892
  64. package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +418 -0
  65. package/dist/src/learning/KnowledgeLearningPlatform.test.js +243 -6
  66. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +25 -1
  67. package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +13 -5
  68. package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
  69. package/dist/src/learning/PublicAnswerContract.test.js +85 -0
  70. package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
  71. package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
  72. package/dist/src/learning/agentConversationExecution.js +211 -0
  73. package/dist/src/learning/agentConversationExecution.test.js +209 -0
  74. package/dist/src/learning/agentConversationSerialization.js +266 -0
  75. package/dist/src/learning/agentConversationSerialization.test.js +165 -0
  76. package/dist/src/learning/agentResponseBudget.js +179 -0
  77. package/dist/src/learning/agentResponseBudget.test.js +97 -0
  78. package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
  79. package/dist/src/learning/answerReleaseReview.js +1191 -250
  80. package/dist/src/learning/answerReleaseReview.test.js +1293 -7
  81. package/dist/src/learning/answerTaskPlan.js +473 -0
  82. package/dist/src/learning/conversationComposer.js +627 -386
  83. package/dist/src/learning/conversationComposer.test.js +1403 -0
  84. package/dist/src/learning/evidenceContextAssembler.js +312 -120
  85. package/dist/src/learning/graphAnswerCoverage.js +37 -0
  86. package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
  87. package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
  88. package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
  89. package/dist/src/learning/graphAnswerFacts.js +94 -0
  90. package/dist/src/learning/graphAnswerFacts.test.js +39 -0
  91. package/dist/src/learning/graphAnswerPlan.js +908 -0
  92. package/dist/src/learning/graphAnswerPlan.test.js +907 -0
  93. package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
  94. package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
  95. package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
  96. package/dist/src/learning/graphClaimMatcher.js +104 -0
  97. package/dist/src/learning/graphConditionedContext.js +109 -0
  98. package/dist/src/learning/graphConditionedContext.test.js +99 -0
  99. package/dist/src/learning/graphContextAssembler.js +3 -13
  100. package/dist/src/learning/graphContextAssembler.test.js +2 -2
  101. package/dist/src/learning/graphExpansionPolicy.js +22 -0
  102. package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
  103. package/dist/src/learning/identityMetadata.test.js +26 -0
  104. package/dist/src/learning/index.js +1 -0
  105. package/dist/src/learning/mobileAnswerProjection.js +104 -0
  106. package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
  107. package/dist/src/learning/queryBackend.js +34 -10
  108. package/dist/src/learning/queryBackend.test.js +21 -0
  109. package/dist/src/learning/ragContextPack.js +115 -16
  110. package/dist/src/learning/ragContextPack.test.js +151 -0
  111. package/dist/src/learning/ragEvidenceQuality.js +96 -0
  112. package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
  113. package/dist/src/learning/ragPublicText.js +67 -4
  114. package/dist/src/learning/ragPublicText.test.js +57 -0
  115. package/dist/src/learning/ragSufficiencyJudge.js +11 -1
  116. package/dist/src/learning/ragSufficiencyProviderJudge.js +16 -26
  117. package/dist/src/learning/ragSufficiencyProviderJudge.test.js +51 -0
  118. package/dist/src/learning/requestNormalization.js +106 -0
  119. package/dist/src/learning/requestNormalization.test.js +101 -0
  120. package/dist/src/learning/store.js +116 -12
  121. package/dist/src/learning/store.test.js +299 -0
  122. package/dist/src/learning/vectorAccelerationAdapter.js +22 -6
  123. package/dist/src/learning/vectorAccelerationAdapter.test.js +30 -0
  124. package/dist/src/learning/workspaceHydration.js +168 -0
  125. package/dist/src/learning/workspaceHydration.test.js +30 -0
  126. package/dist/src/license.policy.contract.test.js +9 -4
  127. package/dist/src/markdown/MarkdownGateway.js +4 -0
  128. package/dist/src/markdown/MarkdownGateway.test.js +59 -0
  129. package/dist/src/middleware/SseResponseWriter.js +122 -0
  130. package/dist/src/middleware/SseResponseWriter.test.js +54 -0
  131. package/dist/src/middleware/auth.js +28 -7
  132. package/dist/src/middleware/auth.test.js +33 -0
  133. package/dist/src/middleware/index.js +2 -1
  134. package/dist/src/mobile.android.evidence.contract.test.js +146 -0
  135. package/dist/src/mobile.android.signing.contract.test.js +66 -0
  136. package/dist/src/mobile.artifact.contract.test.js +144 -0
  137. package/dist/src/mobile.budget.contract.test.js +90 -0
  138. package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
  139. package/dist/src/mobile.graph.parity.contract.test.js +207 -0
  140. package/dist/src/mobile.identity.contract.test.js +66 -0
  141. package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
  142. package/dist/src/mobile.identity.corpus.test.js +40 -0
  143. package/dist/src/mobile.native.recovery.contract.test.js +64 -0
  144. package/dist/src/mobile.pipeline.test.js +11 -1
  145. package/dist/src/mobile.profile.contract.test.js +225 -0
  146. package/dist/src/mobile.semantic.parity.test.js +92 -0
  147. package/dist/src/mobile_exact_analyzer.test.js +113 -0
  148. package/dist/src/notemd/ContentGenerator.js +4 -9
  149. package/dist/src/notemd/FileProcessor.js +4 -9
  150. package/dist/src/notemd/NotemdService.js +12 -17
  151. package/dist/src/notemd/Translator.js +4 -9
  152. package/dist/src/notemd/progressReporter.js +9 -0
  153. package/dist/src/notemd.server.integration.test.js +119 -4
  154. package/dist/src/notemd.workflow.pipeline.test.js +1 -1
  155. package/dist/src/pathbridge.handshake.contract.test.js +29 -0
  156. package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
  157. package/dist/src/pathcore.bundle.contract.test.js +8 -0
  158. package/dist/src/platform/ExportProfile.js +28 -0
  159. package/dist/src/platform/MobileBudget.js +11 -0
  160. package/dist/src/platform/PlatformCapabilities.js +14 -0
  161. package/dist/src/platform/PlatformCapabilities.test.js +6 -0
  162. package/dist/src/query_backend.external_http.integration.test.js +2 -2
  163. package/dist/src/release.godot.mirror.contract.test.js +28 -4
  164. package/dist/src/resources/ResourceRegistry.js +40 -0
  165. package/dist/src/resources/ResourceRegistry.test.js +36 -0
  166. package/dist/src/routes/index.js +0 -4
  167. package/dist/src/routes/knowledge.js +46 -33
  168. package/dist/src/routes/knowledgePayload.js +185 -0
  169. package/dist/src/routes/knowledgePayload.test.js +53 -0
  170. package/dist/src/routes/markdown.js +8 -0
  171. package/dist/src/routes/notemd.js +990 -234
  172. package/dist/src/routes/registry.contract.test.js +5 -2
  173. package/dist/src/routes/registry.shadow.contract.test.js +22 -0
  174. package/dist/src/routes/render.js +14 -51
  175. package/dist/src/runtime.capabilities.test.js +18 -2
  176. package/dist/src/server.js +566 -1090
  177. package/dist/src/server.migration.test.js +417 -15
  178. package/dist/src/sidecar.build.lock.contract.test.js +201 -0
  179. package/dist/src/sidecar.freshness.contract.test.js +184 -0
  180. package/dist/src/sidecar.replacement.boundary.contract.test.js +6 -3
  181. package/dist/src/sidecar.supply.readiness.contract.test.js +11 -0
  182. package/dist/src/simulation.worker.offline.test.js +104 -0
  183. package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
  184. package/dist/src/storage.provider.contract.test.js +152 -1
  185. package/dist/src/tauri.frontend.build.contract.test.js +8 -0
  186. package/dist/src/tauri.window.evidence.execution.test.js +68 -0
  187. package/dist/src/utils/RuntimePaths.js +6 -0
  188. package/dist/src/utils/RuntimePaths.test.js +27 -0
  189. package/dist/src/windows.installer.build.test.js +109 -0
  190. package/dist/src/windows.installer.payload.test.js +76 -0
  191. package/dist/src/windows.installer.runtime.test.js +69 -0
  192. package/dist/src/workspace/WorkspaceRegistry.js +13 -0
  193. package/package.json +32 -10
  194. package/dist/src/routes/data.js +0 -267
  195. package/dist/src/routes/diagnostics.js +0 -51
@@ -8,10 +8,31 @@ var module = { exports: exports };
8
8
  // var Graph, PathEngine;
9
9
 
10
10
 
11
+ /* ResourceReference.js */
12
+ "use strict";
13
+
14
+ normalizeResourceReference = normalizeResourceReference;
15
+ /**
16
+ * Shared, host-neutral reference normalization used by Graph and backend
17
+ * identity generation. It intentionally has no Node or platform dependency so
18
+ * the path-core bundle can execute in a browser VM and in Godot WebView.
19
+ */
20
+ function normalizeResourceReference(reference) {
21
+ if (typeof reference !== 'string') {
22
+ throw new Error('Resource reference must be a string');
23
+ }
24
+ if (reference.includes('\0')) {
25
+ throw new Error('Resource reference must not contain NUL characters');
26
+ }
27
+ return reference.normalize('NFC').replace(/\\/g, '/').toLowerCase();
28
+ }
29
+
30
+
11
31
  /* Graph.js */
12
32
  "use strict";
13
33
 
14
34
 
35
+
15
36
  /**
16
37
  * Directed Graph implementation for managing notes and dependencies.
17
38
  * 用于管理笔记和依赖关系的有向图实现。
@@ -21,6 +42,7 @@ class Graph {
21
42
  this.nodes = new Map();
22
43
  this.adjacencyList = new Map();
23
44
  this.reverseAdjacencyList = new Map();
45
+ this.aliases = new Map();
24
46
  }
25
47
  /**
26
48
  * Adds a node to the graph.
@@ -28,11 +50,90 @@ class Graph {
28
50
  * @param node The node to add | 要添加的节点
29
51
  */
30
52
  addNode(node) {
31
- if (!this.nodes.has(node.id)) {
32
- this.nodes.set(node.id, { ...node, inDegree: 0, outDegree: 0 });
33
- this.adjacencyList.set(node.id, []);
34
- this.reverseAdjacencyList.set(node.id, []);
53
+ if (this.nodes.has(node.id)) {
54
+ return;
55
+ }
56
+ const aliases = [node.id, node.sourceUri, ...(node.identityAliases ?? [])]
57
+ .filter((alias) => typeof alias === 'string' && alias.length > 0);
58
+ const normalizedAliases = new Set(aliases.map(alias => (0, normalizeResourceReference)(alias)));
59
+ normalizedAliases.forEach(alias => {
60
+ const existingNodeId = this.aliases.get(alias);
61
+ if (existingNodeId && existingNodeId !== node.id) {
62
+ throw new Error(`Resource identity alias collision: "${alias}" is claimed by both "${existingNodeId}" and "${node.id}"`);
63
+ }
64
+ });
65
+ this.nodes.set(node.id, { ...node, inDegree: 0, outDegree: 0 });
66
+ this.adjacencyList.set(node.id, []);
67
+ this.reverseAdjacencyList.set(node.id, []);
68
+ normalizedAliases.forEach(alias => {
69
+ this.aliases.set(alias, node.id);
70
+ });
71
+ }
72
+ /**
73
+ * Rehydrates a graph from either a current or legacy JSON snapshot.
74
+ *
75
+ * The snapshot is validated before mutating the returned graph. Edges must
76
+ * reference declared nodes so a corrupt or partially-written snapshot cannot
77
+ * silently create synthetic nodes and change graph semantics during replay.
78
+ */
79
+ static fromJSON(data) {
80
+ if (!data || typeof data !== 'object' || Array.isArray(data)) {
81
+ throw new Error('Graph snapshot must be an object.');
82
+ }
83
+ const snapshot = data;
84
+ if (!Array.isArray(snapshot.nodes) || !Array.isArray(snapshot.edges)) {
85
+ throw new Error('Graph snapshot must contain nodes and edges arrays.');
35
86
  }
87
+ const graph = new Graph();
88
+ const nodeIds = new Set();
89
+ snapshot.nodes.forEach((rawNode, index) => {
90
+ if (!rawNode || typeof rawNode !== 'object' || Array.isArray(rawNode)) {
91
+ throw new Error(`Graph snapshot node at index ${index} must be an object.`);
92
+ }
93
+ const node = rawNode;
94
+ if (typeof node.id !== 'string' || node.id.trim().length === 0) {
95
+ throw new Error(`Graph snapshot node at index ${index} requires a non-empty id.`);
96
+ }
97
+ if (nodeIds.has(node.id)) {
98
+ throw new Error(`Graph snapshot contains duplicate node id: ${node.id}.`);
99
+ }
100
+ nodeIds.add(node.id);
101
+ graph.addNode({
102
+ ...node,
103
+ id: node.id,
104
+ label: typeof node.label === 'string' && node.label.length > 0 ? node.label : node.id,
105
+ inDegree: 0,
106
+ outDegree: 0,
107
+ });
108
+ });
109
+ snapshot.edges.forEach((rawEdge, index) => {
110
+ if (!rawEdge || typeof rawEdge !== 'object' || Array.isArray(rawEdge)) {
111
+ throw new Error(`Graph snapshot edge at index ${index} must be an object.`);
112
+ }
113
+ const edge = rawEdge;
114
+ if (typeof edge.source !== 'string' || typeof edge.target !== 'string') {
115
+ throw new Error(`Graph snapshot edge at index ${index} requires source and target ids.`);
116
+ }
117
+ if (!graph.hasNode(edge.source) || !graph.hasNode(edge.target)) {
118
+ throw new Error(`Graph snapshot edge at index ${index} references an undeclared node: ${edge.source} -> ${edge.target}.`);
119
+ }
120
+ graph.addEdge(edge.source, edge.target, edge.type, edge.weight);
121
+ });
122
+ return graph;
123
+ }
124
+ /** Restore this instance atomically from a legacy or current JSON snapshot. */
125
+ restore(data) {
126
+ const restored = Graph.fromJSON(data);
127
+ this.nodes = restored.nodes;
128
+ this.adjacencyList = restored.adjacencyList;
129
+ this.reverseAdjacencyList = restored.reverseAdjacencyList;
130
+ this.aliases = restored.aliases;
131
+ }
132
+ resolveNodeId(reference) {
133
+ if (this.nodes.has(reference)) {
134
+ return reference;
135
+ }
136
+ return this.aliases.get((0, normalizeResourceReference)(reference));
36
137
  }
37
138
  /**
38
139
  * Retrieves a node by its ID.
@@ -40,16 +141,17 @@ class Graph {
40
141
  * @param id The node ID | 节点 ID
41
142
  * @returns The node or undefined if not found | 节点,如果未找到则返回 undefined
42
143
  */
43
- getNode(id) {
44
- return this.nodes.get(id);
144
+ getNode(reference) {
145
+ const nodeId = this.resolveNodeId(reference);
146
+ return nodeId ? this.nodes.get(nodeId) : undefined;
45
147
  }
46
148
  /**
47
149
  * Checks if a node exists in the graph.
48
150
  * 检查图中是否存在该节点。
49
151
  * @param id The node ID | 节点 ID
50
152
  */
51
- hasNode(id) {
52
- return this.nodes.has(id);
153
+ hasNode(reference) {
154
+ return this.resolveNodeId(reference) !== undefined;
53
155
  }
54
156
  /**
55
157
  * Adds a directed edge between two nodes.
@@ -60,30 +162,32 @@ class Graph {
60
162
  * @param weight Edge weight (confidence) | 边权重 (置信度)
61
163
  */
62
164
  addEdge(source, target, type = 'dependency', weight = 1) {
63
- if (!this.nodes.has(source)) {
64
- this.addNode({ id: source, label: source, inDegree: 0, outDegree: 0 });
165
+ const sourceId = this.resolveNodeId(source) ?? source;
166
+ const targetId = this.resolveNodeId(target) ?? target;
167
+ if (!this.nodes.has(sourceId)) {
168
+ this.addNode({ id: sourceId, label: sourceId, inDegree: 0, outDegree: 0 });
65
169
  }
66
- if (!this.nodes.has(target)) {
67
- this.addNode({ id: target, label: target, inDegree: 0, outDegree: 0 });
170
+ if (!this.nodes.has(targetId)) {
171
+ this.addNode({ id: targetId, label: targetId, inDegree: 0, outDegree: 0 });
68
172
  }
69
- const edge = { source, target, type, weight };
173
+ const edge = { source: sourceId, target: targetId, type, weight };
70
174
  // Add to adjacency list (outgoing)
71
- const outgoing = this.adjacencyList.get(source) || [];
175
+ const outgoing = this.adjacencyList.get(sourceId) || [];
72
176
  // Prevent duplicate edges
73
- if (!outgoing.some(e => e.target === target && e.type === type)) {
177
+ if (!outgoing.some(e => e.target === targetId && e.type === type)) {
74
178
  outgoing.push(edge);
75
- this.adjacencyList.set(source, outgoing);
179
+ this.adjacencyList.set(sourceId, outgoing);
76
180
  // Update out-degree
77
- const sourceNode = this.nodes.get(source);
181
+ const sourceNode = this.nodes.get(sourceId);
78
182
  sourceNode.outDegree++;
79
183
  }
80
184
  // Add to reverse adjacency list (incoming)
81
- const incoming = this.reverseAdjacencyList.get(target) || [];
82
- if (!incoming.some(e => e.source === source && e.type === type)) {
185
+ const incoming = this.reverseAdjacencyList.get(targetId) || [];
186
+ if (!incoming.some(e => e.source === sourceId && e.type === type)) {
83
187
  incoming.push(edge);
84
- this.reverseAdjacencyList.set(target, incoming);
188
+ this.reverseAdjacencyList.set(targetId, incoming);
85
189
  // Update in-degree
86
- const targetNode = this.nodes.get(target);
190
+ const targetNode = this.nodes.get(targetId);
87
191
  targetNode.inDegree++;
88
192
  }
89
193
  }
@@ -92,16 +196,17 @@ class Graph {
92
196
  * 获取节点的所有出边。
93
197
  * @param id Node ID | 节点 ID
94
198
  */
95
- getOutgoingEdges(id) {
96
- return this.adjacencyList.get(id) || [];
199
+ getOutgoingEdges(reference) {
200
+ const nodeId = this.resolveNodeId(reference);
201
+ return nodeId ? (this.adjacencyList.get(nodeId) || []) : [];
97
202
  }
98
203
  /**
99
204
  * Gets all outgoing neighbor IDs for a node.
100
205
  * 获取节点的所有出度邻居 ID。
101
206
  * @param id Node ID | 节点 ID
102
207
  */
103
- getNeighbors(id) {
104
- return (this.adjacencyList.get(id) || []).map(edge => edge.target);
208
+ getNeighbors(reference) {
209
+ return this.getOutgoingEdges(reference).map(edge => edge.target);
105
210
  }
106
211
  /**
107
212
  * Gets all nodes in the graph.
@@ -122,8 +227,9 @@ class Graph {
122
227
  * 获取节点的所有入边。
123
228
  * @param id Node ID | 节点 ID
124
229
  */
125
- getIncomingEdges(id) {
126
- return this.reverseAdjacencyList.get(id) || [];
230
+ getIncomingEdges(reference) {
231
+ const nodeId = this.resolveNodeId(reference);
232
+ return nodeId ? (this.reverseAdjacencyList.get(nodeId) || []) : [];
127
233
  }
128
234
  /**
129
235
  * Returns the graph data in a serializable format.
@@ -140,11 +246,14 @@ class Graph {
140
246
  * 获取所有前驱节点(入边的传递闭包)。
141
247
  * @param id Target node ID
142
248
  */
143
- getPredecessors(id) {
249
+ getPredecessors(reference) {
144
250
  const predecessors = new Set();
145
- const queue = [id];
251
+ const nodeId = this.resolveNodeId(reference);
252
+ if (!nodeId)
253
+ return predecessors;
254
+ const queue = [nodeId];
146
255
  const visited = new Set();
147
- visited.add(id);
256
+ visited.add(nodeId);
148
257
  while (queue.length > 0) {
149
258
  const current = queue.shift();
150
259
  const incoming = this.getIncomingEdges(current);
@@ -163,11 +272,14 @@ class Graph {
163
272
  * 获取所有后继节点(出边的传递闭包)。
164
273
  * @param id Source node ID
165
274
  */
166
- getSuccessors(id) {
275
+ getSuccessors(reference) {
167
276
  const successors = new Set();
168
- const queue = [id];
277
+ const nodeId = this.resolveNodeId(reference);
278
+ if (!nodeId)
279
+ return successors;
280
+ const queue = [nodeId];
169
281
  const visited = new Set();
170
- visited.add(id);
282
+ visited.add(nodeId);
171
283
  while (queue.length > 0) {
172
284
  const current = queue.shift();
173
285
  const outgoing = this.getOutgoingEdges(current);
@@ -189,15 +301,19 @@ class Graph {
189
301
  * @returns Array of node IDs representing the path, or empty if no path found
190
302
  */
191
303
  getShortestPath(source, target) {
192
- if (source === target)
193
- return [source];
194
- const queue = [source];
304
+ const sourceId = this.resolveNodeId(source);
305
+ const targetId = this.resolveNodeId(target);
306
+ if (!sourceId || !targetId)
307
+ return [];
308
+ if (sourceId === targetId)
309
+ return [sourceId];
310
+ const queue = [sourceId];
195
311
  const visited = new Set();
196
312
  const parent = new Map();
197
- visited.add(source);
313
+ visited.add(sourceId);
198
314
  while (queue.length > 0) {
199
315
  const current = queue.shift();
200
- if (current === target)
316
+ if (current === targetId)
201
317
  break;
202
318
  const neighbors = this.getNeighbors(current);
203
319
  for (const neighbor of neighbors) {
@@ -208,12 +324,12 @@ class Graph {
208
324
  }
209
325
  }
210
326
  }
211
- if (!visited.has(target))
327
+ if (!visited.has(targetId))
212
328
  return [];
213
329
  // Reconstruct path
214
- const path = [target];
215
- let curr = target;
216
- while (curr !== source) {
330
+ const path = [targetId];
331
+ let curr = targetId;
332
+ while (curr !== sourceId) {
217
333
  curr = parent.get(curr);
218
334
  path.unshift(curr);
219
335
  }
@@ -392,6 +392,30 @@
392
392
  "subtitle": "Grounded conversation, knowledge search, and guided learning",
393
393
  "conversationTitle": "Grounded Conversation",
394
394
  "conversationSubtitle": "Scoped knowledge, citations, and guided learning actions",
395
+ "answerLanguage": {
396
+ "label": "Answer language",
397
+ "english": "English",
398
+ "chinese": "Chinese",
399
+ "summary": "Matches software language",
400
+ "summaryEnglish": "English answer",
401
+ "summaryChinese": "Chinese answer"
402
+ },
403
+ "responseMode": {
404
+ "label": "Answer detail",
405
+ "slim": "Slim",
406
+ "full": "Full report",
407
+ "summary": "Short grounded answer",
408
+ "summarySlim": "Short grounded answer",
409
+ "summaryFull": "Complete evidence-bounded technical report"
410
+ },
411
+ "responseBudget": {
412
+ "label": "Full report budget",
413
+ "adaptive": "Adaptive",
414
+ "unbounded": "No product cap",
415
+ "summary": "Host-adaptive report budget",
416
+ "summaryAdaptive": "Host-adaptive report budget",
417
+ "summaryUnbounded": "Product cap disabled; runtime safety limits remain"
418
+ },
395
419
  "userId": "Learner ID",
396
420
  "inputLabel": "Ask the scoped knowledge corpus",
397
421
  "inputPlaceholder": "Ask about a concept, citation, prerequisite, or study step...",
@@ -500,6 +524,12 @@
500
524
  "graphDiagnosticsSupportCountLabel": "Support nodes",
501
525
  "graphDiagnosticsBudgetLabel": "Path depth budget",
502
526
  "graphDiagnosticsMissingLookupsLabel": "Missing graph lookups",
527
+ "graphAnswerPlanLabel": "Graph answer plan",
528
+ "graphAnswerIntentLabel": "Intent / depth",
529
+ "graphAnswerCoverageLabel": "Required claim coverage",
530
+ "graphAnswerMissingLabel": "Missing required claims",
531
+ "graphAnswerOmissionsLabel": "Omitted graph candidates",
532
+ "graphExpansionLabel": "Bounded expansion",
503
533
  "graphTemporalValid": "valid",
504
534
  "graphTemporalWarning": "warning",
505
535
  "ragContextLabel": "RAG context",
@@ -946,6 +976,8 @@
946
976
  },
947
977
  "reply": {
948
978
  "structuredAnswer": "Grounded Answer",
979
+ "showNextActions": "Show next actions",
980
+ "hideNextActions": "Hide next actions",
949
981
  "citations": "Citations",
950
982
  "citationsEmpty": "No citations were returned.",
951
983
  "citationUntitled": "Untitled citation",
@@ -388,10 +388,34 @@
388
388
  "opt_visible": "可见节点 (默认)",
389
389
  "opt_total": "统计总数",
390
390
  "agentWorkspace": {
391
+ "responseBudget": {
392
+ "label": "\u5b8c\u6574\u62a5\u544a\u9884\u7b97",
393
+ "adaptive": "\u81ea\u9002\u5e94",
394
+ "unbounded": "\u5173\u95ed\u4ea7\u54c1\u4e0a\u9650",
395
+ "summary": "\u6309\u5bbf\u4e3b\u80fd\u529b\u81ea\u9002\u5e94\u62a5\u544a\u9884\u7b97",
396
+ "summaryAdaptive": "\u6309\u5bbf\u4e3b\u80fd\u529b\u81ea\u9002\u5e94\u62a5\u544a\u9884\u7b97",
397
+ "summaryUnbounded": "\u5df2\u5173\u95ed\u4ea7\u54c1\u4e0a\u9650\uff1b\u8fd0\u884c\u65f6\u5b89\u5168\u9600\u4ecd\u751f\u6548"
398
+ },
391
399
  "title": "知识工作区",
392
400
  "subtitle": "可信对话、知识检索与引导式学习",
393
401
  "conversationTitle": "可信对话",
394
402
  "conversationSubtitle": "限定范围的知识、引用依据与引导式学习动作",
403
+ "answerLanguage": {
404
+ "label": "回答语言",
405
+ "english": "English",
406
+ "chinese": "中文",
407
+ "summary": "跟随软件语言",
408
+ "summaryEnglish": "使用英文回答",
409
+ "summaryChinese": "使用中文回答"
410
+ },
411
+ "responseMode": {
412
+ "label": "回答详略",
413
+ "slim": "简洁",
414
+ "full": "完整报告",
415
+ "summary": "简洁的依据型回答",
416
+ "summarySlim": "简洁的依据型回答",
417
+ "summaryFull": "完整且受证据约束的技术报告"
418
+ },
395
419
  "userId": "学习者 ID",
396
420
  "inputLabel": "向当前限定知识域提问",
397
421
  "inputPlaceholder": "可以询问概念、引用依据、先修依赖或学习步骤...",
@@ -500,6 +524,12 @@
500
524
  "graphDiagnosticsSupportCountLabel": "支撑节点",
501
525
  "graphDiagnosticsBudgetLabel": "路径深度预算",
502
526
  "graphDiagnosticsMissingLookupsLabel": "缺失图查询",
527
+ "graphAnswerPlanLabel": "图回答规划",
528
+ "graphAnswerIntentLabel": "意图 / 深度",
529
+ "graphAnswerCoverageLabel": "必要主张覆盖",
530
+ "graphAnswerMissingLabel": "缺失的必要主张",
531
+ "graphAnswerOmissionsLabel": "已排除的图候选",
532
+ "graphExpansionLabel": "有界图扩展",
503
533
  "graphTemporalValid": "有效",
504
534
  "graphTemporalWarning": "告警",
505
535
  "ragContextLabel": "RAG 上下文",
@@ -946,6 +976,8 @@
946
976
  },
947
977
  "reply": {
948
978
  "structuredAnswer": "可信回答",
979
+ "showNextActions": "显示下一步行动",
980
+ "hideNextActions": "隐藏下一步行动",
949
981
  "citations": "引用",
950
982
  "citationsEmpty": "未返回引用。",
951
983
  "citationUntitled": "未命名引用",
@@ -0,0 +1,33 @@
1
+ (function attachMobileBudgetRuntime(root) {
2
+ 'use strict';
3
+
4
+ // This is the intentionally tiny browser projection of config/mobile-budget.v1.json.
5
+ // The Node/Rust contract remains the source of truth; contract tests reject drift.
6
+ if (!root || root.NoteConnectionMobileBudget) {
7
+ return;
8
+ }
9
+
10
+ root.NoteConnectionMobileBudget = Object.freeze({
11
+ schemaVersion: 1,
12
+ profiles: Object.freeze({
13
+ 'mobile-low': Object.freeze({
14
+ artifactCompressedBytes: 25 * 1024 * 1024,
15
+ maxResidentBytes: 256 * 1024 * 1024,
16
+ maxDeviceRamBytes: 4 * 1024 * 1024 * 1024
17
+ }),
18
+ 'mobile-standard': Object.freeze({
19
+ artifactCompressedBytes: 35 * 1024 * 1024,
20
+ maxResidentBytes: 384 * 1024 * 1024,
21
+ maxDeviceRamBytes: 8 * 1024 * 1024 * 1024
22
+ })
23
+ }),
24
+ runtime: Object.freeze({
25
+ maxDocuments: 5000,
26
+ maxDocumentBytes: 16 * 1024 * 1024,
27
+ maxTotalInputBytes: 64 * 1024 * 1024,
28
+ maxEdges: 250000,
29
+ maxDepth: 64,
30
+ maxProjectionBytes: 48 * 1024 * 1024
31
+ })
32
+ });
33
+ }(typeof globalThis !== 'undefined' ? globalThis : this));