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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reviewGraphAnswerCoverage = reviewGraphAnswerCoverage;
|
|
4
|
+
const graphClaimMatcher_1 = require("./graphClaimMatcher");
|
|
5
|
+
function reviewGraphAnswerCoverage(answer, plan) {
|
|
6
|
+
const requiredClaims = (plan?.claims || []).filter((claim) => claim.required);
|
|
7
|
+
if (requiredClaims.length === 0) {
|
|
8
|
+
return {
|
|
9
|
+
passed: true,
|
|
10
|
+
applicable: false,
|
|
11
|
+
requiredClaimIds: [],
|
|
12
|
+
coveredClaimIds: [],
|
|
13
|
+
missingRequiredClaimIds: [],
|
|
14
|
+
coverageScore: 1,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const coveredClaimIds = requiredClaims
|
|
18
|
+
.filter((claim) => {
|
|
19
|
+
const answerKey = String(answer || '').replace(/\s+/gu, '');
|
|
20
|
+
const statementKey = String(claim.statement || '').replace(/\s+/gu, '');
|
|
21
|
+
return Boolean(statementKey && answerKey.includes(statementKey))
|
|
22
|
+
|| (0, graphClaimMatcher_1.matchGraphAnswerClaim)(answer, claim.statement).covered;
|
|
23
|
+
})
|
|
24
|
+
.map((claim) => claim.claimId);
|
|
25
|
+
const covered = new Set(coveredClaimIds);
|
|
26
|
+
const missingRequiredClaimIds = requiredClaims
|
|
27
|
+
.filter((claim) => !covered.has(claim.claimId))
|
|
28
|
+
.map((claim) => claim.claimId);
|
|
29
|
+
return {
|
|
30
|
+
passed: missingRequiredClaimIds.length === 0,
|
|
31
|
+
applicable: true,
|
|
32
|
+
requiredClaimIds: requiredClaims.map((claim) => claim.claimId),
|
|
33
|
+
coveredClaimIds,
|
|
34
|
+
missingRequiredClaimIds,
|
|
35
|
+
coverageScore: Number((coveredClaimIds.length / requiredClaims.length).toFixed(4)),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const graphAnswerCoverage_1 = require("./graphAnswerCoverage");
|
|
4
|
+
const plan = {
|
|
5
|
+
intent: 'definition',
|
|
6
|
+
depth: 'standard',
|
|
7
|
+
anchorAtomId: 'water_glass',
|
|
8
|
+
leadClaimId: 'definition',
|
|
9
|
+
requiredRoles: ['definition', 'boundary', 'mechanism'],
|
|
10
|
+
omittedCandidates: [],
|
|
11
|
+
claims: [
|
|
12
|
+
{
|
|
13
|
+
claimId: 'definition',
|
|
14
|
+
role: 'definition',
|
|
15
|
+
required: true,
|
|
16
|
+
priority: 100,
|
|
17
|
+
statement: 'A water glass is a transparent drinking vessel containing water.',
|
|
18
|
+
subjectAtomId: 'water_glass',
|
|
19
|
+
supportingAtomIds: [],
|
|
20
|
+
supportingEdgeIds: [],
|
|
21
|
+
evidenceRefs: [],
|
|
22
|
+
confidence: 0.98,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
claimId: 'boundary',
|
|
26
|
+
role: 'boundary',
|
|
27
|
+
required: true,
|
|
28
|
+
priority: 84,
|
|
29
|
+
statement: 'The solid wall forms a material boundary between the liquid and the environment.',
|
|
30
|
+
subjectAtomId: 'water_glass',
|
|
31
|
+
supportingAtomIds: ['material_boundary'],
|
|
32
|
+
supportingEdgeIds: [],
|
|
33
|
+
evidenceRefs: [],
|
|
34
|
+
confidence: 0.91,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
claimId: 'mechanism',
|
|
38
|
+
role: 'mechanism',
|
|
39
|
+
required: true,
|
|
40
|
+
priority: 82,
|
|
41
|
+
statement: 'Heat moves through the glass wall and its thickness affects thermal exchange.',
|
|
42
|
+
subjectAtomId: 'water_glass',
|
|
43
|
+
supportingAtomIds: ['thermal_exchange'],
|
|
44
|
+
supportingEdgeIds: ['edge_heat'],
|
|
45
|
+
evidenceRefs: [],
|
|
46
|
+
confidence: 0.9,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
describe('reviewGraphAnswerCoverage', () => {
|
|
51
|
+
test('passes when every required graph claim is represented with natural paraphrasing', () => {
|
|
52
|
+
const review = (0, graphAnswerCoverage_1.reviewGraphAnswerCoverage)('A water glass is a transparent vessel for water. Its solid wall separates the liquid from the surrounding environment. Heat passes through that glass wall, and wall thickness changes the rate of thermal exchange.', plan);
|
|
53
|
+
expect(review.passed).toBe(true);
|
|
54
|
+
expect(review.missingRequiredClaimIds).toEqual([]);
|
|
55
|
+
expect(review.coverageScore).toBe(1);
|
|
56
|
+
});
|
|
57
|
+
test('fails when a high-confidence mechanism claim is dropped from the public answer', () => {
|
|
58
|
+
const review = (0, graphAnswerCoverage_1.reviewGraphAnswerCoverage)('A water glass is a transparent drinking vessel containing water. Its solid wall forms a material boundary between the liquid and the environment.', plan);
|
|
59
|
+
expect(review.passed).toBe(false);
|
|
60
|
+
expect(review.missingRequiredClaimIds).toEqual(['mechanism']);
|
|
61
|
+
expect(review.coverageScore).toBeCloseTo(2 / 3, 4);
|
|
62
|
+
});
|
|
63
|
+
test('does not count a negated paraphrase as coverage', () => {
|
|
64
|
+
const review = (0, graphAnswerCoverage_1.reviewGraphAnswerCoverage)('A water glass is a transparent drinking vessel containing water. Its wall does not separate the liquid from the environment. Heat does not move through the glass wall and thickness has no effect on thermal exchange.', plan);
|
|
65
|
+
expect(review.coveredClaimIds).toEqual(['definition']);
|
|
66
|
+
expect(review.missingRequiredClaimIds).toEqual(['boundary', 'mechanism']);
|
|
67
|
+
});
|
|
68
|
+
test('covers conservative Chinese paraphrases without requiring exact source wording', () => {
|
|
69
|
+
const chinesePlan = {
|
|
70
|
+
...plan,
|
|
71
|
+
claims: [
|
|
72
|
+
{
|
|
73
|
+
...plan.claims[0],
|
|
74
|
+
claimId: 'definition_zh',
|
|
75
|
+
statement: '水杯是用于盛水的透明饮用容器。',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
...plan.claims[1],
|
|
79
|
+
claimId: 'boundary_zh',
|
|
80
|
+
statement: '坚固杯壁在液体和外部环境之间形成材料边界。',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
...plan.claims[2],
|
|
84
|
+
claimId: 'mechanism_zh',
|
|
85
|
+
statement: '热量会穿过杯壁,杯壁厚度会影响热交换。',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
const review = (0, graphAnswerCoverage_1.reviewGraphAnswerCoverage)('水杯是一种透明的盛水容器。它的实体杯壁把液体与周围环境隔开;热可以经由玻璃壁传递,而壁厚会改变换热速度。', chinesePlan);
|
|
90
|
+
expect(review.passed).toBe(true);
|
|
91
|
+
expect(review.coveredClaimIds).toEqual(['definition_zh', 'boundary_zh', 'mechanism_zh']);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_GRAPH_ANSWER_COVERAGE_CALIBRATION_CASES = void 0;
|
|
4
|
+
exports.evaluateGraphAnswerCoverageCalibration = evaluateGraphAnswerCoverageCalibration;
|
|
5
|
+
const graphClaimMatcher_1 = require("./graphClaimMatcher");
|
|
6
|
+
exports.DEFAULT_GRAPH_ANSWER_COVERAGE_CALIBRATION_CASES = [
|
|
7
|
+
{ caseId: 'definition_en_positive', statement: 'A water glass is a transparent container for water.', answer: 'A water glass is a transparent vessel used to hold water.', expectedCovered: true },
|
|
8
|
+
{ caseId: 'definition_en_negative', statement: 'A water glass is a transparent container for water.', answer: 'A water glass is not a transparent container for water.', expectedCovered: false },
|
|
9
|
+
{ caseId: 'definition_zh_positive', statement: '水杯是用于盛水的透明容器。', answer: '水杯是一种透明的盛水器皿。', expectedCovered: true },
|
|
10
|
+
{ caseId: 'definition_zh_negative', statement: '水杯是用于盛水的透明容器。', answer: '水杯并不是用于盛水的透明容器。', expectedCovered: false },
|
|
11
|
+
{ caseId: 'causal_en_positive', statement: 'Heating the sealed glass causes pressure to rise.', answer: 'Pressure rises because heat enters the sealed glass.', expectedCovered: true },
|
|
12
|
+
{ caseId: 'causal_en_negative', statement: 'Heating the sealed glass causes pressure to rise.', answer: 'Heating the sealed glass does not cause pressure to rise.', expectedCovered: false },
|
|
13
|
+
{ caseId: 'causal_zh_positive', statement: '加热密闭玻璃容器会导致压力上升。', answer: '密闭玻璃容器受热后会造成压力升高。', expectedCovered: true },
|
|
14
|
+
{ caseId: 'causal_zh_negative', statement: '加热密闭玻璃容器会导致压力上升。', answer: '加热密闭玻璃容器不会导致压力上升。', expectedCovered: false },
|
|
15
|
+
{ caseId: 'compare_en_positive', statement: 'Glass conducts heat better than plastic.', answer: 'Compared with plastic, glass conducts heat better.', expectedCovered: true },
|
|
16
|
+
{ caseId: 'compare_en_negative', statement: 'Glass conducts heat better than plastic.', answer: 'Glass does not conduct heat better than plastic.', expectedCovered: false },
|
|
17
|
+
{ caseId: 'compare_zh_positive', statement: '玻璃比塑料导热更快。', answer: '与塑料相比,玻璃导热更快。', expectedCovered: true },
|
|
18
|
+
{ caseId: 'compare_zh_negative', statement: '玻璃比塑料导热更快。', answer: '玻璃并不比塑料导热更快。', expectedCovered: false },
|
|
19
|
+
{ caseId: 'procedure_en_positive', statement: 'Rinse the glass before drying it.', answer: 'Before drying the glass, rinse it thoroughly.', expectedCovered: true },
|
|
20
|
+
{ caseId: 'procedure_en_negative', statement: 'Rinse the glass before drying it.', answer: 'Do not rinse the glass before drying it.', expectedCovered: false },
|
|
21
|
+
{ caseId: 'procedure_zh_positive', statement: '先冲洗杯子,再将它晾干。', answer: '杯子需要先冲洗,之后再晾干。', expectedCovered: true },
|
|
22
|
+
{ caseId: 'procedure_zh_negative', statement: '先冲洗杯子,再将它晾干。', answer: '不要先冲洗杯子再晾干。', expectedCovered: false },
|
|
23
|
+
{ caseId: 'temporal_en_positive', statement: 'This guidance applies after 2025.', answer: 'After 2025, this guidance applies.', expectedCovered: true },
|
|
24
|
+
{ caseId: 'temporal_en_negative', statement: 'This guidance applies after 2025.', answer: 'This guidance does not apply after 2025.', expectedCovered: false },
|
|
25
|
+
{ caseId: 'temporal_zh_positive', statement: '该规则在2025年之后生效。', answer: '2025年以后,该规则开始生效。', expectedCovered: true },
|
|
26
|
+
{ caseId: 'temporal_zh_negative', statement: '该规则在2025年之后生效。', answer: '该规则在2025年之后不会生效。', expectedCovered: false },
|
|
27
|
+
{ caseId: 'weak_evidence_en_positive', statement: 'Heat passing through the wall raises the liquid temperature.', answer: 'The liquid temperature rises as heat passes through the wall.', expectedCovered: true },
|
|
28
|
+
{ caseId: 'weak_evidence_en_negative', statement: 'Heat passing through the wall raises the liquid temperature.', answer: 'The graph contains a node titled Liquid Temperature.', expectedCovered: false },
|
|
29
|
+
{ caseId: 'weak_evidence_zh_positive', statement: '热量穿过杯壁会使液体温度上升。', answer: '液体温度会随着热量经杯壁传递而升高。', expectedCovered: true },
|
|
30
|
+
{ caseId: 'weak_evidence_zh_negative', statement: '热量穿过杯壁会使液体温度上升。', answer: '图中存在一个名为“液体温度”的节点。', expectedCovered: false },
|
|
31
|
+
];
|
|
32
|
+
function evaluateGraphAnswerCoverageCalibration(cases) {
|
|
33
|
+
const falsePositiveCaseIds = [];
|
|
34
|
+
const falseNegativeCaseIds = [];
|
|
35
|
+
let truePositiveCount = 0;
|
|
36
|
+
let trueNegativeCount = 0;
|
|
37
|
+
cases.forEach((item) => {
|
|
38
|
+
const covered = (0, graphClaimMatcher_1.matchGraphAnswerClaim)(item.answer, item.statement).covered;
|
|
39
|
+
if (covered && item.expectedCovered)
|
|
40
|
+
truePositiveCount += 1;
|
|
41
|
+
else if (!covered && !item.expectedCovered)
|
|
42
|
+
trueNegativeCount += 1;
|
|
43
|
+
else if (covered)
|
|
44
|
+
falsePositiveCaseIds.push(item.caseId);
|
|
45
|
+
else
|
|
46
|
+
falseNegativeCaseIds.push(item.caseId);
|
|
47
|
+
});
|
|
48
|
+
const precisionDenominator = truePositiveCount + falsePositiveCaseIds.length;
|
|
49
|
+
const recallDenominator = truePositiveCount + falseNegativeCaseIds.length;
|
|
50
|
+
return {
|
|
51
|
+
sampleCount: cases.length,
|
|
52
|
+
truePositiveCount,
|
|
53
|
+
trueNegativeCount,
|
|
54
|
+
falsePositiveCaseIds,
|
|
55
|
+
falseNegativeCaseIds,
|
|
56
|
+
precision: precisionDenominator > 0 ? Number((truePositiveCount / precisionDenominator).toFixed(4)) : 1,
|
|
57
|
+
recall: recallDenominator > 0 ? Number((truePositiveCount / recallDenominator).toFixed(4)) : 1,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const graphAnswerCoverageCalibration_1 = require("./graphAnswerCoverageCalibration");
|
|
4
|
+
describe('evaluateGraphAnswerCoverageCalibration', () => {
|
|
5
|
+
test('reports false positives and false negatives separately', () => {
|
|
6
|
+
const report = (0, graphAnswerCoverageCalibration_1.evaluateGraphAnswerCoverageCalibration)([
|
|
7
|
+
{
|
|
8
|
+
caseId: 'positive_en',
|
|
9
|
+
statement: 'Heat moves through the glass wall.',
|
|
10
|
+
answer: 'Thermal energy passes through the glass wall.',
|
|
11
|
+
expectedCovered: true,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
caseId: 'negative_en',
|
|
15
|
+
statement: 'Heat moves through the glass wall.',
|
|
16
|
+
answer: 'Heat does not move through the glass wall.',
|
|
17
|
+
expectedCovered: false,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
caseId: 'positive_zh',
|
|
21
|
+
statement: '杯壁把液体与环境隔开。',
|
|
22
|
+
answer: '实体杯壁将杯中液体和外部环境分隔开。',
|
|
23
|
+
expectedCovered: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
caseId: 'negative_zh',
|
|
27
|
+
statement: '杯壁把液体与环境隔开。',
|
|
28
|
+
answer: '杯壁并不能把液体与外部环境隔开。',
|
|
29
|
+
expectedCovered: false,
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
expect(report.sampleCount).toBe(4);
|
|
33
|
+
expect(report.falsePositiveCaseIds).toEqual([]);
|
|
34
|
+
expect(report.falseNegativeCaseIds).toEqual([]);
|
|
35
|
+
expect(report.precision).toBe(1);
|
|
36
|
+
expect(report.recall).toBe(1);
|
|
37
|
+
});
|
|
38
|
+
test('meets the release floor across the versioned multilingual intent corpus', () => {
|
|
39
|
+
const report = (0, graphAnswerCoverageCalibration_1.evaluateGraphAnswerCoverageCalibration)(graphAnswerCoverageCalibration_1.DEFAULT_GRAPH_ANSWER_COVERAGE_CALIBRATION_CASES);
|
|
40
|
+
expect(report.sampleCount).toBeGreaterThanOrEqual(24);
|
|
41
|
+
expect(report.falsePositiveCaseIds).toEqual([]);
|
|
42
|
+
expect(report.falseNegativeCaseIds).toEqual([]);
|
|
43
|
+
expect(report.precision).toBeGreaterThanOrEqual(0.95);
|
|
44
|
+
expect(report.recall).toBeGreaterThanOrEqual(0.95);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatGraphAnswerProfileSentence = formatGraphAnswerProfileSentence;
|
|
4
|
+
exports.collectGraphAnswerWindowTitles = collectGraphAnswerWindowTitles;
|
|
5
|
+
exports.collectGraphAnswerFacts = collectGraphAnswerFacts;
|
|
6
|
+
function formatGraphAnswerProfileSentence(facts, useChinese) {
|
|
7
|
+
const { anchorTitle, predecessorTitles, successorTitles } = facts;
|
|
8
|
+
const degreeParts = [];
|
|
9
|
+
if (facts.inDegree !== null) {
|
|
10
|
+
degreeParts.push(useChinese ? `入度为 ${facts.inDegree}` : `${facts.inDegree} incoming`);
|
|
11
|
+
}
|
|
12
|
+
if (facts.outDegree !== null) {
|
|
13
|
+
degreeParts.push(useChinese ? `出度为 ${facts.outDegree}` : `${facts.outDegree} outgoing`);
|
|
14
|
+
}
|
|
15
|
+
if (degreeParts.length <= 0 && predecessorTitles.length <= 0 && successorTitles.length <= 0) {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
if (useChinese) {
|
|
19
|
+
const fragments = [];
|
|
20
|
+
if (degreeParts.length > 0) {
|
|
21
|
+
fragments.push(`${anchorTitle || '当前锚点'}在当前图中的${degreeParts.join(',')}`);
|
|
22
|
+
}
|
|
23
|
+
if (predecessorTitles.length > 0) {
|
|
24
|
+
fragments.push(`紧邻前置节点包括 ${predecessorTitles.join('、')}`);
|
|
25
|
+
}
|
|
26
|
+
if (successorTitles.length > 0) {
|
|
27
|
+
fragments.push(`后续分支包括 ${successorTitles.join('、')}`);
|
|
28
|
+
}
|
|
29
|
+
return fragments.join(',');
|
|
30
|
+
}
|
|
31
|
+
const fragments = [];
|
|
32
|
+
if (degreeParts.length > 0) {
|
|
33
|
+
fragments.push(`${anchorTitle || 'The current anchor'} has ${degreeParts.join(' and ')} links in the current graph`);
|
|
34
|
+
}
|
|
35
|
+
if (predecessorTitles.length > 0 && successorTitles.length > 0) {
|
|
36
|
+
fragments.push(`The graph connects this topic to upstream evidence from ${predecessorTitles.join(', ')} and downstream evidence from ${successorTitles.join(', ')}`);
|
|
37
|
+
}
|
|
38
|
+
else if (predecessorTitles.length > 0) {
|
|
39
|
+
fragments.push(`The graph connects this topic to upstream evidence from ${predecessorTitles.join(', ')}`);
|
|
40
|
+
}
|
|
41
|
+
else if (successorTitles.length > 0) {
|
|
42
|
+
fragments.push(`The graph connects this topic to downstream evidence from ${successorTitles.join(', ')}`);
|
|
43
|
+
}
|
|
44
|
+
return fragments.join('; ');
|
|
45
|
+
}
|
|
46
|
+
function normalizeAtomId(value) {
|
|
47
|
+
return String(value || '').trim();
|
|
48
|
+
}
|
|
49
|
+
function normalizeComparableTitle(value) {
|
|
50
|
+
return value.toLowerCase();
|
|
51
|
+
}
|
|
52
|
+
function collectGraphAnswerWindowTitles(graphContext, windowKey, selection, limit) {
|
|
53
|
+
const anchorAtomId = normalizeAtomId(selection.anchorAtomId);
|
|
54
|
+
const anchorTitle = normalizeComparableTitle(selection.normalizeTitle(selection.anchorTitle));
|
|
55
|
+
const seen = new Set();
|
|
56
|
+
const titles = [];
|
|
57
|
+
for (const node of graphContext[windowKey] || []) {
|
|
58
|
+
const atomId = normalizeAtomId(node && node.atomId);
|
|
59
|
+
const title = selection.normalizeTitle(node && node.title);
|
|
60
|
+
const comparableTitle = normalizeComparableTitle(title);
|
|
61
|
+
if (!title || (atomId && atomId === anchorAtomId) || (comparableTitle && comparableTitle === anchorTitle)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const key = comparableTitle || atomId;
|
|
65
|
+
if (seen.has(key)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
seen.add(key);
|
|
69
|
+
titles.push(title);
|
|
70
|
+
if (titles.length >= limit) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return titles;
|
|
75
|
+
}
|
|
76
|
+
function finiteNumber(value) {
|
|
77
|
+
const numeric = Number(value);
|
|
78
|
+
return Number.isFinite(numeric) ? numeric : null;
|
|
79
|
+
}
|
|
80
|
+
function collectGraphAnswerFacts(graphContext, selection, windowLimit = 2) {
|
|
81
|
+
if (!graphContext) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const anchorProfile = graphContext.anchorGraphProfile && typeof graphContext.anchorGraphProfile === 'object'
|
|
85
|
+
? graphContext.anchorGraphProfile
|
|
86
|
+
: null;
|
|
87
|
+
return {
|
|
88
|
+
anchorTitle: selection.normalizeTitle(selection.anchorTitle),
|
|
89
|
+
inDegree: finiteNumber(anchorProfile?.inDegree),
|
|
90
|
+
outDegree: finiteNumber(anchorProfile?.outDegree),
|
|
91
|
+
predecessorTitles: collectGraphAnswerWindowTitles(graphContext, 'predecessorWindow', selection, windowLimit),
|
|
92
|
+
successorTitles: collectGraphAnswerWindowTitles(graphContext, 'successorWindow', selection, windowLimit),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const graphAnswerFacts_1 = require("./graphAnswerFacts");
|
|
4
|
+
function makeGraphContext() {
|
|
5
|
+
return {
|
|
6
|
+
anchorAtomId: 'anchor',
|
|
7
|
+
anchorTitle: 'Anchor',
|
|
8
|
+
anchorGraphProfile: { atomId: 'anchor', title: 'Anchor', inDegree: 2, outDegree: 3 },
|
|
9
|
+
predecessorWindow: [
|
|
10
|
+
{ atomId: 'anchor', title: 'Anchor' },
|
|
11
|
+
{ atomId: 'predecessor', title: 'Upstream Node' },
|
|
12
|
+
{ atomId: 'duplicate', title: 'upstream node' },
|
|
13
|
+
],
|
|
14
|
+
successorWindow: [{ atomId: 'successor', title: 'Downstream Node' }],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
describe('collectGraphAnswerFacts', () => {
|
|
18
|
+
test('deduplicates windows and excludes the anchor by atom or title', () => {
|
|
19
|
+
const facts = (0, graphAnswerFacts_1.collectGraphAnswerFacts)(makeGraphContext(), {
|
|
20
|
+
anchorAtomId: 'anchor',
|
|
21
|
+
anchorTitle: 'Anchor',
|
|
22
|
+
normalizeTitle: (value) => String(value || '').trim(),
|
|
23
|
+
});
|
|
24
|
+
expect(facts).toEqual({
|
|
25
|
+
anchorTitle: 'Anchor',
|
|
26
|
+
inDegree: 2,
|
|
27
|
+
outDegree: 3,
|
|
28
|
+
predecessorTitles: ['Upstream Node'],
|
|
29
|
+
successorTitles: ['Downstream Node'],
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
test('returns no facts when graph context is unavailable', () => {
|
|
33
|
+
expect((0, graphAnswerFacts_1.collectGraphAnswerFacts)(null, {
|
|
34
|
+
anchorAtomId: '',
|
|
35
|
+
anchorTitle: '',
|
|
36
|
+
normalizeTitle: (value) => String(value || '').trim(),
|
|
37
|
+
})).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
});
|