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.
- package/README.md +257 -1803
- package/dist/src/agent_workspace.contract.parity.test.js +105 -421
- package/dist/src/agent_workspace.frontend.test.js +410 -11
- package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
- package/dist/src/appimage.patchelf.test.js +113 -0
- package/dist/src/appimage.portability.test.js +156 -0
- package/dist/src/backend/FileLoader.js +18 -4
- package/dist/src/backend/FileLoader.test.js +125 -0
- package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
- package/dist/src/backend/GraphBuilder.js +66 -18
- package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
- package/dist/src/backend/GraphMetrics.js +0 -3
- package/dist/src/backend/ResourceIdentity.js +155 -0
- package/dist/src/backend/ResourceIdentity.test.js +113 -0
- package/dist/src/backend/algorithms/CycleDetection.js +0 -1
- package/dist/src/backend/algorithms/HybridEngine.js +0 -3
- package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
- package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
- package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
- package/dist/src/backend/build_dag.js +0 -1
- package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
- package/dist/src/capacitor.runtime.contract.test.js +11 -2
- package/dist/src/core/Graph.js +138 -42
- package/dist/src/core/Graph.test.js +74 -0
- package/dist/src/core/NoteConnection.js +2 -2
- package/dist/src/core/PathBridge.js +265 -2
- package/dist/src/core/ResourceReference.js +17 -0
- package/dist/src/desktop.godot.pack.test.js +142 -0
- package/dist/src/desktop.runtime.graph.test.js +66 -0
- package/dist/src/export/WorkspaceExportBundle.js +44 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +61 -0
- package/dist/src/foundation.release.evidence.contract.test.js +127 -9
- package/dist/src/foundation.sqlite.runtime.contract.test.js +6 -0
- package/dist/src/frontend/README.md +257 -1803
- package/dist/src/frontend/agent_workspace.js +665 -7
- package/dist/src/frontend/index.html +31 -2
- package/dist/src/frontend/knowledge_projection_contract.js +230 -0
- package/dist/src/frontend/knowledge_projection_store.js +214 -0
- package/dist/src/frontend/libs/path_core.js +158 -42
- package/dist/src/frontend/locales/en.json +32 -0
- package/dist/src/frontend/locales/zh.json +32 -0
- package/dist/src/frontend/mobile_budget_runtime.js +33 -0
- package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
- package/dist/src/frontend/mobile_identity_contract.js +221 -0
- package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
- package/dist/src/frontend/path.html +6 -2
- package/dist/src/frontend/simulationWorker.js +1 -1
- package/dist/src/frontend/source_manager.js +110 -4
- package/dist/src/frontend/storage_provider.js +661 -71
- package/dist/src/frontend/styles.css +107 -13
- package/dist/src/frontend/workspace_panes.js +111 -7
- package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
- package/dist/src/graph.answer.operator.contract.test.js +72 -0
- package/dist/src/index.js +6 -2
- package/dist/src/index.knowledge-root.test.js +118 -0
- package/dist/src/indexing/IndexLifecycle.js +22 -0
- package/dist/src/indexing/IndexLifecycle.test.js +24 -0
- package/dist/src/knowledge.api.contract.test.js +4 -2
- package/dist/src/knowledge_projection.contract.test.js +134 -0
- package/dist/src/knowledge_projection_store.test.js +200 -0
- package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
- package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +4687 -3892
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +418 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +243 -6
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +25 -1
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +13 -5
- package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
- package/dist/src/learning/PublicAnswerContract.test.js +85 -0
- package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
- package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
- package/dist/src/learning/agentConversationExecution.js +211 -0
- package/dist/src/learning/agentConversationExecution.test.js +209 -0
- package/dist/src/learning/agentConversationSerialization.js +266 -0
- package/dist/src/learning/agentConversationSerialization.test.js +165 -0
- package/dist/src/learning/agentResponseBudget.js +179 -0
- package/dist/src/learning/agentResponseBudget.test.js +97 -0
- package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
- package/dist/src/learning/answerReleaseReview.js +1191 -250
- package/dist/src/learning/answerReleaseReview.test.js +1293 -7
- package/dist/src/learning/answerTaskPlan.js +473 -0
- package/dist/src/learning/conversationComposer.js +627 -386
- package/dist/src/learning/conversationComposer.test.js +1403 -0
- package/dist/src/learning/evidenceContextAssembler.js +312 -120
- package/dist/src/learning/graphAnswerCoverage.js +37 -0
- package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
- package/dist/src/learning/graphAnswerFacts.js +94 -0
- package/dist/src/learning/graphAnswerFacts.test.js +39 -0
- package/dist/src/learning/graphAnswerPlan.js +908 -0
- package/dist/src/learning/graphAnswerPlan.test.js +907 -0
- package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
- package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
- package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
- package/dist/src/learning/graphClaimMatcher.js +104 -0
- package/dist/src/learning/graphConditionedContext.js +109 -0
- package/dist/src/learning/graphConditionedContext.test.js +99 -0
- package/dist/src/learning/graphContextAssembler.js +3 -13
- package/dist/src/learning/graphContextAssembler.test.js +2 -2
- package/dist/src/learning/graphExpansionPolicy.js +22 -0
- package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
- package/dist/src/learning/identityMetadata.test.js +26 -0
- package/dist/src/learning/index.js +1 -0
- package/dist/src/learning/mobileAnswerProjection.js +104 -0
- package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
- package/dist/src/learning/queryBackend.js +34 -10
- package/dist/src/learning/queryBackend.test.js +21 -0
- package/dist/src/learning/ragContextPack.js +115 -16
- package/dist/src/learning/ragContextPack.test.js +151 -0
- package/dist/src/learning/ragEvidenceQuality.js +96 -0
- package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
- package/dist/src/learning/ragPublicText.js +67 -4
- package/dist/src/learning/ragPublicText.test.js +57 -0
- package/dist/src/learning/ragSufficiencyJudge.js +11 -1
- package/dist/src/learning/ragSufficiencyProviderJudge.js +16 -26
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +51 -0
- package/dist/src/learning/requestNormalization.js +106 -0
- package/dist/src/learning/requestNormalization.test.js +101 -0
- package/dist/src/learning/store.js +116 -12
- package/dist/src/learning/store.test.js +299 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +22 -6
- package/dist/src/learning/vectorAccelerationAdapter.test.js +30 -0
- package/dist/src/learning/workspaceHydration.js +168 -0
- package/dist/src/learning/workspaceHydration.test.js +30 -0
- package/dist/src/license.policy.contract.test.js +9 -4
- package/dist/src/markdown/MarkdownGateway.js +4 -0
- package/dist/src/markdown/MarkdownGateway.test.js +59 -0
- package/dist/src/middleware/SseResponseWriter.js +122 -0
- package/dist/src/middleware/SseResponseWriter.test.js +54 -0
- package/dist/src/middleware/auth.js +28 -7
- package/dist/src/middleware/auth.test.js +33 -0
- package/dist/src/middleware/index.js +2 -1
- package/dist/src/mobile.android.evidence.contract.test.js +146 -0
- package/dist/src/mobile.android.signing.contract.test.js +66 -0
- package/dist/src/mobile.artifact.contract.test.js +144 -0
- package/dist/src/mobile.budget.contract.test.js +90 -0
- package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
- package/dist/src/mobile.graph.parity.contract.test.js +207 -0
- package/dist/src/mobile.identity.contract.test.js +66 -0
- package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
- package/dist/src/mobile.identity.corpus.test.js +40 -0
- package/dist/src/mobile.native.recovery.contract.test.js +64 -0
- package/dist/src/mobile.pipeline.test.js +11 -1
- package/dist/src/mobile.profile.contract.test.js +225 -0
- package/dist/src/mobile.semantic.parity.test.js +92 -0
- package/dist/src/mobile_exact_analyzer.test.js +113 -0
- package/dist/src/notemd/ContentGenerator.js +4 -9
- package/dist/src/notemd/FileProcessor.js +4 -9
- package/dist/src/notemd/NotemdService.js +12 -17
- package/dist/src/notemd/Translator.js +4 -9
- package/dist/src/notemd/progressReporter.js +9 -0
- package/dist/src/notemd.server.integration.test.js +119 -4
- package/dist/src/notemd.workflow.pipeline.test.js +1 -1
- package/dist/src/pathbridge.handshake.contract.test.js +29 -0
- package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
- package/dist/src/pathcore.bundle.contract.test.js +8 -0
- package/dist/src/platform/ExportProfile.js +28 -0
- package/dist/src/platform/MobileBudget.js +11 -0
- package/dist/src/platform/PlatformCapabilities.js +14 -0
- package/dist/src/platform/PlatformCapabilities.test.js +6 -0
- package/dist/src/query_backend.external_http.integration.test.js +2 -2
- package/dist/src/release.godot.mirror.contract.test.js +28 -4
- package/dist/src/resources/ResourceRegistry.js +40 -0
- package/dist/src/resources/ResourceRegistry.test.js +36 -0
- package/dist/src/routes/index.js +0 -4
- package/dist/src/routes/knowledge.js +46 -33
- package/dist/src/routes/knowledgePayload.js +185 -0
- package/dist/src/routes/knowledgePayload.test.js +53 -0
- package/dist/src/routes/markdown.js +8 -0
- package/dist/src/routes/notemd.js +990 -234
- package/dist/src/routes/registry.contract.test.js +5 -2
- package/dist/src/routes/registry.shadow.contract.test.js +22 -0
- package/dist/src/routes/render.js +14 -51
- package/dist/src/runtime.capabilities.test.js +18 -2
- package/dist/src/server.js +566 -1090
- package/dist/src/server.migration.test.js +417 -15
- package/dist/src/sidecar.build.lock.contract.test.js +201 -0
- package/dist/src/sidecar.freshness.contract.test.js +184 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +6 -3
- package/dist/src/sidecar.supply.readiness.contract.test.js +11 -0
- package/dist/src/simulation.worker.offline.test.js +104 -0
- package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
- package/dist/src/storage.provider.contract.test.js +152 -1
- package/dist/src/tauri.frontend.build.contract.test.js +8 -0
- package/dist/src/tauri.window.evidence.execution.test.js +68 -0
- package/dist/src/utils/RuntimePaths.js +6 -0
- package/dist/src/utils/RuntimePaths.test.js +27 -0
- package/dist/src/windows.installer.build.test.js +109 -0
- package/dist/src/windows.installer.payload.test.js +76 -0
- package/dist/src/windows.installer.runtime.test.js +69 -0
- package/dist/src/workspace/WorkspaceRegistry.js +13 -0
- package/package.json +32 -10
- package/dist/src/routes/data.js +0 -267
- package/dist/src/routes/diagnostics.js +0 -51
|
@@ -44,6 +44,70 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
44
44
|
nowIso = '2026-03-31T08:00:00.000Z';
|
|
45
45
|
platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform(() => new Date(nowIso));
|
|
46
46
|
});
|
|
47
|
+
test('resolves adaptive full budgets from validated host capability and projects mobile to slim', async () => {
|
|
48
|
+
const extendedPlatform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({
|
|
49
|
+
nowProvider: () => new Date(nowIso),
|
|
50
|
+
autoPersist: false,
|
|
51
|
+
responseBudgetCapability: { memoryClass: 'high', workload: 'large' },
|
|
52
|
+
});
|
|
53
|
+
await extendedPlatform.ingestKnowledge({
|
|
54
|
+
incremental: true,
|
|
55
|
+
documents: [{
|
|
56
|
+
documentId: 'doc_adaptive_budget_probe',
|
|
57
|
+
sourcePath: 'Knowledge_Base/adaptive/budget-probe.md',
|
|
58
|
+
workspaceId: 'adaptive',
|
|
59
|
+
corpusId: 'adaptive',
|
|
60
|
+
language: 'en',
|
|
61
|
+
content: '# Adaptive Budget Probe\n\nA bounded report budget should select the extended tier for a large high-memory host.',
|
|
62
|
+
}],
|
|
63
|
+
});
|
|
64
|
+
const extendedResponse = await extendedPlatform.agentConversation({
|
|
65
|
+
userId: 'adaptive-budget-user',
|
|
66
|
+
sessionId: 'adaptive-budget-extended',
|
|
67
|
+
message: 'what is adaptive budget probe?',
|
|
68
|
+
responseMode: 'full',
|
|
69
|
+
persistMemory: false,
|
|
70
|
+
scope: {
|
|
71
|
+
workspaceId: 'adaptive',
|
|
72
|
+
corpusId: 'adaptive',
|
|
73
|
+
sourcePathPrefixes: ['Knowledge_Base/adaptive'],
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
expect(extendedResponse.responseBudget?.tier).toBe('extended');
|
|
77
|
+
expect(extendedResponse.trace.responseBudget?.rag?.maxFragments).toBe(160);
|
|
78
|
+
expect(extendedResponse.summary.responseBudgetTier).toBe('extended');
|
|
79
|
+
const maxPlatform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({
|
|
80
|
+
nowProvider: () => new Date(nowIso),
|
|
81
|
+
autoPersist: false,
|
|
82
|
+
responseBudgetCapability: { memoryClass: 'high', workload: 'max' },
|
|
83
|
+
});
|
|
84
|
+
const maxResponse = await maxPlatform.agentConversation({
|
|
85
|
+
userId: 'adaptive-budget-user',
|
|
86
|
+
sessionId: 'adaptive-budget-max',
|
|
87
|
+
message: 'what is adaptive budget probe?',
|
|
88
|
+
responseMode: 'full',
|
|
89
|
+
persistMemory: false,
|
|
90
|
+
});
|
|
91
|
+
expect(maxResponse.responseBudget?.tier).toBe('max');
|
|
92
|
+
expect(maxResponse.responseBudget?.reportMaxChars).toBe(160000);
|
|
93
|
+
const mobileResponse = await extendedPlatform.agentConversation({
|
|
94
|
+
userId: 'adaptive-budget-user',
|
|
95
|
+
sessionId: 'adaptive-budget-mobile',
|
|
96
|
+
message: 'what is adaptive budget probe?',
|
|
97
|
+
responseMode: 'full',
|
|
98
|
+
responseBudgetMode: 'unbounded',
|
|
99
|
+
responseProfile: 'mobile_compact',
|
|
100
|
+
persistMemory: false,
|
|
101
|
+
scope: {
|
|
102
|
+
workspaceId: 'adaptive',
|
|
103
|
+
corpusId: 'adaptive',
|
|
104
|
+
sourcePathPrefixes: ['Knowledge_Base/adaptive'],
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
expect(mobileResponse.responseMode).toBe('slim');
|
|
108
|
+
expect(mobileResponse.responseBudget?.tier).toBe('standard');
|
|
109
|
+
expect(mobileResponse.responseBudget?.productCapDisabled).toBe(false);
|
|
110
|
+
});
|
|
47
111
|
test('ingest supports staleness detection and temporal supersede edges', async () => {
|
|
48
112
|
const firstIngest = await platform.ingestKnowledge({
|
|
49
113
|
incremental: true,
|
|
@@ -279,6 +343,104 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
279
343
|
expect(queryResult.trace.latencyMs).toBeGreaterThanOrEqual(0);
|
|
280
344
|
expect(queryResult.trace.evidenceCoverageRatio).toBeGreaterThan(0);
|
|
281
345
|
});
|
|
346
|
+
test('workspace inspection exposes an additive source inventory for hydration reconciliation', async () => {
|
|
347
|
+
await platform.ingestKnowledge({
|
|
348
|
+
incremental: true,
|
|
349
|
+
documents: [
|
|
350
|
+
{
|
|
351
|
+
documentId: 'doc_inventory_a',
|
|
352
|
+
sourcePath: 'Knowledge_Base/waterglass/water-glass.md',
|
|
353
|
+
language: 'en',
|
|
354
|
+
content: '# Water Glass\nA scoped source.',
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
documentId: 'doc_inventory_b',
|
|
358
|
+
sourcePath: 'Knowledge_Base/waterglass/Amorphous ice.md',
|
|
359
|
+
language: 'zh',
|
|
360
|
+
content: '## 非晶冰\nAmorphous ice is an amorphous solid water phase.',
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
});
|
|
364
|
+
const inspection = await platform.inspectKnowledgeWorkspaceRequest({
|
|
365
|
+
query: '非晶冰',
|
|
366
|
+
scope: {
|
|
367
|
+
sourcePathPrefixes: ['Knowledge_Base/waterglass'],
|
|
368
|
+
},
|
|
369
|
+
includeSourceInventory: true,
|
|
370
|
+
});
|
|
371
|
+
expect(inspection.sourceInventory).toEqual(expect.objectContaining({
|
|
372
|
+
documentCount: 2,
|
|
373
|
+
sourcePaths: expect.arrayContaining([
|
|
374
|
+
'Knowledge_Base/waterglass/water-glass.md',
|
|
375
|
+
'Knowledge_Base/waterglass/Amorphous ice.md',
|
|
376
|
+
]),
|
|
377
|
+
}));
|
|
378
|
+
});
|
|
379
|
+
test('query planner resolves a Chinese section title inside an English-named source document', async () => {
|
|
380
|
+
await platform.ingestKnowledge({
|
|
381
|
+
incremental: true,
|
|
382
|
+
documents: [{
|
|
383
|
+
documentId: 'doc_amorphous_ice',
|
|
384
|
+
sourcePath: 'Knowledge_Base/waterglass/Amorphous ice.md',
|
|
385
|
+
language: 'zh',
|
|
386
|
+
content: [
|
|
387
|
+
'## 非晶冰',
|
|
388
|
+
'非晶冰(Amorphous ice)是水的一种固态形式。',
|
|
389
|
+
'',
|
|
390
|
+
'### 核心概念与数学基础',
|
|
391
|
+
'其结构可用 $g(r)$ 描述。',
|
|
392
|
+
].join('\n'),
|
|
393
|
+
}],
|
|
394
|
+
});
|
|
395
|
+
const queryResult = await platform.queryKnowledge({
|
|
396
|
+
query: '什么是非晶冰?我应该通过哪些知识点学习?',
|
|
397
|
+
topK: 4,
|
|
398
|
+
scope: {
|
|
399
|
+
sourcePathPrefixes: ['Knowledge_Base/waterglass'],
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
expect(queryResult.trace.planner?.titleHitDocumentIds).toContain('doc_amorphous_ice');
|
|
403
|
+
expect(queryResult.items[0]?.atom.title).toBe('非晶冰');
|
|
404
|
+
});
|
|
405
|
+
test('compound agent conversation releases a complete subject definition with math markup', async () => {
|
|
406
|
+
const content = [
|
|
407
|
+
'## 非晶冰',
|
|
408
|
+
'非晶冰(Amorphous ice)是水的一种固态形式,其分子排列缺乏长程有序结构。',
|
|
409
|
+
'',
|
|
410
|
+
'### 核心概念与数学基础',
|
|
411
|
+
'其结构可用径向分布函数 $g(r)$ 描述。',
|
|
412
|
+
'',
|
|
413
|
+
'对于由 N 个粒子组成的系统:',
|
|
414
|
+
'$$ g(r) = \\frac{V}{N^2} \\left\\langle \\sum_{i=1}^{N} \\sum_{j \\ne i}^{N} \\delta(\\mathbf{r} - (\\mathbf{r}_i - \\mathbf{r}_j)) \\right\\rangle $$',
|
|
415
|
+
].join('\n');
|
|
416
|
+
await platform.ingestKnowledge({
|
|
417
|
+
incremental: true,
|
|
418
|
+
documents: [{
|
|
419
|
+
documentId: 'doc_compound_amorphous_ice',
|
|
420
|
+
sourcePath: 'Knowledge_Base/waterglass/Amorphous ice.md',
|
|
421
|
+
language: 'zh',
|
|
422
|
+
content,
|
|
423
|
+
}],
|
|
424
|
+
});
|
|
425
|
+
const response = await platform.agentConversation({
|
|
426
|
+
userId: 'compound_answer_user',
|
|
427
|
+
sessionId: 'compound_answer_session',
|
|
428
|
+
message: '什么是非晶冰?我应该通过哪些知识点学习?',
|
|
429
|
+
answerLanguage: 'zh',
|
|
430
|
+
topK: 8,
|
|
431
|
+
persistMemory: false,
|
|
432
|
+
scope: {
|
|
433
|
+
sourcePathPrefixes: ['Knowledge_Base/waterglass'],
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
expect(response.answer).toContain('非晶冰(Amorphous ice)是水的一种固态形式');
|
|
437
|
+
expect(response.answer).toContain('$g(r)$');
|
|
438
|
+
expect(response.answer).toContain('$$');
|
|
439
|
+
expect(response.answer).not.toMatch(/###\s+(?!建议学习路径)/u);
|
|
440
|
+
expect(response.answer).not.toContain('标');
|
|
441
|
+
expect(response.answer).not.toContain('水杯');
|
|
442
|
+
expect(response.answerReleaseReview?.decision).not.toBe('abstain');
|
|
443
|
+
});
|
|
282
444
|
test('query temporal validity preserves supersession edge details after document updates', async () => {
|
|
283
445
|
await platform.ingestKnowledge({
|
|
284
446
|
incremental: true,
|
|
@@ -1580,22 +1742,22 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
1580
1742
|
}));
|
|
1581
1743
|
expect(structuredBlock && 'overviewMarkdown' in structuredBlock
|
|
1582
1744
|
? String(structuredBlock.overviewMarkdown || '')
|
|
1583
|
-
: '').toContain('##
|
|
1745
|
+
: '').toContain('## 回答上下文');
|
|
1584
1746
|
expect(structuredBlock && 'explanationMarkdown' in structuredBlock
|
|
1585
1747
|
? String(structuredBlock.explanationMarkdown || '')
|
|
1586
|
-
: '').toContain('##
|
|
1748
|
+
: '').toContain('## 说明');
|
|
1587
1749
|
expect(structuredBlock && 'evidenceMarkdown' in structuredBlock
|
|
1588
1750
|
? String(structuredBlock.evidenceMarkdown || '')
|
|
1589
|
-
: '').toContain('##
|
|
1751
|
+
: '').toContain('## 证据摘要');
|
|
1590
1752
|
expect(structuredBlock && 'explanationMarkdown' in structuredBlock
|
|
1591
1753
|
? String(structuredBlock.explanationMarkdown || '')
|
|
1592
|
-
: '').toContain('
|
|
1754
|
+
: '').toContain('最佳范围锚点');
|
|
1593
1755
|
expect(structuredBlock && 'nextActionsMarkdown' in structuredBlock
|
|
1594
1756
|
? String(structuredBlock.nextActionsMarkdown || '')
|
|
1595
|
-
: '').toContain('##
|
|
1757
|
+
: '').toContain('## 下一步行动');
|
|
1596
1758
|
expect(structuredBlock && 'nextActionsMarkdown' in structuredBlock
|
|
1597
1759
|
? String(structuredBlock.nextActionsMarkdown || '')
|
|
1598
|
-
: '').toContain('
|
|
1760
|
+
: '').toContain('记录本回合的用户关注点');
|
|
1599
1761
|
expect(response.trace.usedScope.corpusId).toBe('optics');
|
|
1600
1762
|
expect(response.summary.appliedMemoryCount).toBeGreaterThan(0);
|
|
1601
1763
|
const persistedMemory = await platform.searchConversationMemory({
|
|
@@ -1644,10 +1806,36 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
1644
1806
|
persistMemory: false,
|
|
1645
1807
|
});
|
|
1646
1808
|
expect(response.answer).toMatch(/^A water glass is/i);
|
|
1809
|
+
expect(response.answer).toContain('soda-lime glass');
|
|
1810
|
+
expect(response.answer).toContain('conduction and convection');
|
|
1647
1811
|
expect(response.answer).not.toContain('The strongest scoped match is');
|
|
1648
1812
|
expect(response.knowledgePoints).toHaveLength(1);
|
|
1649
1813
|
expect(response.summary.returnedKnowledgePoints).toBe(1);
|
|
1650
1814
|
expect(response.citations.length).toBeGreaterThanOrEqual(2);
|
|
1815
|
+
expect(response.graphAnswerPlan).toEqual(expect.objectContaining({
|
|
1816
|
+
intent: 'definition',
|
|
1817
|
+
anchorAtomId: expect.any(String),
|
|
1818
|
+
}));
|
|
1819
|
+
expect(response.graphAnswerPlan?.requiredRoles).toEqual(expect.arrayContaining([
|
|
1820
|
+
'definition',
|
|
1821
|
+
'boundary',
|
|
1822
|
+
'mechanism',
|
|
1823
|
+
]));
|
|
1824
|
+
expect(response.graphAnswerCoverage).toEqual(expect.objectContaining({
|
|
1825
|
+
passed: true,
|
|
1826
|
+
missingRequiredClaimIds: [],
|
|
1827
|
+
coverageScore: 1,
|
|
1828
|
+
}));
|
|
1829
|
+
expect(response.graphAnswerPlan).toEqual(response.answerReleaseReview?.publicGraphAnswerPlan);
|
|
1830
|
+
expect(response.graphAnswerCoverage).toEqual(response.answerReleaseReview?.graphAnswerCoverage);
|
|
1831
|
+
expect(response.knowledgeRun?.graphAnswerPlan).toEqual(response.graphAnswerPlan);
|
|
1832
|
+
expect(response.knowledgeRun?.graphAnswerCoverage).toEqual(response.graphAnswerCoverage);
|
|
1833
|
+
expect(response.trace.graphAnswerPlan).toEqual(response.graphAnswerPlan);
|
|
1834
|
+
expect(response.trace.graphAnswerCoverage).toEqual(response.graphAnswerCoverage);
|
|
1835
|
+
expect(response.trace.ragContextPack?.graphConditioning).toEqual(expect.objectContaining({
|
|
1836
|
+
strategy: 'graph_answer_plan',
|
|
1837
|
+
matchedClaimCount: expect.any(Number),
|
|
1838
|
+
}));
|
|
1651
1839
|
const groupedPoint = response.knowledgePoints[0];
|
|
1652
1840
|
expect(groupedPoint.title).toBe('Water Glass');
|
|
1653
1841
|
expect(groupedPoint.documentId).toBe('doc_water_glass_grouped');
|
|
@@ -1657,6 +1845,35 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
1657
1845
|
expect(groupedPoint.citations.length).toBeGreaterThanOrEqual(2);
|
|
1658
1846
|
expect(new Set(groupedPoint.citations.map((citation) => citation.documentId))).toEqual(new Set(['doc_water_glass_grouped']));
|
|
1659
1847
|
});
|
|
1848
|
+
test('agent conversation fails closed when a semantically adjacent document is not the requested subject', async () => {
|
|
1849
|
+
await platform.ingestKnowledge({
|
|
1850
|
+
incremental: true,
|
|
1851
|
+
documents: [
|
|
1852
|
+
{
|
|
1853
|
+
documentId: 'doc_water_glass_adjacent',
|
|
1854
|
+
sourcePath: 'Knowledge_Base/waterglass/water glass.md',
|
|
1855
|
+
language: 'zh',
|
|
1856
|
+
content: [
|
|
1857
|
+
'# 水杯 (water glass)',
|
|
1858
|
+
'水杯是由透明非晶态玻璃和水组成的容器。',
|
|
1859
|
+
'玻璃的非晶态结构影响其光学与热学性质。',
|
|
1860
|
+
].join('\n'),
|
|
1861
|
+
},
|
|
1862
|
+
],
|
|
1863
|
+
});
|
|
1864
|
+
const response = await platform.agentConversation({
|
|
1865
|
+
userId: 'agent_subject_drift_user',
|
|
1866
|
+
sessionId: 'session_subject_drift',
|
|
1867
|
+
message: '什么是非晶冰?我应该通过哪些知识点学习?',
|
|
1868
|
+
topK: 8,
|
|
1869
|
+
persistMemory: false,
|
|
1870
|
+
});
|
|
1871
|
+
expect(response.answer).toContain('非晶冰');
|
|
1872
|
+
expect(response.answer).not.toContain('水杯是由透明非晶态玻璃和水组成的容器');
|
|
1873
|
+
expect(response.answerReleaseReview?.decision).toBe('abstain');
|
|
1874
|
+
expect(response.answerReleaseReview?.failedGateIds).toContain('query_subject_alignment');
|
|
1875
|
+
expect(response.answerReleaseReview?.publicGraphAnswerPlan?.claims || []).toHaveLength(0);
|
|
1876
|
+
});
|
|
1660
1877
|
test('agent conversation recovers a title-like knowledge point when the active scope misses another corpus', async () => {
|
|
1661
1878
|
await platform.ingestKnowledge({
|
|
1662
1879
|
incremental: true,
|
|
@@ -1827,6 +2044,8 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
1827
2044
|
usedFallback: true,
|
|
1828
2045
|
}),
|
|
1829
2046
|
}));
|
|
2047
|
+
expect(knowledgeRunArtifact?.payload?.graphAnswerPlan).toEqual(knowledgeRunArtifact?.payload?.answerReleaseReview?.publicGraphAnswerPlan);
|
|
2048
|
+
expect(knowledgeRunArtifact?.payload?.graphAnswerCoverage).toEqual(knowledgeRunArtifact?.payload?.answerReleaseReview?.graphAnswerCoverage);
|
|
1830
2049
|
const reviewCards = (flashcardArtifact?.payload || {}).reviewCards || [];
|
|
1831
2050
|
expect(reviewCards).toHaveLength(1);
|
|
1832
2051
|
const followUp = await platform.executeWorkflowArtifactReviewFollowUp({
|
|
@@ -2323,6 +2542,24 @@ describe('KnowledgeLearningPlatform', () => {
|
|
|
2323
2542
|
});
|
|
2324
2543
|
expect(causalResponse.trace.ragContextPack?.sourceBoundary).toBe('full_document');
|
|
2325
2544
|
expect(deepResponse.trace.ragContextPack?.sourceBoundary).toBe('full_document');
|
|
2545
|
+
expect(baseResponse.trace.graphExpansion).toEqual({
|
|
2546
|
+
enabled: false,
|
|
2547
|
+
reason: 'ordinary_query',
|
|
2548
|
+
maxSteps: 0,
|
|
2549
|
+
executedSteps: 0,
|
|
2550
|
+
maxNeighbors: 6,
|
|
2551
|
+
selectedNeighborCount: 0,
|
|
2552
|
+
maxPathDepth: 6,
|
|
2553
|
+
});
|
|
2554
|
+
expect(deepResponse.trace.graphExpansion).toEqual(expect.objectContaining({
|
|
2555
|
+
enabled: true,
|
|
2556
|
+
reason: 'explicit_depth_request',
|
|
2557
|
+
maxSteps: 1,
|
|
2558
|
+
maxNeighbors: 8,
|
|
2559
|
+
maxPathDepth: 8,
|
|
2560
|
+
}));
|
|
2561
|
+
expect(deepResponse.trace.graphExpansion?.executedSteps).toBeLessThanOrEqual(1);
|
|
2562
|
+
expect(deepResponse.trace.graphExpansion?.selectedNeighborCount).toBeLessThanOrEqual(8);
|
|
2326
2563
|
});
|
|
2327
2564
|
test('agent conversation uses optional LLM sufficiency judge for borderline legacy source windows', async () => {
|
|
2328
2565
|
const savedAt = '2026-07-05T00:00:00.000Z';
|
|
@@ -33,6 +33,7 @@ exports.KNOWLEDGE_WORKSPACE_CONVERSATION_REGRESSION_CASES = freezeRegressionCase
|
|
|
33
33
|
preloadTargets: ['waterglass'],
|
|
34
34
|
activeTarget: 'waterglass',
|
|
35
35
|
query: '什么是waterglass?',
|
|
36
|
+
answerLanguage: 'zh',
|
|
36
37
|
expected: {
|
|
37
38
|
minCitations: 1,
|
|
38
39
|
scopeSource: 'explicit_request',
|
|
@@ -52,10 +53,21 @@ exports.KNOWLEDGE_WORKSPACE_CONVERSATION_REGRESSION_CASES = freezeRegressionCase
|
|
|
52
53
|
'遵从您的要求',
|
|
53
54
|
'all reasoning',
|
|
54
55
|
'final output',
|
|
56
|
+
'下表列出了',
|
|
57
|
+
'参数 (Parameter)',
|
|
58
|
+
':---',
|
|
59
|
+
'PET Plastic Cup',
|
|
60
|
+
'Metal Cup',
|
|
61
|
+
'Context pa',
|
|
62
|
+
'Comparison of Fluid Containment Technologies',
|
|
63
|
+
'subsequent branch',
|
|
64
|
+
'核心概念及其数学基础',
|
|
55
65
|
],
|
|
56
66
|
ragSourceBoundary: 'full_document',
|
|
57
67
|
requiredRagRoles: ['direct_support', 'parent_context', 'graph_neighbor_support'],
|
|
58
68
|
acceptedRagSufficiencyStatuses: ['sufficient', 'borderline'],
|
|
69
|
+
requireCompleteGraphAnswerCoverage: true,
|
|
70
|
+
requireGraphAnswerPlanOrder: true,
|
|
59
71
|
},
|
|
60
72
|
},
|
|
61
73
|
{
|
|
@@ -64,6 +76,7 @@ exports.KNOWLEDGE_WORKSPACE_CONVERSATION_REGRESSION_CASES = freezeRegressionCase
|
|
|
64
76
|
preloadTargets: ['waterglass'],
|
|
65
77
|
activeTarget: 'waterglass',
|
|
66
78
|
query: '什么是water glass',
|
|
79
|
+
answerLanguage: 'zh',
|
|
67
80
|
expected: {
|
|
68
81
|
minCitations: 1,
|
|
69
82
|
scopeSource: 'explicit_request',
|
|
@@ -83,10 +96,16 @@ exports.KNOWLEDGE_WORKSPACE_CONVERSATION_REGRESSION_CASES = freezeRegressionCase
|
|
|
83
96
|
'遵从您的要求',
|
|
84
97
|
'all reasoning',
|
|
85
98
|
'final output',
|
|
99
|
+
'下表列出了',
|
|
100
|
+
'参数 (Parameter)',
|
|
101
|
+
':---',
|
|
102
|
+
'核心概念及其数学基础',
|
|
86
103
|
],
|
|
87
104
|
ragSourceBoundary: 'full_document',
|
|
88
105
|
requiredRagRoles: ['direct_support', 'parent_context', 'graph_neighbor_support'],
|
|
89
106
|
acceptedRagSufficiencyStatuses: ['sufficient', 'borderline'],
|
|
107
|
+
requireCompleteGraphAnswerCoverage: true,
|
|
108
|
+
requireGraphAnswerPlanOrder: true,
|
|
90
109
|
},
|
|
91
110
|
},
|
|
92
111
|
{
|
|
@@ -101,15 +120,20 @@ exports.KNOWLEDGE_WORKSPACE_CONVERSATION_REGRESSION_CASES = freezeRegressionCase
|
|
|
101
120
|
acceptedAnswerReleaseDecisions: ['release', 'revise'],
|
|
102
121
|
plannerTitleLikeQueries: ['water glass', 'plastic cup'],
|
|
103
122
|
primarySourcePath: 'Knowledge_Base/waterglass/water glass.md',
|
|
104
|
-
|
|
123
|
+
answerMustCoverConcepts: ['glass_material', 'plastic'],
|
|
105
124
|
answerMustNotContain: [
|
|
106
125
|
'No scoped knowledge points matched',
|
|
107
126
|
'retrieval_candidates_below_threshold',
|
|
127
|
+
'消色差透镜',
|
|
128
|
+
'数学优化',
|
|
108
129
|
],
|
|
109
130
|
ragSourceBoundary: 'full_document',
|
|
110
131
|
requiredRagRoles: ['direct_support', 'parent_context', 'graph_neighbor_support'],
|
|
111
132
|
acceptedRagSufficiencyStatuses: ['sufficient', 'borderline'],
|
|
112
133
|
requireScopedDocumentIds: false,
|
|
134
|
+
requireCompleteGraphAnswerCoverage: true,
|
|
135
|
+
requireGraphAnswerPlanOrder: true,
|
|
136
|
+
requiredGraphAnswerRoles: ['contrast'],
|
|
113
137
|
},
|
|
114
138
|
},
|
|
115
139
|
{
|
|
@@ -44,6 +44,7 @@ function deriveScopedConversationRequest(caseEntry) {
|
|
|
44
44
|
userId: `regression_user_${caseEntry.id}`,
|
|
45
45
|
sessionId: `regression_session_${caseEntry.id}`,
|
|
46
46
|
message: caseEntry.query,
|
|
47
|
+
answerLanguage: caseEntry.answerLanguage || 'auto',
|
|
47
48
|
persistMemory: false,
|
|
48
49
|
topK: Number.isInteger(caseEntry.topK) && Number(caseEntry.topK) > 0
|
|
49
50
|
? Number(caseEntry.topK)
|
|
@@ -2681,11 +2682,8 @@ describe('KnowledgeWorkspaceConversationRegression', () => {
|
|
|
2681
2682
|
});
|
|
2682
2683
|
test('registers waterglass RAG claim-gate and preamble-leak runtime acceptance', () => {
|
|
2683
2684
|
const expectedWaterglassReleaseAcceptance = expect.objectContaining({
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
'query_intent_alignment',
|
|
2687
|
-
'rag_claim_citation_support',
|
|
2688
|
-
]),
|
|
2685
|
+
requireCompleteGraphAnswerCoverage: true,
|
|
2686
|
+
requireGraphAnswerPlanOrder: true,
|
|
2689
2687
|
answerMustNotContain: expect.arrayContaining([
|
|
2690
2688
|
'所有推理过程',
|
|
2691
2689
|
'最终输出',
|
|
@@ -3813,6 +3811,16 @@ describe('KnowledgeWorkspaceConversationRegression', () => {
|
|
|
3813
3811
|
expected.answerMustNotContain?.forEach((fragment) => {
|
|
3814
3812
|
expect(response.answer).not.toContain(fragment);
|
|
3815
3813
|
});
|
|
3814
|
+
if (caseEntry.id.startsWith('waterglass_explicit_scope_')) {
|
|
3815
|
+
const publicAnswer = String(response.answer || '');
|
|
3816
|
+
expect(publicAnswer).not.toMatch(/(?:Plastic Cup|Metal Cup|Comparison of Fluid Containment|Context pa|紧邻前置节点包括|后续分支包括)/iu);
|
|
3817
|
+
expect(publicAnswer).not.toMatch(/\.\.\.$|(?:and|or|with|between|from|to|is|are|以及|并且|其中|通常在|范围为|分别为|性能)\s*$/iu);
|
|
3818
|
+
expect(publicAnswer).not.toContain('```');
|
|
3819
|
+
expect((publicAnswer.match(/(?<!\\)\$/gu) || []).length % 2).toBe(0);
|
|
3820
|
+
expect((publicAnswer.match(/(?<!\\)\$\$/gu) || []).length % 2).toBe(0);
|
|
3821
|
+
expect(response.assistantBlocks?.filter((block) => block.type === 'structured_answer')).toHaveLength(1);
|
|
3822
|
+
expect(response.assistantBlocks?.find((block) => block.type === 'structured_answer')).toEqual(expect.objectContaining({ directAnswer: response.answer }));
|
|
3823
|
+
}
|
|
3816
3824
|
if (expected.ragSourceBoundary) {
|
|
3817
3825
|
expect(response.trace.ragContextPack).toEqual(expect.objectContaining({
|
|
3818
3826
|
sourceBoundary: expected.ragSourceBoundary,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const KnowledgeLearningPlatform_1 = require("./KnowledgeLearningPlatform");
|
|
4
|
+
async function measurementEvidence(first, second) {
|
|
5
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
6
|
+
await platform.ingestKnowledge({ relationRecomputeMode: 'none', documents: [
|
|
7
|
+
{ documentId: 'measurement-left', sourcePath: 'quality/measurement-left.md', content: `# Calibration Measurements\n${first}` },
|
|
8
|
+
{ documentId: 'measurement-right', sourcePath: 'quality/measurement-right.md', content: `# Calibration Measurements\n${second}` },
|
|
9
|
+
] });
|
|
10
|
+
return platform.agentConversation({ message: 'Summarize calibration measurements.', responseMode: 'full', persistMemory: false });
|
|
11
|
+
}
|
|
12
|
+
const measurements = [
|
|
13
|
+
['different frequencies', 'The calibration rate is 12 Hz.', 'The calibration rate is 18 Hz.', true],
|
|
14
|
+
['storage capacity', 'The calibration capacity is 64 MB.', 'The calibration capacity is 128 MB.', true],
|
|
15
|
+
['Chinese storage capacity', '定标缓冲区容量是64MB。', '定标缓冲区容量是128MB。', true],
|
|
16
|
+
['decimal storage units', 'The calibration capacity is 1 MB.', 'The calibration capacity is 1000000 B.', false],
|
|
17
|
+
['binary storage units', 'The calibration capacity is 1 MiB.', 'The calibration capacity is 1048576 B.', false],
|
|
18
|
+
['decimal and binary storage units differ', 'The calibration capacity is 1 MB.', 'The calibration capacity is 1 MiB.', true],
|
|
19
|
+
['bits and bytes', 'The calibration capacity is 1 B.', 'The calibration capacity is 8 b.', false],
|
|
20
|
+
['megabits and megabytes', 'The calibration capacity is 1 MB.', 'The calibration capacity is 8 Mb.', false],
|
|
21
|
+
['case-distinct storage units', 'The calibration capacity is 1 MB.', 'The calibration capacity is 1 Mb.', true],
|
|
22
|
+
['opposed storage constraint', 'The calibration capacity is 1 MB.', 'The calibration capacity is not 1000000 B.', true],
|
|
23
|
+
['Chinese frequencies', '定标频率是12赫兹。', '定标频率是18赫兹。', true],
|
|
24
|
+
['day durations', 'The calibration retention period is 7 days.', 'The calibration retention period is 30 days.', true],
|
|
25
|
+
['Chinese day durations', '定标记录保留周期是7天。', '定标记录保留周期是30天。', true],
|
|
26
|
+
['opposed exact constraints', 'The calibration rate is 12 Hz.', 'The calibration rate is not 12 Hz.', true],
|
|
27
|
+
['Chinese opposed constraints', '定标频率是12赫兹。', '定标频率不是12赫兹。', true],
|
|
28
|
+
['compatible negative constraint', 'The calibration rate is not 12 Hz.', 'The calibration rate is 18 Hz.', false],
|
|
29
|
+
['two exclusions', 'The calibration rate is not 12 Hz.', 'The calibration rate is not 18 Hz.', false],
|
|
30
|
+
['Chinese compatible constraint', '定标频率不是12赫兹。', '定标频率是18赫兹。', false],
|
|
31
|
+
['equivalent frequency units', 'The calibration rate is 1 kHz.', 'The calibration rate is 1000 Hz.', false],
|
|
32
|
+
['equivalent duration units', 'The calibration duration is 1000 ms.', 'The calibration duration is 1 s.', false],
|
|
33
|
+
['equivalent length units', 'The calibration length is 12 mm.', 'The calibration length is 1.2 cm.', false],
|
|
34
|
+
['equivalent mass units', 'The calibration mass is 1000 mg.', 'The calibration mass is 1 g.', false],
|
|
35
|
+
['equivalent temperature units', 'The calibration temperature is 0 °C.', 'The calibration temperature is 273.15 K.', false],
|
|
36
|
+
['incompatible dimensions', 'The calibration reading is 5 s.', 'The calibration reading is 5 m.', false],
|
|
37
|
+
['Chinese incompatible dimensions', '定标读数是5赫兹。', '定标读数是5毫秒。', false],
|
|
38
|
+
['historical headings', '## Current\nThe calibration duration is 12 ms.', '## Historical\nThe calibration duration is 18 ms.', false],
|
|
39
|
+
['environment headings', '## Production\nThe calibration duration is 12 ms.', '## Staging\nThe calibration duration is 18 ms.', false],
|
|
40
|
+
['Chinese environment headings', '## 生产环境\n定标时长是12毫秒。', '## 测试环境\n定标时长是18毫秒。', false],
|
|
41
|
+
['distinct minor versions', 'The calibration duration is 12 ms for version 1.2.', 'The calibration duration is 18 ms for version 1.3.', false],
|
|
42
|
+
['same minor version', 'The calibration duration is 12 ms for version 1.2.', 'The calibration duration is 18 ms for version 1.2.', true],
|
|
43
|
+
['different subjects', 'The alpha calibration duration is 12 ms.', 'The beta calibration duration is 18 ms.', false],
|
|
44
|
+
['scientific notation', 'The calibration rate is 1e3 Hz.', 'The calibration rate is 2e3 Hz.', true],
|
|
45
|
+
['scientific equivalence', 'The calibration rate is 1e3 Hz.', 'The calibration rate is 1000 Hz.', false],
|
|
46
|
+
['leading decimal magnitudes', 'The calibration duration is .5 s.', 'The calibration duration is .8 s.', true],
|
|
47
|
+
['uncertain magnitude', 'The calibration offset is ±12 ms.', 'The calibration offset is 4 ms.', false],
|
|
48
|
+
['range constraint', 'The calibration duration is at least 12 ms.', 'The calibration duration is 18 ms.', false],
|
|
49
|
+
['tolerance half-width constraints', 'The calibration tolerance is +/-0.10 mm.', 'The calibration tolerance is +/-0.50 mm.', true],
|
|
50
|
+
['equivalent tolerance half-widths', 'The calibration tolerance is ±0.10 mm.', 'The calibration tolerance is 0.01 cm.', false],
|
|
51
|
+
['Chinese tolerance half-widths', '定标公差为±0.10毫米。', '定标公差为±0.50毫米。', true],
|
|
52
|
+
['postfix uncertainty', 'The calibration duration is 12 ms ± 2 ms.', 'The calibration duration is 18 ms.', false],
|
|
53
|
+
['postfix range', 'The calibration duration is 12 ms to 20 ms.', 'The calibration duration is 18 ms.', false],
|
|
54
|
+
['unrecognized compound dimension', 'The calibration reading is 5 m/s.', 'The calibration reading is 8 m.', false],
|
|
55
|
+
['SI symbol case', 'The calibration reading is 5 µM.', 'The calibration reading is 8 µm.', false],
|
|
56
|
+
['tiny distinct magnitudes', 'The calibration length is 1e-10 nm.', 'The calibration length is 2e-10 nm.', true],
|
|
57
|
+
['equivalent measured capacity', 'The calibration size is 10 mm.', 'The calibration size is 1 cm.', false],
|
|
58
|
+
['explicit distinct years', 'The calibration duration is 12 ms in 2023.', 'The calibration duration is 18 ms in 2024.', false],
|
|
59
|
+
['explicit same year', 'The calibration duration is 12 ms in 2024.', 'The calibration duration is 18 ms in 2024.', true],
|
|
60
|
+
['Chinese distinct years', '定标时长在2023年是12毫秒。', '定标时长在2024年是18毫秒。', false],
|
|
61
|
+
['distinct platforms', 'The calibration duration is 12 ms on Linux.', 'The calibration duration is 18 ms on Windows.', false],
|
|
62
|
+
['same platform', 'The calibration duration is 12 ms on Linux.', 'The calibration duration is 18 ms on Linux.', true],
|
|
63
|
+
['standalone paragraph qualifiers', 'In production. The calibration duration is 12 ms.', 'In staging. The calibration duration is 18 ms.', false],
|
|
64
|
+
['matching paragraph qualifiers', 'In production. The calibration duration is 12 ms.', 'In production. The calibration duration is 18 ms.', true],
|
|
65
|
+
['ambiguous environment', 'The calibration duration is 12 ms in production or staging.', 'The calibration duration is 18 ms in production.', false],
|
|
66
|
+
['ambiguous heading', '## Production and Staging\nThe calibration duration is 12 ms.', '## Production\nThe calibration duration is 18 ms.', false],
|
|
67
|
+
];
|
|
68
|
+
describe('measurement evidence comparability', () => {
|
|
69
|
+
test.each(measurements)('%s', async (_name, first, second, conflictExpected) => {
|
|
70
|
+
const response = await measurementEvidence(first, second);
|
|
71
|
+
const conflicts = response.trace.ragContextPack?.fragments.filter(fragment => fragment.role === 'conflict') || [];
|
|
72
|
+
expect(conflicts.length > 0).toBe(conflictExpected);
|
|
73
|
+
for (const fragment of conflicts) {
|
|
74
|
+
expect(fragment.citationIds).toHaveLength(2);
|
|
75
|
+
expect(fragment.sourceBoundary).toBe('full_document');
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const KnowledgeLearningPlatform_1 = require("./KnowledgeLearningPlatform");
|
|
9
|
+
const AnswerQualityEvaluation_1 = require("./AnswerQualityEvaluation");
|
|
10
|
+
// V3's first confirmation is archived. These observed cases are now regression evidence.
|
|
11
|
+
const corpus = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v3.json'), 'utf8')));
|
|
12
|
+
const cases = corpus.cases.filter(entry => [
|
|
13
|
+
'cal-dag-en', 'cal-dag-zh', 'cal-retention-en', 'v3-retry-budget-en', 'v3-idempotency-zh',
|
|
14
|
+
'v3-sets-en', 'v3-index-swap-en', 'v3-memory-fences-en', 'v3-transaction-isolation-zh',
|
|
15
|
+
'v3-channels-zh', 'v3-checksum-en', 'v3-stable-reference-zh',
|
|
16
|
+
].includes(entry.id));
|
|
17
|
+
const observedV4 = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v4.json'), 'utf8')));
|
|
18
|
+
cases.push(...observedV4.cases.filter(entry => ['v4-receives-en', 'v4-content-addressing-en'].includes(entry.id)));
|
|
19
|
+
const observedV5 = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v5.json'), 'utf8')));
|
|
20
|
+
cases.push(...observedV5.cases.filter(entry => ['v5-iterator-en', 'v5-reentrant-lock-zh', 'v5-replication-zh'].includes(entry.id)));
|
|
21
|
+
const observedV6 = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v6.json'), 'utf8')));
|
|
22
|
+
cases.push(...observedV6.cases.filter(entry => ['v6-locking-en', 'v6-queue-en', 'v6-repeatable-command-en', 'v6-read-isolation-zh'].includes(entry.id)));
|
|
23
|
+
const observedV1 = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v1.json'), 'utf8')));
|
|
24
|
+
const observedV2 = (0, AnswerQualityEvaluation_1.parseAnswerQualityCorpus)(JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(__dirname, '../../fixtures/answer-quality/v2.json'), 'utf8')));
|
|
25
|
+
cases.push(...observedV1.cases.filter(entry => ['eval-capacity-en', 'eval-capacity-zh', 'eval-math-zh'].includes(entry.id)));
|
|
26
|
+
cases.push(...observedV2.cases.filter(entry => entry.id === 'confirm-collections-zh'));
|
|
27
|
+
describe.each(['slim', 'full'])('public answer contracts in %s', responseMode => {
|
|
28
|
+
test('keeps an unrelated Chinese sentence out after an explicit comparison subject', async () => {
|
|
29
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
30
|
+
await platform.ingestKnowledge({ relationRecomputeMode: 'none', documents: [
|
|
31
|
+
{ documentId: 'mutable', sourcePath: 'quality/mutable.md', content: '# 可变向量\n可变向量允许原地修改元素。火星有两颗卫星。' },
|
|
32
|
+
{ documentId: 'fixed', sourcePath: 'quality/fixed.md', content: '# 不可变向量\n不可变向量不允许原地修改元素。' },
|
|
33
|
+
] });
|
|
34
|
+
const response = await platform.agentConversation({ message: '比较可变向量和不可变向量。', answerLanguage: 'zh', responseMode, persistMemory: false });
|
|
35
|
+
if (responseMode === 'slim')
|
|
36
|
+
expect(response.answer).not.toContain('火星');
|
|
37
|
+
expect(response.answer).toContain('不允许原地修改元素');
|
|
38
|
+
});
|
|
39
|
+
test('treats a requested table concept as subject matter', async () => {
|
|
40
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
41
|
+
await platform.ingestKnowledge({ relationRecomputeMode: 'none', documents: [
|
|
42
|
+
{ documentId: 'dispatch-table', sourcePath: 'quality/dispatch.md', content: '# Dispatch Table\nA dispatch table maps operation codes to executable targets.' },
|
|
43
|
+
] });
|
|
44
|
+
const response = await platform.agentConversation({ message: 'What is a dispatch table?', answerLanguage: 'en', responseMode, persistMemory: false });
|
|
45
|
+
expect(response.answer).toContain('maps operation codes');
|
|
46
|
+
expect(response.answerReleaseReview?.decision).not.toBe('abstain');
|
|
47
|
+
});
|
|
48
|
+
test('keeps a short Chinese definition and its supported constraint', async () => {
|
|
49
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
50
|
+
await platform.ingestKnowledge({ relationRecomputeMode: 'none', documents: [
|
|
51
|
+
{ documentId: 'mutex', sourcePath: 'quality/mutex.md', content: '# 互斥锁\n互斥锁保护临界区。同一时刻只有一个持有者。' },
|
|
52
|
+
] });
|
|
53
|
+
const response = await platform.agentConversation({ message: '什么是互斥锁?', answerLanguage: 'zh', responseMode, persistMemory: false });
|
|
54
|
+
expect(response.answer).toContain('保护临界区');
|
|
55
|
+
expect(response.answer).toContain('同一时刻只有一个持有者');
|
|
56
|
+
});
|
|
57
|
+
test('rejects an attribute assertion about a different entity', async () => {
|
|
58
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
59
|
+
await platform.ingestKnowledge({ relationRecomputeMode: 'none', documents: [
|
|
60
|
+
{ documentId: 'helium', sourcePath: 'quality/helium.md', content: '# Helium Log\nThe Helium log retention period is 9 days.' },
|
|
61
|
+
] });
|
|
62
|
+
const response = await platform.agentConversation({ message: 'What is the retention period for the Titanium log?', answerLanguage: 'en', responseMode, persistMemory: false });
|
|
63
|
+
expect(response.answerReleaseReview?.decision).toBe('abstain');
|
|
64
|
+
expect(response.answer).not.toMatch(/9 days/iu);
|
|
65
|
+
});
|
|
66
|
+
test.each(cases)('$id preserves the requested evidence and its ordering', async (entry) => {
|
|
67
|
+
const platform = new KnowledgeLearningPlatform_1.KnowledgeLearningPlatform({ autoPersist: false });
|
|
68
|
+
await platform.ingestKnowledge({ documents: entry.documents, relationRecomputeMode: 'none' });
|
|
69
|
+
const response = await platform.agentConversation({ message: entry.query, answerLanguage: entry.language, responseMode,
|
|
70
|
+
persistMemory: false, scope: { documentIds: entry.documents.map(document => document.documentId) } });
|
|
71
|
+
expect(response.answerReleaseReview?.decision).not.toBe('abstain');
|
|
72
|
+
for (const fact of entry.reference.facts) {
|
|
73
|
+
expect({ id: fact.id, covered: fact.patterns.some(pattern => new RegExp(pattern, 'iu').test(response.answer)) })
|
|
74
|
+
.toEqual({ id: fact.id, covered: true });
|
|
75
|
+
}
|
|
76
|
+
for (const claim of entry.reference.unsupportedClaims)
|
|
77
|
+
expect(response.answer).not.toMatch(new RegExp(claim.pattern, 'iu'));
|
|
78
|
+
let previousEnd = 0;
|
|
79
|
+
for (const step of entry.reference.orderedSteps || []) {
|
|
80
|
+
const match = new RegExp(step, 'iu').exec(response.answer.slice(previousEnd));
|
|
81
|
+
expect(match).not.toBeNull();
|
|
82
|
+
previousEnd += match.index + match[0].length;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|