oh-my-knowledge 0.48.0 → 0.49.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 +50 -18
- package/README.zh.md +55 -23
- package/dist/analysis/coverage-analyzer.d.ts +1 -0
- package/dist/analysis/coverage-analyzer.js +125 -62
- package/dist/analysis/failure-clusterer.js +2 -1
- package/dist/analysis/gap-analyzer.d.ts +2 -2
- package/dist/analysis/gap-analyzer.js +13 -3
- package/dist/analysis/hedging-classifier.d.ts +2 -2
- package/dist/analysis/hedging-classifier.js +3 -4
- package/dist/analysis/report-diagnostics.js +9 -7
- package/dist/analysis/sample-diagnostics.js +6 -6
- package/dist/artifact-graph/doctor.js +15 -7
- package/dist/assets/agent-skills/omk/SKILL.md +27 -7
- package/dist/assets/agent-skills/omk/references/commands.md +18 -17
- package/dist/authoring/evolver.d.ts +10 -6
- package/dist/authoring/evolver.js +496 -83
- package/dist/authoring/generator.d.ts +3 -3
- package/dist/authoring/generator.js +5 -10
- package/dist/authoring/sample-fixer.d.ts +8 -6
- package/dist/authoring/sample-fixer.js +76 -5
- package/dist/cli/commands/doctor.js +31 -14
- package/dist/cli/commands/eval/index.d.ts +3 -0
- package/dist/cli/commands/eval/index.js +163 -17
- package/dist/cli/commands/evolve.d.ts +4 -4
- package/dist/cli/commands/evolve.js +27 -13
- package/dist/cli/commands/init.js +16 -3
- package/dist/cli/commands/observe/inbox.js +28 -21
- package/dist/cli/commands/observe/index.js +20 -11
- package/dist/cli/commands/observe/ingest.d.ts +3 -0
- package/dist/cli/commands/observe/ingest.js +30 -2
- package/dist/cli/commands/sample.d.ts +6 -3
- package/dist/cli/commands/sample.js +72 -68
- package/dist/cli/lib/codex-model-hint.d.ts +9 -0
- package/dist/cli/lib/codex-model-hint.js +45 -0
- package/dist/cli/lib/generation-failure-hint.d.ts +2 -0
- package/dist/cli/lib/generation-failure-hint.js +61 -0
- package/dist/cli/lib/i18n-dict/common.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/common.js +4 -0
- package/dist/cli/lib/i18n-dict/gen.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/gen.js +38 -6
- package/dist/cli/lib/i18n-dict/help.js +6 -6
- package/dist/cli/lib/i18n-dict/init.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/init.js +13 -9
- package/dist/cli/lib/i18n-dict/run.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/run.js +34 -2
- package/dist/cli/lib/llm-failure-classifier.d.ts +2 -0
- package/dist/cli/lib/llm-failure-classifier.js +8 -0
- package/dist/cli/lib/parse-run-config.d.ts +6 -5
- package/dist/cli/lib/parse-run-config.js +16 -9
- package/dist/cli/lib/runtime-defaults.d.ts +21 -0
- package/dist/cli/lib/runtime-defaults.js +79 -0
- package/dist/diagnosis/observe-mapper.js +14 -15
- package/dist/diagnosis/observe-producer.js +3 -1
- package/dist/diagnosis/studio-projection.js +14 -7
- package/dist/diagnosis/types.d.ts +2 -0
- package/dist/diagnosis/types.js +12 -0
- package/dist/doctor/endpoint-rule.js +2 -1
- package/dist/eval-core/artifact-file-names.js +18 -1
- package/dist/eval-core/artifact-index.d.ts +7 -11
- package/dist/eval-core/artifact-index.js +139 -80
- package/dist/eval-core/cache.d.ts +12 -3
- package/dist/eval-core/cache.js +89 -29
- package/dist/eval-core/comparability.js +10 -6
- package/dist/eval-core/evaluation-execution.d.ts +2 -1
- package/dist/eval-core/evaluation-execution.js +122 -37
- package/dist/eval-core/evaluation-job.d.ts +4 -1
- package/dist/eval-core/evaluation-job.js +4 -1
- package/dist/eval-core/evaluation-reporting.d.ts +15 -13
- package/dist/eval-core/evaluation-reporting.js +54 -52
- package/dist/eval-core/execution-strategy.d.ts +2 -0
- package/dist/eval-core/execution-strategy.js +11 -9
- package/dist/eval-core/fact-checker.js +15 -7
- package/dist/eval-core/holdout.js +3 -2
- package/dist/eval-core/judge-independence.d.ts +2 -2
- package/dist/eval-core/mock-hook.cjs +23 -6
- package/dist/eval-core/mocks-runtime.js +30 -8
- package/dist/eval-core/report-document.d.ts +12 -0
- package/dist/eval-core/report-document.js +1151 -0
- package/dist/eval-core/report-extensions.d.ts +4 -0
- package/dist/eval-core/report-extensions.js +500 -0
- package/dist/eval-core/report-file-migration.js +7 -2
- package/dist/eval-core/resume-compatibility.d.ts +31 -0
- package/dist/eval-core/resume-compatibility.js +141 -0
- package/dist/eval-core/sample-fingerprint.d.ts +12 -0
- package/dist/eval-core/sample-fingerprint.js +193 -0
- package/dist/eval-core/schema.js +86 -31
- package/dist/eval-core/verdict.d.ts +8 -4
- package/dist/eval-core/verdict.js +24 -10
- package/dist/eval-workflows/batch-evaluation-workflow.d.ts +2 -1
- package/dist/eval-workflows/batch-evaluation-workflow.js +25 -12
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.d.ts +10 -5
- package/dist/eval-workflows/evaluation-pipeline/preflight-warnings.js +58 -21
- package/dist/eval-workflows/evaluation-pipeline/report-finalize.js +3 -1
- package/dist/eval-workflows/evaluation-pipeline/run-state.d.ts +4 -1
- package/dist/eval-workflows/evaluation-pipeline/run-state.js +4 -1
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.d.ts +6 -5
- package/dist/eval-workflows/evaluation-pipeline/test-set-hash.js +17 -10
- package/dist/eval-workflows/evaluation-pipeline.js +12 -7
- package/dist/eval-workflows/run-evaluation.d.ts +9 -7
- package/dist/eval-workflows/run-evaluation.js +79 -51
- package/dist/executors/anthropic-api.js +65 -9
- package/dist/executors/claude-cli.js +16 -79
- package/dist/executors/claude-protocol.d.ts +28 -0
- package/dist/executors/claude-protocol.js +180 -0
- package/dist/executors/claude-sdk-trace.js +56 -28
- package/dist/executors/claude-sdk.d.ts +1 -0
- package/dist/executors/claude-sdk.js +39 -93
- package/dist/executors/codex-cli-trace.js +166 -31
- package/dist/executors/codex-cli.d.ts +6 -8
- package/dist/executors/codex-cli.js +49 -151
- package/dist/executors/codex-protocol.d.ts +24 -0
- package/dist/executors/codex-protocol.js +234 -0
- package/dist/executors/codex-sdk.js +68 -120
- package/dist/executors/gemini.js +88 -13
- package/dist/executors/index.d.ts +2 -3
- package/dist/executors/index.js +5 -3
- package/dist/executors/openai-api.js +70 -9
- package/dist/executors/runtime-fingerprint.js +88 -11
- package/dist/executors/script-command.d.ts +8 -0
- package/dist/executors/script-command.js +87 -0
- package/dist/executors/script.js +202 -29
- package/dist/executors/shared.d.ts +35 -3
- package/dist/executors/shared.js +113 -15
- package/dist/grading/assertions.d.ts +1 -1
- package/dist/grading/assertions.js +19 -9
- package/dist/grading/diagnostic.d.ts +9 -2
- package/dist/grading/diagnostic.js +25 -2
- package/dist/grading/index.js +10 -4
- package/dist/grading/judge.js +19 -6
- package/dist/grading/layered-scores.d.ts +2 -3
- package/dist/grading/layered-scores.js +2 -3
- package/dist/inputs/load-samples.d.ts +1 -2
- package/dist/inputs/load-samples.js +23 -1
- package/dist/inputs/mcp-resolver.js +6 -3
- package/dist/inputs/sample-document.d.ts +11 -0
- package/dist/inputs/sample-document.js +96 -0
- package/dist/managed/evidence.d.ts +1 -0
- package/dist/managed/evidence.js +1 -1
- package/dist/managed/store.js +200 -91
- package/dist/observability/codex-trace-adapter.d.ts +5 -0
- package/dist/observability/codex-trace-adapter.js +850 -0
- package/dist/observability/experience.d.ts +32 -6
- package/dist/observability/experience.js +2695 -459
- package/dist/observability/feedback-matchers.js +16 -1
- package/dist/observability/inbox-view-model.d.ts +1 -1
- package/dist/observability/inbox-view-model.js +19 -14
- package/dist/observability/inbox.d.ts +7 -1
- package/dist/observability/inbox.js +632 -124
- package/dist/observability/problem-patterns.js +2 -0
- package/dist/observability/review-state.d.ts +6 -0
- package/dist/observability/review-state.js +235 -63
- package/dist/observability/skill-chain-advisories.js +1 -1
- package/dist/observability/skill-chain.js +17 -4
- package/dist/observability/skill-health-analyzer.d.ts +32 -7
- package/dist/observability/skill-health-analyzer.js +194 -121
- package/dist/observability/skill-health-report.d.ts +10 -0
- package/dist/observability/skill-health-report.js +620 -0
- package/dist/observability/soft-standards/constants.d.ts +0 -1
- package/dist/observability/soft-standards/constants.js +0 -1
- package/dist/observability/soft-standards/index.d.ts +1 -1
- package/dist/observability/soft-standards/index.js +1 -1
- package/dist/observability/soft-standards/llm-extractor.js +8 -10
- package/dist/observability/soft-standards/skill-standards-store.d.ts +2 -1
- package/dist/observability/soft-standards/skill-standards-store.js +59 -18
- package/dist/observability/soft-standards/types.d.ts +2 -2
- package/dist/observability/trace-adapter.d.ts +12 -7
- package/dist/observability/trace-adapter.js +11 -9
- package/dist/observability/trace-attribution.d.ts +13 -5
- package/dist/observability/trace-attribution.js +315 -21
- package/dist/observability/trace-ingestion.d.ts +9 -0
- package/dist/observability/trace-ingestion.js +80 -0
- package/dist/observability/trace-ir.d.ts +113 -0
- package/dist/observability/trace-ir.js +87 -0
- package/dist/observability/trace-segmenter.d.ts +19 -6
- package/dist/observability/trace-segmenter.js +377 -196
- package/dist/observability/trace-session-index.d.ts +19 -0
- package/dist/observability/trace-session-index.js +68 -0
- package/dist/observability/trace-source.d.ts +12 -4
- package/dist/observability/trace-source.js +939 -215
- package/dist/renderer/html-renderer.js +37 -6
- package/dist/renderer/icons.js +3 -0
- package/dist/renderer/observation-inbox-renderer.js +208 -90
- package/dist/renderer/skill-detail-renderer.js +452 -109
- package/dist/renderer/skill-health-renderer.js +69 -12
- package/dist/renderer/summary.js +28 -7
- package/dist/renderer/table.js +21 -4
- package/dist/renderer/test-view.d.ts +1 -0
- package/dist/renderer/test-view.js +44 -9
- package/dist/server/indexed-report-store.js +14 -18
- package/dist/server/job-store.js +64 -26
- package/dist/server/report-server.js +190 -78
- package/dist/server/report-store.js +57 -80
- package/dist/server/skill-index.js +143 -49
- package/dist/server/skill-insights.js +44 -5
- package/dist/shared/artifact-graph.d.ts +3 -0
- package/dist/shared/artifact-graph.js +224 -0
- package/dist/shared/assertion-types.d.ts +8 -0
- package/dist/shared/assertion-types.js +46 -0
- package/dist/shared/atomic-json.d.ts +8 -0
- package/dist/shared/atomic-json.js +33 -0
- package/dist/shared/diagnosis-schema.d.ts +9 -0
- package/dist/shared/diagnosis-schema.js +181 -0
- package/dist/shared/doctor-report.d.ts +3 -0
- package/dist/shared/doctor-report.js +103 -0
- package/dist/shared/evaluation-job.d.ts +6 -0
- package/dist/shared/evaluation-job.js +217 -0
- package/dist/shared/executor-result.d.ts +17 -0
- package/dist/shared/executor-result.js +221 -0
- package/dist/shared/file-lock.d.ts +12 -0
- package/dist/shared/file-lock.js +129 -0
- package/dist/shared/json-value.d.ts +5 -0
- package/dist/shared/json-value.js +36 -0
- package/dist/shared/keyed-mutex.d.ts +7 -0
- package/dist/shared/keyed-mutex.js +24 -0
- package/dist/shared/record-count.d.ts +8 -0
- package/dist/shared/record-count.js +43 -0
- package/dist/shared/sample-contract.d.ts +3 -0
- package/dist/shared/sample-contract.js +332 -0
- package/dist/shared/timestamp.d.ts +6 -0
- package/dist/shared/timestamp.js +64 -0
- package/dist/shared/token-usage.d.ts +19 -0
- package/dist/shared/token-usage.js +50 -0
- package/dist/shared/tool-call-status.d.ts +8 -0
- package/dist/shared/tool-call-status.js +28 -0
- package/dist/shared/tool-identity.d.ts +21 -0
- package/dist/shared/tool-identity.js +84 -0
- package/dist/shared/tool-search.js +73 -16
- package/dist/shared/trace-projection.d.ts +5 -0
- package/dist/shared/trace-projection.js +20 -0
- package/dist/shared/trace-source-kind.d.ts +3 -0
- package/dist/shared/trace-source-kind.js +12 -0
- package/dist/types/diagnosis.d.ts +2 -0
- package/dist/types/eval.d.ts +4 -0
- package/dist/types/executor.d.ts +32 -5
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/judge.d.ts +2 -0
- package/dist/types/observability.d.ts +116 -9
- package/dist/types/report.d.ts +58 -6
- package/dist/types/skill-index.d.ts +7 -0
- package/dist/types/trace.d.ts +2 -0
- package/dist/types/trace.js +1 -0
- package/package.json +9 -5
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AnalysisResult, ResultEntry, SampleSnapshot, VarianceData } from '../types/index.js';
|
|
2
|
+
export declare function isSampleSnapshotRecord(value: unknown, sampleIds: string[]): value is Record<string, SampleSnapshot>;
|
|
3
|
+
export declare function isAnalysisResult(value: unknown, variants: string[], results: ResultEntry[]): value is AnalysisResult;
|
|
4
|
+
export declare function isVarianceData(value: unknown, variants: string[]): value is VarianceData;
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { isJsonValue } from '../shared/json-value.js';
|
|
2
|
+
import { sampleContractValidationError } from '../shared/sample-contract.js';
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function isFiniteNumber(value) {
|
|
7
|
+
return typeof value === 'number'
|
|
8
|
+
&& Number.isFinite(value)
|
|
9
|
+
&& Math.abs(value) <= Number.MAX_SAFE_INTEGER;
|
|
10
|
+
}
|
|
11
|
+
function isNonNegativeNumber(value) {
|
|
12
|
+
return isFiniteNumber(value) && value >= 0;
|
|
13
|
+
}
|
|
14
|
+
function isNonNegativeInteger(value) {
|
|
15
|
+
return Number.isSafeInteger(value) && value >= 0;
|
|
16
|
+
}
|
|
17
|
+
function isRate(value) {
|
|
18
|
+
return isFiniteNumber(value) && value >= 0 && value <= 1;
|
|
19
|
+
}
|
|
20
|
+
function isScore(value) {
|
|
21
|
+
return isFiniteNumber(value) && value >= 0 && value <= 5;
|
|
22
|
+
}
|
|
23
|
+
function hasExactKeys(value, expected) {
|
|
24
|
+
const keys = Object.keys(value);
|
|
25
|
+
return keys.length === expected.length && expected.every((key) => Object.hasOwn(value, key));
|
|
26
|
+
}
|
|
27
|
+
function hasOnlyKeys(value, allowed) {
|
|
28
|
+
const allowedKeys = new Set(allowed);
|
|
29
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
30
|
+
}
|
|
31
|
+
function isStringArray(value) {
|
|
32
|
+
return Array.isArray(value)
|
|
33
|
+
&& value.every((entry) => typeof entry === 'string' && entry.length > 0);
|
|
34
|
+
}
|
|
35
|
+
function isSampleSnapshot(value, expectedId) {
|
|
36
|
+
return sampleContractValidationError(value, expectedId) === undefined;
|
|
37
|
+
}
|
|
38
|
+
export function isSampleSnapshotRecord(value, sampleIds) {
|
|
39
|
+
return isRecord(value)
|
|
40
|
+
&& hasExactKeys(value, sampleIds)
|
|
41
|
+
&& sampleIds.every((sampleId) => isSampleSnapshot(value[sampleId], sampleId));
|
|
42
|
+
}
|
|
43
|
+
function isCountRecord(value) {
|
|
44
|
+
return isRecord(value)
|
|
45
|
+
&& Object.keys(value).every((key) => key.length > 0)
|
|
46
|
+
&& Object.values(value).every(isNonNegativeInteger);
|
|
47
|
+
}
|
|
48
|
+
function safeCountSum(value) {
|
|
49
|
+
let total = 0;
|
|
50
|
+
for (const count of Object.values(value)) {
|
|
51
|
+
total += count;
|
|
52
|
+
if (!Number.isSafeInteger(total))
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return total;
|
|
56
|
+
}
|
|
57
|
+
function isCoverage(value) {
|
|
58
|
+
if (!isRecord(value)
|
|
59
|
+
|| !Array.isArray(value.entries)
|
|
60
|
+
|| !value.entries.every((entry) => isRecord(entry)
|
|
61
|
+
&& typeof entry.path === 'string'
|
|
62
|
+
&& entry.path.length > 0
|
|
63
|
+
&& (entry.type === 'principle'
|
|
64
|
+
|| entry.type === 'semantic'
|
|
65
|
+
|| entry.type === 'design'
|
|
66
|
+
|| entry.type === 'script'
|
|
67
|
+
|| entry.type === 'code'
|
|
68
|
+
|| entry.type === 'other')
|
|
69
|
+
&& typeof entry.accessed === 'boolean'
|
|
70
|
+
&& isNonNegativeInteger(entry.accessCount)
|
|
71
|
+
&& entry.accessed === (entry.accessCount > 0)
|
|
72
|
+
&& (entry.lineCount === undefined || isNonNegativeInteger(entry.lineCount)))
|
|
73
|
+
|| !isNonNegativeInteger(value.filesCovered)
|
|
74
|
+
|| !isNonNegativeInteger(value.filesTotal)
|
|
75
|
+
|| !isRate(value.fileCoverageRate)
|
|
76
|
+
|| !isStringArray(value.uncoveredFiles)
|
|
77
|
+
|| !isNonNegativeInteger(value.grepPatternsUsed)
|
|
78
|
+
|| !isRate(value.overallRate))
|
|
79
|
+
return false;
|
|
80
|
+
const entries = value.entries;
|
|
81
|
+
const paths = entries.map((entry) => entry.path);
|
|
82
|
+
if (new Set(paths).size !== paths.length)
|
|
83
|
+
return false;
|
|
84
|
+
const filesCovered = entries.filter((entry) => entry.accessed).length;
|
|
85
|
+
const uncoveredFiles = entries
|
|
86
|
+
.filter((entry) => !entry.accessed)
|
|
87
|
+
.map((entry) => entry.path);
|
|
88
|
+
if (value.filesTotal !== entries.length
|
|
89
|
+
|| value.filesCovered !== filesCovered
|
|
90
|
+
|| value.uncoveredFiles.length !== uncoveredFiles.length
|
|
91
|
+
|| value.uncoveredFiles.some((path, index) => path !== uncoveredFiles[index]))
|
|
92
|
+
return false;
|
|
93
|
+
const fileCoverageRate = value.filesTotal > 0
|
|
94
|
+
? Number((filesCovered / value.filesTotal).toFixed(2))
|
|
95
|
+
: 0;
|
|
96
|
+
const grepBonus = value.grepPatternsUsed > 0
|
|
97
|
+
? Math.min(1, value.grepPatternsUsed / Math.max(5, value.filesTotal))
|
|
98
|
+
: 0;
|
|
99
|
+
const overallRate = Number((fileCoverageRate * 0.6 + grepBonus * 0.4).toFixed(2));
|
|
100
|
+
return value.fileCoverageRate === fileCoverageRate
|
|
101
|
+
&& value.overallRate === overallRate;
|
|
102
|
+
}
|
|
103
|
+
function isGapSignal(value) {
|
|
104
|
+
return isRecord(value)
|
|
105
|
+
&& typeof value.sampleId === 'string'
|
|
106
|
+
&& value.sampleId.length > 0
|
|
107
|
+
&& (value.type === 'failed_search'
|
|
108
|
+
|| value.type === 'explicit_marker'
|
|
109
|
+
|| value.type === 'hedging'
|
|
110
|
+
|| value.type === 'repeated_failure')
|
|
111
|
+
&& (value.turn === undefined || isNonNegativeInteger(value.turn))
|
|
112
|
+
&& typeof value.context === 'string'
|
|
113
|
+
&& (value.evidence === undefined || (isRecord(value.evidence) && isJsonValue(value.evidence)))
|
|
114
|
+
&& isRate(value.weight)
|
|
115
|
+
&& (value.classifierVerdict === undefined
|
|
116
|
+
|| (isRecord(value.classifierVerdict)
|
|
117
|
+
&& typeof value.classifierVerdict.isUncertainty === 'boolean'
|
|
118
|
+
&& isRate(value.classifierVerdict.confidence)
|
|
119
|
+
&& typeof value.classifierVerdict.reason === 'string'));
|
|
120
|
+
}
|
|
121
|
+
function isGapReport(value, variant, successfulSampleIds) {
|
|
122
|
+
const sampleCount = successfulSampleIds.size;
|
|
123
|
+
if (!isRecord(value)
|
|
124
|
+
|| value.variant !== variant
|
|
125
|
+
|| value.sampleCount !== sampleCount
|
|
126
|
+
|| !isNonNegativeInteger(value.samplesWithGap)
|
|
127
|
+
|| value.samplesWithGap > sampleCount
|
|
128
|
+
|| !isRate(value.gapRate)
|
|
129
|
+
|| !isRate(value.weightedGapRate)
|
|
130
|
+
|| value.weightedGapRate > value.gapRate
|
|
131
|
+
|| (value.testSetPath !== undefined
|
|
132
|
+
&& value.testSetPath !== null
|
|
133
|
+
&& typeof value.testSetPath !== 'string')
|
|
134
|
+
|| (value.testSetHash !== undefined
|
|
135
|
+
&& value.testSetHash !== null
|
|
136
|
+
&& typeof value.testSetHash !== 'string')
|
|
137
|
+
|| !Array.isArray(value.signals)
|
|
138
|
+
|| !value.signals.every(isGapSignal)
|
|
139
|
+
|| value.signals.some((signal) => isRecord(signal)
|
|
140
|
+
&& typeof signal.sampleId === 'string'
|
|
141
|
+
&& !successfulSampleIds.has(signal.sampleId))
|
|
142
|
+
|| !isRecord(value.byType)
|
|
143
|
+
|| !hasExactKeys(value.byType, [
|
|
144
|
+
'failed_search',
|
|
145
|
+
'explicit_marker',
|
|
146
|
+
'hedging',
|
|
147
|
+
'repeated_failure',
|
|
148
|
+
])
|
|
149
|
+
|| !Object.values(value.byType).every(isNonNegativeInteger))
|
|
150
|
+
return false;
|
|
151
|
+
const sampleWeights = new Map();
|
|
152
|
+
for (const signal of value.signals) {
|
|
153
|
+
sampleWeights.set(signal.sampleId, Math.max(sampleWeights.get(signal.sampleId) ?? 0, signal.weight));
|
|
154
|
+
}
|
|
155
|
+
if (value.samplesWithGap !== sampleWeights.size)
|
|
156
|
+
return false;
|
|
157
|
+
const expectedRate = sampleCount > 0
|
|
158
|
+
? Number((value.samplesWithGap / sampleCount).toFixed(4))
|
|
159
|
+
: 0;
|
|
160
|
+
if (Math.abs(value.gapRate - expectedRate) > 1e-9)
|
|
161
|
+
return false;
|
|
162
|
+
const expectedWeightedRate = sampleCount > 0
|
|
163
|
+
? Number(([...sampleWeights.values()].reduce((sum, weight) => sum + weight, 0)
|
|
164
|
+
/ sampleCount).toFixed(4))
|
|
165
|
+
: 0;
|
|
166
|
+
if (Math.abs(value.weightedGapRate - expectedWeightedRate) > 1e-9)
|
|
167
|
+
return false;
|
|
168
|
+
const observedByType = {
|
|
169
|
+
failed_search: 0,
|
|
170
|
+
explicit_marker: 0,
|
|
171
|
+
hedging: 0,
|
|
172
|
+
repeated_failure: 0,
|
|
173
|
+
};
|
|
174
|
+
for (const signal of value.signals) {
|
|
175
|
+
observedByType[signal.type]++;
|
|
176
|
+
}
|
|
177
|
+
return Object.entries(observedByType).every(([type, count]) => value.byType[type] === count);
|
|
178
|
+
}
|
|
179
|
+
function isSampleQuality(value, sampleCount) {
|
|
180
|
+
if (!isRecord(value)
|
|
181
|
+
|| !isCountRecord(value.capabilityCoverage)
|
|
182
|
+
|| !isRecord(value.difficultyDistribution)
|
|
183
|
+
|| !hasExactKeys(value.difficultyDistribution, ['easy', 'medium', 'hard', 'unspecified'])
|
|
184
|
+
|| !Object.values(value.difficultyDistribution).every(isNonNegativeInteger)
|
|
185
|
+
|| !isCountRecord(value.constructDistribution)
|
|
186
|
+
|| !isCountRecord(value.provenanceBreakdown)
|
|
187
|
+
|| !isNonNegativeInteger(value.avgRubricLength)
|
|
188
|
+
|| !isNonNegativeInteger(value.sampleCountWithCapability)
|
|
189
|
+
|| !isNonNegativeInteger(value.sampleCountWithDifficulty)
|
|
190
|
+
|| !isNonNegativeInteger(value.sampleCountWithConstruct)
|
|
191
|
+
|| !isNonNegativeInteger(value.sampleCountWithProvenance)
|
|
192
|
+
|| value.sampleCountWithCapability > sampleCount
|
|
193
|
+
|| value.sampleCountWithDifficulty > sampleCount
|
|
194
|
+
|| value.sampleCountWithConstruct > sampleCount
|
|
195
|
+
|| value.sampleCountWithProvenance > sampleCount
|
|
196
|
+
|| safeCountSum(value.difficultyDistribution) !== sampleCount
|
|
197
|
+
|| safeCountSum(value.constructDistribution) !== sampleCount
|
|
198
|
+
|| safeCountSum(value.provenanceBreakdown) !== sampleCount)
|
|
199
|
+
return false;
|
|
200
|
+
const capabilityCoverage = value.capabilityCoverage;
|
|
201
|
+
const sampleCountWithCapability = value.sampleCountWithCapability;
|
|
202
|
+
const capabilityCounts = Object.values(capabilityCoverage);
|
|
203
|
+
const capabilityTagCount = safeCountSum(capabilityCoverage);
|
|
204
|
+
if (capabilityCounts.some((count) => count <= 0 || count > sampleCountWithCapability)
|
|
205
|
+
|| (sampleCountWithCapability === 0
|
|
206
|
+
? capabilityTagCount !== 0
|
|
207
|
+
: capabilityTagCount === undefined
|
|
208
|
+
|| capabilityTagCount < sampleCountWithCapability))
|
|
209
|
+
return false;
|
|
210
|
+
const difficulty = value.difficultyDistribution;
|
|
211
|
+
const construct = value.constructDistribution;
|
|
212
|
+
const provenance = value.provenanceBreakdown;
|
|
213
|
+
const allowedProvenance = new Set([
|
|
214
|
+
'human',
|
|
215
|
+
'llm-generated',
|
|
216
|
+
'production-trace',
|
|
217
|
+
'unspecified',
|
|
218
|
+
]);
|
|
219
|
+
if (value.sampleCountWithDifficulty
|
|
220
|
+
!== difficulty.easy + difficulty.medium + difficulty.hard
|
|
221
|
+
|| value.sampleCountWithConstruct
|
|
222
|
+
!== sampleCount - (construct.unspecified ?? 0)
|
|
223
|
+
|| value.sampleCountWithProvenance
|
|
224
|
+
!== sampleCount - (provenance.unspecified ?? 0)
|
|
225
|
+
|| Object.keys(provenance).some((key) => !allowedProvenance.has(key)))
|
|
226
|
+
return false;
|
|
227
|
+
if (value.representativeness === undefined)
|
|
228
|
+
return true;
|
|
229
|
+
const rep = value.representativeness;
|
|
230
|
+
if (!isRecord(rep)
|
|
231
|
+
|| !isNonNegativeInteger(rep.capabilityCount)
|
|
232
|
+
|| rep.capabilityCount !== Object.keys(capabilityCoverage).length)
|
|
233
|
+
return false;
|
|
234
|
+
if (!isRate(rep.capabilityConcentration)
|
|
235
|
+
|| (rep.dominantCapability !== undefined && typeof rep.dominantCapability !== 'string')
|
|
236
|
+
|| !isRate(rep.difficultyConcentration)
|
|
237
|
+
|| !(rep.dominantDifficulty === undefined
|
|
238
|
+
|| rep.dominantDifficulty === 'easy'
|
|
239
|
+
|| rep.dominantDifficulty === 'medium'
|
|
240
|
+
|| rep.dominantDifficulty === 'hard')
|
|
241
|
+
|| !isRate(rep.constructConcentration)
|
|
242
|
+
|| (rep.dominantConstruct !== undefined && typeof rep.dominantConstruct !== 'string'))
|
|
243
|
+
return false;
|
|
244
|
+
const [dominantCapability, capabilityConcentration] = dominantShare(capabilityCoverage);
|
|
245
|
+
const [dominantDifficulty, difficultyConcentration] = dominantShare({
|
|
246
|
+
easy: difficulty.easy,
|
|
247
|
+
medium: difficulty.medium,
|
|
248
|
+
hard: difficulty.hard,
|
|
249
|
+
});
|
|
250
|
+
const declaredConstruct = Object.fromEntries(Object.entries(construct).filter(([key]) => key !== 'unspecified'));
|
|
251
|
+
const [dominantConstruct, constructConcentration] = dominantShare(declaredConstruct);
|
|
252
|
+
return rep.dominantCapability === dominantCapability
|
|
253
|
+
&& closeTo(rep.capabilityConcentration, capabilityConcentration, 1e-12)
|
|
254
|
+
&& rep.dominantDifficulty === dominantDifficulty
|
|
255
|
+
&& closeTo(rep.difficultyConcentration, difficultyConcentration, 1e-12)
|
|
256
|
+
&& rep.dominantConstruct === dominantConstruct
|
|
257
|
+
&& closeTo(rep.constructConcentration, constructConcentration, 1e-12);
|
|
258
|
+
}
|
|
259
|
+
function dominantShare(counts) {
|
|
260
|
+
let label;
|
|
261
|
+
let max = 0;
|
|
262
|
+
let total = 0;
|
|
263
|
+
for (const [key, count] of Object.entries(counts)) {
|
|
264
|
+
total += count;
|
|
265
|
+
if (!Number.isSafeInteger(total))
|
|
266
|
+
return [undefined, Number.NaN];
|
|
267
|
+
if (count > max) {
|
|
268
|
+
max = count;
|
|
269
|
+
label = key;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return total > 0 ? [label, max / total] : [undefined, 0];
|
|
273
|
+
}
|
|
274
|
+
function isHoldout(value, variants, sampleCount) {
|
|
275
|
+
if (!isRecord(value)
|
|
276
|
+
|| !isRate(value.ratio)
|
|
277
|
+
|| value.ratio <= 0
|
|
278
|
+
|| value.ratio >= 1
|
|
279
|
+
|| (value.disabled !== undefined && typeof value.disabled !== 'boolean')
|
|
280
|
+
|| !isRecord(value.perVariant)
|
|
281
|
+
|| (value.testSetPath !== undefined
|
|
282
|
+
&& value.testSetPath !== null
|
|
283
|
+
&& typeof value.testSetPath !== 'string')
|
|
284
|
+
|| (value.testSetHash !== undefined
|
|
285
|
+
&& value.testSetHash !== null
|
|
286
|
+
&& typeof value.testSetHash !== 'string'))
|
|
287
|
+
return false;
|
|
288
|
+
if (value.disabled === true)
|
|
289
|
+
return Object.keys(value.perVariant).length === 0;
|
|
290
|
+
if (!hasExactKeys(value.perVariant, variants))
|
|
291
|
+
return false;
|
|
292
|
+
return Object.values(value.perVariant).every((entry) => isRecord(entry)
|
|
293
|
+
&& isScore(entry.trainScore)
|
|
294
|
+
&& isScore(entry.holdoutScore)
|
|
295
|
+
&& isNonNegativeInteger(entry.trainCount)
|
|
296
|
+
&& isNonNegativeInteger(entry.holdoutCount)
|
|
297
|
+
&& entry.trainCount + entry.holdoutCount === sampleCount
|
|
298
|
+
&& isNonNegativeInteger(entry.trainScorable)
|
|
299
|
+
&& isNonNegativeInteger(entry.holdoutScorable)
|
|
300
|
+
&& entry.trainScorable <= entry.trainCount
|
|
301
|
+
&& entry.holdoutScorable <= entry.holdoutCount);
|
|
302
|
+
}
|
|
303
|
+
export function isAnalysisResult(value, variants, results) {
|
|
304
|
+
const sampleCount = results.length;
|
|
305
|
+
if (!isRecord(value)
|
|
306
|
+
|| (value.summary !== undefined && typeof value.summary !== 'string')
|
|
307
|
+
|| !Array.isArray(value.insights)
|
|
308
|
+
|| !value.insights.every((insight) => isRecord(insight)
|
|
309
|
+
&& typeof insight.type === 'string'
|
|
310
|
+
&& insight.type.length > 0
|
|
311
|
+
&& (insight.severity === 'error'
|
|
312
|
+
|| insight.severity === 'warning'
|
|
313
|
+
|| insight.severity === 'info')
|
|
314
|
+
&& isJsonValue(insight.details))
|
|
315
|
+
|| (value.suggestions !== undefined
|
|
316
|
+
&& (!Array.isArray(value.suggestions)
|
|
317
|
+
|| !value.suggestions.every((suggestion) => typeof suggestion === 'string')))
|
|
318
|
+
|| (value.coverage !== undefined
|
|
319
|
+
&& (!isRecord(value.coverage)
|
|
320
|
+
|| !hasOnlyKeys(value.coverage, variants)
|
|
321
|
+
|| !Object.values(value.coverage).every(isCoverage)))
|
|
322
|
+
|| (value.gapReports !== undefined
|
|
323
|
+
&& (!isRecord(value.gapReports)
|
|
324
|
+
|| !hasOnlyKeys(value.gapReports, variants)
|
|
325
|
+
|| !Object.entries(value.gapReports).every(([variant, report]) => isGapReport(report, variant, new Set(results
|
|
326
|
+
.filter((entry) => entry.variants[variant]?.ok === true)
|
|
327
|
+
.map((entry) => entry.sample_id))))))
|
|
328
|
+
|| (value.sampleQuality !== undefined
|
|
329
|
+
&& !isSampleQuality(value.sampleQuality, sampleCount))
|
|
330
|
+
|| (value.holdout !== undefined
|
|
331
|
+
&& !isHoldout(value.holdout, variants, sampleCount)))
|
|
332
|
+
return false;
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
function mean(values) {
|
|
336
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
337
|
+
}
|
|
338
|
+
function sampleStddev(values) {
|
|
339
|
+
if (values.length < 2)
|
|
340
|
+
return 0;
|
|
341
|
+
const avg = mean(values);
|
|
342
|
+
const variance = values.reduce((sum, value) => sum + (value - avg) ** 2, 0)
|
|
343
|
+
/ (values.length - 1);
|
|
344
|
+
return Math.sqrt(variance);
|
|
345
|
+
}
|
|
346
|
+
function closeTo(left, right, tolerance = 1e-4) {
|
|
347
|
+
return Math.abs(left - right) <= tolerance;
|
|
348
|
+
}
|
|
349
|
+
function isVarianceMetric(value, runs, scoreDomain) {
|
|
350
|
+
if (!isRecord(value)
|
|
351
|
+
|| !Array.isArray(value.scores)
|
|
352
|
+
|| value.scores.length === 0
|
|
353
|
+
|| value.scores.length > runs
|
|
354
|
+
|| !value.scores.every(scoreDomain ? isScore : isNonNegativeNumber)
|
|
355
|
+
|| !isFiniteNumber(value.mean)
|
|
356
|
+
|| !isFiniteNumber(value.lower)
|
|
357
|
+
|| !isFiniteNumber(value.upper)
|
|
358
|
+
|| value.lower > value.mean
|
|
359
|
+
|| value.mean > value.upper
|
|
360
|
+
|| !isNonNegativeNumber(value.stddev))
|
|
361
|
+
return false;
|
|
362
|
+
return closeTo(value.mean, Number(mean(value.scores).toFixed(4)))
|
|
363
|
+
&& closeTo(value.stddev, Number(sampleStddev(value.scores).toFixed(4)));
|
|
364
|
+
}
|
|
365
|
+
function isEffectSize(value, leftCount, rightCount) {
|
|
366
|
+
return isRecord(value)
|
|
367
|
+
&& isFiniteNumber(value.cohensD)
|
|
368
|
+
&& isFiniteNumber(value.hedgesG)
|
|
369
|
+
&& (value.primary === 'd'
|
|
370
|
+
|| value.primary === 'g'
|
|
371
|
+
|| value.primary === 'none')
|
|
372
|
+
&& (value.magnitude === 'negligible'
|
|
373
|
+
|| value.magnitude === 'small'
|
|
374
|
+
|| value.magnitude === 'medium'
|
|
375
|
+
|| value.magnitude === 'large'
|
|
376
|
+
|| value.magnitude === 'none')
|
|
377
|
+
&& isNonNegativeNumber(value.pooledStddev)
|
|
378
|
+
&& value.n1 === leftCount
|
|
379
|
+
&& value.n2 === rightCount;
|
|
380
|
+
}
|
|
381
|
+
function isVarianceComparisonMetric(value, left, right) {
|
|
382
|
+
return isRecord(value)
|
|
383
|
+
&& isFiniteNumber(value.meanDiff)
|
|
384
|
+
&& closeTo(value.meanDiff, Number((left.mean - right.mean).toFixed(4)))
|
|
385
|
+
&& isFiniteNumber(value.tStatistic)
|
|
386
|
+
&& isNonNegativeInteger(value.df)
|
|
387
|
+
&& typeof value.significant === 'boolean'
|
|
388
|
+
&& isEffectSize(value.effectSize, left.scores.length, right.scores.length);
|
|
389
|
+
}
|
|
390
|
+
function metricMapIsValid(value, keys, runs, scoreDomain) {
|
|
391
|
+
return isRecord(value)
|
|
392
|
+
&& hasOnlyKeys(value, keys)
|
|
393
|
+
&& Object.values(value).every((metric) => isVarianceMetric(metric, runs, scoreDomain));
|
|
394
|
+
}
|
|
395
|
+
function comparisonMetricMapIsValid(value, keys, left, right) {
|
|
396
|
+
if (!isRecord(value) || !hasOnlyKeys(value, keys))
|
|
397
|
+
return false;
|
|
398
|
+
return Object.entries(value).every(([key, metric]) => {
|
|
399
|
+
const leftMetric = left?.[key];
|
|
400
|
+
const rightMetric = right?.[key];
|
|
401
|
+
return leftMetric !== undefined
|
|
402
|
+
&& rightMetric !== undefined
|
|
403
|
+
&& isVarianceComparisonMetric(metric, leftMetric, rightMetric);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
function isSaturation(value, variants, runs) {
|
|
407
|
+
if (!isRecord(value)
|
|
408
|
+
|| !Array.isArray(value.checkpointSampleCounts)
|
|
409
|
+
|| value.checkpointSampleCounts.length !== runs
|
|
410
|
+
|| !value.checkpointSampleCounts.every(isNonNegativeInteger)
|
|
411
|
+
|| value.checkpointSampleCounts.some((count, index, all) => index > 0 && count < all[index - 1])
|
|
412
|
+
|| !isRecord(value.perVariant)
|
|
413
|
+
|| !hasExactKeys(value.perVariant, variants))
|
|
414
|
+
return false;
|
|
415
|
+
const checkpointSampleCounts = value.checkpointSampleCounts;
|
|
416
|
+
for (const traces of Object.values(value.perVariant)) {
|
|
417
|
+
if (!Array.isArray(traces)
|
|
418
|
+
|| traces.length !== runs
|
|
419
|
+
|| traces.some((trace, index, all) => isRecord(trace)
|
|
420
|
+
&& index > 0
|
|
421
|
+
&& isRecord(all[index - 1])
|
|
422
|
+
&& isNonNegativeInteger(trace.n)
|
|
423
|
+
&& isNonNegativeInteger(all[index - 1].n)
|
|
424
|
+
&& trace.n < all[index - 1].n)
|
|
425
|
+
|| !traces.every((trace) => isRecord(trace)
|
|
426
|
+
&& isNonNegativeInteger(trace.n)
|
|
427
|
+
&& isScore(trace.mean)
|
|
428
|
+
&& isScore(trace.ciLow)
|
|
429
|
+
&& isScore(trace.ciHigh)
|
|
430
|
+
&& trace.ciLow <= trace.mean
|
|
431
|
+
&& trace.mean <= trace.ciHigh))
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
if (value.verdicts === undefined)
|
|
435
|
+
return true;
|
|
436
|
+
if (runs < 5
|
|
437
|
+
|| !isRecord(value.verdicts)
|
|
438
|
+
|| !hasOnlyKeys(value.verdicts, variants))
|
|
439
|
+
return false;
|
|
440
|
+
return Object.values(value.verdicts).every((verdict) => isRecord(verdict)
|
|
441
|
+
&& typeof verdict.saturated === 'boolean'
|
|
442
|
+
&& (verdict.atN === null
|
|
443
|
+
|| (Number.isSafeInteger(verdict.atN)
|
|
444
|
+
&& verdict.atN > 0
|
|
445
|
+
&& verdict.atN <= (checkpointSampleCounts.at(-1) ?? 0)))
|
|
446
|
+
&& (verdict.confidence === 'high'
|
|
447
|
+
|| verdict.confidence === 'medium'
|
|
448
|
+
|| verdict.confidence === 'low')
|
|
449
|
+
&& (verdict.method === 'slope'
|
|
450
|
+
|| verdict.method === 'bootstrap-ci-width'
|
|
451
|
+
|| verdict.method === 'plateau-height')
|
|
452
|
+
&& isNonNegativeNumber(verdict.threshold)
|
|
453
|
+
&& typeof verdict.reason === 'string');
|
|
454
|
+
}
|
|
455
|
+
export function isVarianceData(value, variants) {
|
|
456
|
+
if (!isRecord(value)
|
|
457
|
+
|| !Number.isSafeInteger(value.runs)
|
|
458
|
+
|| value.runs < 2
|
|
459
|
+
|| !isRecord(value.perVariant)
|
|
460
|
+
|| !hasOnlyKeys(value.perVariant, variants))
|
|
461
|
+
return false;
|
|
462
|
+
const runs = value.runs;
|
|
463
|
+
for (const variant of Object.values(value.perVariant)) {
|
|
464
|
+
const extended = variant;
|
|
465
|
+
if (!isVarianceMetric(variant, runs, true)
|
|
466
|
+
|| (extended.byMetric !== undefined
|
|
467
|
+
&& !metricMapIsValid(extended.byMetric, ['cost', 'efficiency'], runs, false))
|
|
468
|
+
|| (extended.byLayer !== undefined
|
|
469
|
+
&& !metricMapIsValid(extended.byLayer, ['fact', 'behavior', 'judge'], runs, true)))
|
|
470
|
+
return false;
|
|
471
|
+
}
|
|
472
|
+
if (!Array.isArray(value.comparisons))
|
|
473
|
+
return false;
|
|
474
|
+
const pairs = new Set();
|
|
475
|
+
for (const comparison of value.comparisons) {
|
|
476
|
+
if (!isRecord(comparison)
|
|
477
|
+
|| typeof comparison.a !== 'string'
|
|
478
|
+
|| typeof comparison.b !== 'string'
|
|
479
|
+
|| comparison.a === comparison.b
|
|
480
|
+
|| !variants.includes(comparison.a)
|
|
481
|
+
|| !variants.includes(comparison.b))
|
|
482
|
+
return false;
|
|
483
|
+
const pair = [comparison.a, comparison.b].sort().join('\u0000');
|
|
484
|
+
if (pairs.has(pair))
|
|
485
|
+
return false;
|
|
486
|
+
pairs.add(pair);
|
|
487
|
+
const left = value.perVariant[comparison.a];
|
|
488
|
+
const right = value.perVariant[comparison.b];
|
|
489
|
+
if (!left
|
|
490
|
+
|| !right
|
|
491
|
+
|| !isVarianceComparisonMetric(comparison, left, right)
|
|
492
|
+
|| (comparison.byMetric !== undefined
|
|
493
|
+
&& !comparisonMetricMapIsValid(comparison.byMetric, ['cost', 'efficiency'], left.byMetric, right.byMetric))
|
|
494
|
+
|| (comparison.byLayer !== undefined
|
|
495
|
+
&& !comparisonMetricMapIsValid(comparison.byLayer, ['fact', 'behavior', 'judge'], left.byLayer, right.byLayer)))
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
return value.saturation === undefined
|
|
499
|
+
|| isSaturation(value.saturation, variants, runs);
|
|
500
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readdirSync, readFileSync, renameSync, unlinkSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
3
4
|
import { doctorReportFileStem, isReportFileName, reportFilePath, stripDomainPrefix } from './artifact-file-names.js';
|
|
4
5
|
function legacyJsonStem(fileName) {
|
|
5
6
|
if (!fileName.endsWith('.json'))
|
|
@@ -66,8 +67,10 @@ export function migrateLegacyReportFiles(dir, domain) {
|
|
|
66
67
|
continue;
|
|
67
68
|
const sourcePath = join(dir, file);
|
|
68
69
|
let targetStem = null;
|
|
70
|
+
let sourceData;
|
|
69
71
|
try {
|
|
70
|
-
|
|
72
|
+
sourceData = JSON.parse(readFileSync(sourcePath, 'utf-8'));
|
|
73
|
+
targetStem = targetStemForLegacyReport(domain, file, sourceData);
|
|
71
74
|
}
|
|
72
75
|
catch {
|
|
73
76
|
continue;
|
|
@@ -77,7 +80,9 @@ export function migrateLegacyReportFiles(dir, domain) {
|
|
|
77
80
|
const targetPath = reportFilePath(dir, targetStem);
|
|
78
81
|
try {
|
|
79
82
|
if (existsSync(targetPath)) {
|
|
80
|
-
|
|
83
|
+
const targetData = JSON.parse(readFileSync(targetPath, 'utf-8'));
|
|
84
|
+
if (isDeepStrictEqual(sourceData, targetData))
|
|
85
|
+
unlinkSync(sourcePath);
|
|
81
86
|
}
|
|
82
87
|
else {
|
|
83
88
|
renameSync(sourcePath, targetPath);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Artifact, EvalBudget, JudgeConfig, Report, Sample, Task } from '../types/index.js';
|
|
2
|
+
export interface ResumeCompatibilityInput {
|
|
3
|
+
variants: string[];
|
|
4
|
+
model: string;
|
|
5
|
+
executorName: string;
|
|
6
|
+
effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
7
|
+
noJudge: boolean;
|
|
8
|
+
judgeModels: JudgeConfig[];
|
|
9
|
+
judgeRepeat?: number;
|
|
10
|
+
lengthDebias?: boolean;
|
|
11
|
+
budget?: EvalBudget;
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
retry?: number;
|
|
14
|
+
noDiagnostic?: boolean;
|
|
15
|
+
skillDir: string;
|
|
16
|
+
samples: Sample[];
|
|
17
|
+
samplesBaseDir?: string;
|
|
18
|
+
tasks: Task[];
|
|
19
|
+
artifacts: Artifact[];
|
|
20
|
+
}
|
|
21
|
+
export interface ResumeCompatibilityResult {
|
|
22
|
+
compatible: boolean;
|
|
23
|
+
mismatches: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Decide whether successful entries from an earlier report can be inserted
|
|
27
|
+
* into the current measurement without mixing protocols. Every value compared
|
|
28
|
+
* here is either the report's public measurement evidence or a request option
|
|
29
|
+
* that can alter a persisted VariantResult.
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkResumeCompatibility(report: Report, current: ResumeCompatibilityInput): ResumeCompatibilityResult;
|