oh-my-knowledge 0.26.0 → 0.27.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 +109 -347
- package/README.zh.md +146 -376
- package/dist/src/analysis/report-diagnostics.d.ts +1 -1
- package/dist/src/analysis/report-diagnostics.js +1 -1
- package/dist/src/analysis/sample-diagnostics.d.ts +2 -2
- package/dist/src/analysis/sample-diagnostics.js +2 -2
- package/dist/src/authoring/generator.d.ts.map +1 -1
- package/dist/src/authoring/generator.js +9 -8
- package/dist/src/authoring/generator.js.map +1 -1
- package/dist/src/cli/cli-exit.d.ts +15 -0
- package/dist/src/cli/cli-exit.d.ts.map +1 -0
- package/dist/src/cli/cli-exit.js +19 -0
- package/dist/src/cli/cli-exit.js.map +1 -0
- package/dist/src/cli/commands/_shared.d.ts +12 -0
- package/dist/src/cli/commands/_shared.d.ts.map +1 -0
- package/dist/src/cli/commands/_shared.js +26 -0
- package/dist/src/cli/commands/_shared.js.map +1 -0
- package/dist/src/cli/commands/doctor.d.ts +2 -0
- package/dist/src/cli/commands/doctor.d.ts.map +1 -0
- package/dist/src/cli/commands/doctor.js +137 -0
- package/dist/src/cli/commands/doctor.js.map +1 -0
- package/dist/src/cli/commands/eval-debias.d.ts +2 -0
- package/dist/src/cli/commands/eval-debias.d.ts.map +1 -0
- package/dist/src/cli/commands/eval-debias.js +88 -0
- package/dist/src/cli/commands/eval-debias.js.map +1 -0
- package/dist/src/cli/commands/eval-gold.d.ts +2 -0
- package/dist/src/cli/commands/eval-gold.d.ts.map +1 -0
- package/dist/src/cli/commands/eval-gold.js +137 -0
- package/dist/src/cli/commands/eval-gold.js.map +1 -0
- package/dist/src/cli/commands/eval-runner.d.ts +2 -0
- package/dist/src/cli/commands/eval-runner.d.ts.map +1 -0
- package/dist/src/cli/commands/eval-runner.js +299 -0
- package/dist/src/cli/commands/eval-runner.js.map +1 -0
- package/dist/src/cli/commands/eval.d.ts +2 -0
- package/dist/src/cli/commands/eval.d.ts.map +1 -0
- package/dist/src/cli/commands/eval.js +16 -0
- package/dist/src/cli/commands/eval.js.map +1 -0
- package/dist/src/cli/commands/export-diff.d.ts +2 -0
- package/dist/src/cli/commands/export-diff.d.ts.map +1 -0
- package/dist/src/cli/commands/export-diff.js +177 -0
- package/dist/src/cli/commands/export-diff.js.map +1 -0
- package/dist/src/cli/commands/export-saturation.d.ts +2 -0
- package/dist/src/cli/commands/export-saturation.d.ts.map +1 -0
- package/dist/src/cli/commands/export-saturation.js +59 -0
- package/dist/src/cli/commands/export-saturation.js.map +1 -0
- package/dist/src/cli/commands/export-verdict.d.ts +2 -0
- package/dist/src/cli/commands/export-verdict.d.ts.map +1 -0
- package/dist/src/cli/commands/export-verdict.js +45 -0
- package/dist/src/cli/commands/export-verdict.js.map +1 -0
- package/dist/src/cli/commands/export.d.ts +2 -0
- package/dist/src/cli/commands/export.d.ts.map +1 -0
- package/dist/src/cli/commands/export.js +150 -0
- package/dist/src/cli/commands/export.js.map +1 -0
- package/dist/src/cli/commands/improve-failures.d.ts +2 -0
- package/dist/src/cli/commands/improve-failures.d.ts.map +1 -0
- package/dist/src/cli/commands/improve-failures.js +59 -0
- package/dist/src/cli/commands/improve-failures.js.map +1 -0
- package/dist/src/cli/commands/improve-plan.d.ts +2 -0
- package/dist/src/cli/commands/improve-plan.d.ts.map +1 -0
- package/dist/src/cli/commands/improve-plan.js +75 -0
- package/dist/src/cli/commands/improve-plan.js.map +1 -0
- package/dist/src/cli/commands/improve-samples.d.ts +2 -0
- package/dist/src/cli/commands/improve-samples.d.ts.map +1 -0
- package/dist/src/cli/commands/improve-samples.js +120 -0
- package/dist/src/cli/commands/improve-samples.js.map +1 -0
- package/dist/src/cli/commands/improve-skill.d.ts +2 -0
- package/dist/src/cli/commands/improve-skill.d.ts.map +1 -0
- package/dist/src/cli/commands/improve-skill.js +115 -0
- package/dist/src/cli/commands/improve-skill.js.map +1 -0
- package/dist/src/cli/commands/improve.d.ts +2 -0
- package/dist/src/cli/commands/improve.d.ts.map +1 -0
- package/dist/src/cli/commands/improve.js +34 -0
- package/dist/src/cli/commands/improve.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts +2 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -0
- package/dist/src/cli/commands/init.js +110 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/observe.d.ts +2 -0
- package/dist/src/cli/commands/observe.d.ts.map +1 -0
- package/dist/src/cli/commands/observe.js +77 -0
- package/dist/src/cli/commands/observe.js.map +1 -0
- package/dist/src/cli/commands/registry.d.ts +11 -0
- package/dist/src/cli/commands/registry.d.ts.map +1 -0
- package/dist/src/cli/commands/registry.js +42 -0
- package/dist/src/cli/commands/registry.js.map +1 -0
- package/dist/src/cli/commands/studio.d.ts +2 -0
- package/dist/src/cli/commands/studio.d.ts.map +1 -0
- package/dist/src/cli/commands/studio.js +76 -0
- package/dist/src/cli/commands/studio.js.map +1 -0
- package/dist/src/cli/coverage-renderer.d.ts +1 -1
- package/dist/src/cli/coverage-renderer.js +1 -1
- package/dist/src/cli/i18n-dict.d.ts +4 -4
- package/dist/src/cli/i18n-dict.d.ts.map +1 -1
- package/dist/src/cli/i18n-dict.js +558 -564
- package/dist/src/cli/i18n-dict.js.map +1 -1
- package/dist/src/cli/index.js +43 -1516
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/parse-run-config.d.ts +3 -4
- package/dist/src/cli/parse-run-config.d.ts.map +1 -1
- package/dist/src/cli/parse-run-config.js +5 -5
- package/dist/src/cli/parse-run-config.js.map +1 -1
- package/dist/src/cli/parse-strict.d.ts +0 -13
- package/dist/src/cli/parse-strict.d.ts.map +1 -1
- package/dist/src/cli/parse-strict.js +2 -1
- package/dist/src/cli/parse-strict.js.map +1 -1
- package/dist/src/doctor/index.d.ts +1 -1
- package/dist/src/doctor/index.js +2 -2
- package/dist/src/doctor/index.js.map +1 -1
- package/dist/src/doctor/preflight.d.ts +2 -2
- package/dist/src/doctor/preflight.js +2 -2
- package/dist/src/eval-core/fact-checker.js +1 -1
- package/dist/src/eval-core/fact-checker.js.map +1 -1
- package/dist/src/eval-core/layer-gates.d.ts +1 -1
- package/dist/src/eval-core/layer-gates.js +1 -1
- package/dist/src/eval-core/verdict.d.ts +4 -4
- package/dist/src/eval-core/verdict.d.ts.map +1 -1
- package/dist/src/eval-core/verdict.js +2 -2
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts +15 -2
- package/dist/src/eval-workflows/batch-evaluation-workflow.d.ts.map +1 -1
- package/dist/src/eval-workflows/batch-evaluation-workflow.js +13 -2
- package/dist/src/eval-workflows/batch-evaluation-workflow.js.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts +6 -3
- package/dist/src/eval-workflows/evaluation-pipeline.d.ts.map +1 -1
- package/dist/src/eval-workflows/evaluation-pipeline.js +10 -9
- package/dist/src/eval-workflows/evaluation-pipeline.js.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts +1 -1
- package/dist/src/eval-workflows/run-evaluation.d.ts.map +1 -1
- package/dist/src/eval-workflows/run-evaluation.js +13 -6
- package/dist/src/eval-workflows/run-evaluation.js.map +1 -1
- package/dist/src/executors/script.d.ts.map +1 -1
- package/dist/src/executors/script.js +16 -3
- package/dist/src/executors/script.js.map +1 -1
- package/dist/src/grading/debias-validate.d.ts +2 -2
- package/dist/src/grading/debias-validate.js +2 -2
- package/dist/src/grading/gold-cli.d.ts +2 -5
- package/dist/src/grading/gold-cli.d.ts.map +1 -1
- package/dist/src/grading/gold-cli.js +4 -8
- package/dist/src/grading/gold-cli.js.map +1 -1
- package/dist/src/grading/judge.d.ts +1 -1
- package/dist/src/renderer/html-renderer.js +1 -1
- package/dist/src/renderer/layout.js +5 -5
- package/dist/src/renderer/layout.js.map +1 -1
- package/dist/src/renderer/skill-health-renderer.d.ts +1 -1
- package/dist/src/renderer/skill-health-renderer.js +1 -1
- package/dist/src/renderer/summary.js +8 -8
- package/dist/src/server/report-server.d.ts.map +1 -1
- package/dist/src/server/report-server.js +8 -7
- package/dist/src/server/report-server.js.map +1 -1
- package/dist/src/types/doctor.d.ts +3 -3
- package/dist/src/types/eval.d.ts +1 -1
- package/dist/src/types/report.d.ts +1 -1
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ export declare function analyzeResults(report: Report, opts?: AnalyzeResultsOpti
|
|
|
26
26
|
* Missing fields are bucketed under the `unspecified` key in the relevant
|
|
27
27
|
* distribution map, so users see "I have N samples without difficulty declared".
|
|
28
28
|
*
|
|
29
|
-
* Used by `
|
|
29
|
+
* Used by `omk improve` to surface coverage gaps. Does NOT participate
|
|
30
30
|
* in grading / judge / verdict. See docs/sample-design-spec.md.
|
|
31
31
|
*/
|
|
32
32
|
export declare function buildSampleQualityAggregate(samples: Sample[]): SampleQualityAggregate;
|
|
@@ -56,7 +56,7 @@ export function analyzeResults(report, opts = {}) {
|
|
|
56
56
|
* Missing fields are bucketed under the `unspecified` key in the relevant
|
|
57
57
|
* distribution map, so users see "I have N samples without difficulty declared".
|
|
58
58
|
*
|
|
59
|
-
* Used by `
|
|
59
|
+
* Used by `omk improve` to surface coverage gaps. Does NOT participate
|
|
60
60
|
* in grading / judge / verdict. See docs/sample-design-spec.md.
|
|
61
61
|
*/
|
|
62
62
|
export function buildSampleQualityAggregate(samples) {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* (d) are cost / latency outliers (one sample spikes the budget by itself), or
|
|
17
17
|
* (e) fail across the board (likely broken sample, not a model deficiency).
|
|
18
18
|
*
|
|
19
|
-
* The CLI `omk
|
|
19
|
+
* The CLI `omk improve <reportId>` surfaces these so users can iterate
|
|
20
20
|
* the SAMPLE SET as much as they iterate the SKILL.
|
|
21
21
|
*
|
|
22
22
|
* Output shape: a flat list of issues, each tagged with severity and the
|
|
@@ -75,7 +75,7 @@ export declare function normalizeCapability(raw: string): string;
|
|
|
75
75
|
type DiagnosticLang = 'zh' | 'en';
|
|
76
76
|
export declare function formatSampleIssue(issue: SampleIssue, lang?: DiagnosticLang): string;
|
|
77
77
|
/**
|
|
78
|
-
* Plain-text formatter for `omk
|
|
78
|
+
* Plain-text formatter for `omk improve <reportId>`.
|
|
79
79
|
*/
|
|
80
80
|
export declare function formatSampleDiagnostics(diag: SampleDiagnosticReport, options?: {
|
|
81
81
|
topN?: number;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* (d) are cost / latency outliers (one sample spikes the budget by itself), or
|
|
17
17
|
* (e) fail across the board (likely broken sample, not a model deficiency).
|
|
18
18
|
*
|
|
19
|
-
* The CLI `omk
|
|
19
|
+
* The CLI `omk improve <reportId>` surfaces these so users can iterate
|
|
20
20
|
* the SAMPLE SET as much as they iterate the SKILL.
|
|
21
21
|
*
|
|
22
22
|
* Output shape: a flat list of issues, each tagged with severity and the
|
|
@@ -376,7 +376,7 @@ export function formatSampleIssue(issue, lang = 'zh') {
|
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
/**
|
|
379
|
-
* Plain-text formatter for `omk
|
|
379
|
+
* Plain-text formatter for `omk improve <reportId>`.
|
|
380
380
|
*/
|
|
381
381
|
export function formatSampleDiagnostics(diag, options = {}) {
|
|
382
382
|
const lines = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/authoring/generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/authoring/generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AA+BhD,UAAU,sBAAsB;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,EAAE,YAAY,EAAE,KAAS,EAAE,KAAqB,EAAE,YAAuB,EAAE,EAAE,sBAAsB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2C1L;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAoClF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createExecutor, DEFAULT_MODEL } from '../executors/index.js';
|
|
2
|
-
const SYSTEM_PROMPT = `你是一个评测用例生成器。你的任务是根据用户提供的 skill
|
|
2
|
+
const SYSTEM_PROMPT = `你是一个评测用例生成器。你的任务是根据用户提供的 skill(系统提示词)内容,生成高质量的评测用例。
|
|
3
3
|
|
|
4
4
|
每个用例需包含以下字段:
|
|
5
5
|
- sample_id: 唯一标识,格式为 s001, s002, ...
|
|
@@ -7,16 +7,17 @@ const SYSTEM_PROMPT = `你是一个评测用例生成器。你的任务是根据
|
|
|
7
7
|
- context: 可选,附加上下文信息(如代码片段、文档段落等),仅在需要时提供
|
|
8
8
|
- rubric: 评分标准,描述一个好的回答应该具备什么特征(1-2 句话)
|
|
9
9
|
- assertions: 2-3 个断言检查,可选类型:
|
|
10
|
-
- { "type": "contains", "value": "
|
|
11
|
-
- { "type": "not_contains", "value": "
|
|
12
|
-
- { "type": "regex", "pattern": "
|
|
10
|
+
- { "type": "contains", "value": "English keyword or code token", "weight": 1 }
|
|
11
|
+
- { "type": "not_contains", "value": "English phrase that should not appear", "weight": 0.5 }
|
|
12
|
+
- { "type": "regex", "pattern": "English|code|token", "weight": 1 }
|
|
13
13
|
|
|
14
14
|
要求:
|
|
15
|
-
1.
|
|
15
|
+
1. 评测用例应覆盖 skill 的不同能力维度
|
|
16
16
|
2. prompt 要贴近真实用户的使用场景
|
|
17
17
|
3. rubric 要具体,不要泛泛而谈
|
|
18
18
|
4. assertions 要有区分度,能检测出有无 skill 的差异
|
|
19
|
-
5.
|
|
19
|
+
5. assertions 的 value / pattern / values / reference 必须使用英文、数字或代码 token,不要使用中文关键词。
|
|
20
|
+
6. 断言应检测 skill 文档中的具体细节(如特定参数名、配置值、工作流步骤),而非通用知识。
|
|
20
21
|
避免使用 baseline 凭常识或搜索文件也能答对的断言(如 not_contains 通用错误写法)。
|
|
21
22
|
优先使用 contains 检测文档独有的术语、参数组合或特定值
|
|
22
23
|
|
|
@@ -32,7 +33,7 @@ export async function generateSamples({ skillContent, count = 5, model = DEFAULT
|
|
|
32
33
|
|
|
33
34
|
${skillContent}
|
|
34
35
|
|
|
35
|
-
请根据这个 skill 生成 ${count}
|
|
36
|
+
请根据这个 skill 生成 ${count} 个评测用例。直接输出 JSON 数组。`;
|
|
36
37
|
const result = await executor({ model, system: SYSTEM_PROMPT, prompt });
|
|
37
38
|
if (!result.ok) {
|
|
38
39
|
throw new Error(`generation failed: ${result.error || 'unknown error'}`);
|
|
@@ -57,7 +58,7 @@ ${skillContent}
|
|
|
57
58
|
// (see sanitizeGeneratedSamples).
|
|
58
59
|
const { stripped } = sanitizeGeneratedSamples(samples);
|
|
59
60
|
if (stripped.length > 0) {
|
|
60
|
-
process.stderr.write(`[omk
|
|
61
|
+
process.stderr.write(`[omk improve samples] LLM-output 含 ${stripped.length} 个非法元数据字段,已剥离避免污染:\n - ${stripped.join('\n - ')}\n`);
|
|
61
62
|
}
|
|
62
63
|
return { samples, costUSD: result.costUSD };
|
|
63
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/authoring/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtE,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/authoring/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 命令退出信号。execute() / parse-strict / requireEvaluationReport 等想以
|
|
3
|
+
* 特定 exit code 终止时,throw 这个,不要直接 process.exit。
|
|
4
|
+
*
|
|
5
|
+
* dispatcher (`main()` 顶层 catch) 负责把 CliExit 转成 process.exit(code) —
|
|
6
|
+
* 这样 execute() 可以在单测里被 try/catch 捕获,不 kill 整个测试进程。
|
|
7
|
+
*
|
|
8
|
+
* 异步回调内的「子进程 exit code 透传」。
|
|
9
|
+
* 不走这层,继续 process.exit — 那是子进程退出后的 cleanup,不在 main 调用栈。
|
|
10
|
+
*/
|
|
11
|
+
export declare class CliExit extends Error {
|
|
12
|
+
readonly code: number;
|
|
13
|
+
constructor(code: number);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=cli-exit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-exit.d.ts","sourceRoot":"","sources":["../../../src/cli/cli-exit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,qBAAa,OAAQ,SAAQ,KAAK;aACJ,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAIzC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 命令退出信号。execute() / parse-strict / requireEvaluationReport 等想以
|
|
3
|
+
* 特定 exit code 终止时,throw 这个,不要直接 process.exit。
|
|
4
|
+
*
|
|
5
|
+
* dispatcher (`main()` 顶层 catch) 负责把 CliExit 转成 process.exit(code) —
|
|
6
|
+
* 这样 execute() 可以在单测里被 try/catch 捕获,不 kill 整个测试进程。
|
|
7
|
+
*
|
|
8
|
+
* 异步回调内的「子进程 exit code 透传」。
|
|
9
|
+
* 不走这层,继续 process.exit — 那是子进程退出后的 cleanup,不在 main 调用栈。
|
|
10
|
+
*/
|
|
11
|
+
export class CliExit extends Error {
|
|
12
|
+
code;
|
|
13
|
+
constructor(code) {
|
|
14
|
+
super(`CliExit(${code})`);
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.name = 'CliExit';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=cli-exit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-exit.js","sourceRoot":"","sources":["../../../src/cli/cli-exit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK;IACJ;IAA5B,YAA4B,IAAY;QACtC,KAAK,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC;QADA,SAAI,GAAJ,IAAI,CAAQ;QAEtC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CliLang } from '../i18n.js';
|
|
2
|
+
import type { EvaluationReport, ReportDocument } from '../../types/index.js';
|
|
3
|
+
export interface EvalResult {
|
|
4
|
+
report: ReportDocument;
|
|
5
|
+
filePath: string | null;
|
|
6
|
+
}
|
|
7
|
+
export interface ReportServer {
|
|
8
|
+
start: () => Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
export declare function requireEvaluationReport(report: ReportDocument | null, id: string, lang: CliLang): EvaluationReport;
|
|
11
|
+
export declare function parseLastWindow(spec: string): string | null;
|
|
12
|
+
//# sourceMappingURL=_shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/_shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAYlH;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ3D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CliExit } from '../cli-exit.js';
|
|
2
|
+
import { tCli } from '../i18n.js';
|
|
3
|
+
export function requireEvaluationReport(report, id, lang) {
|
|
4
|
+
if (!report) {
|
|
5
|
+
console.error(tCli('cli.common.report_not_found', lang, { id }));
|
|
6
|
+
throw new CliExit(1);
|
|
7
|
+
}
|
|
8
|
+
if (report.kind === 'batch-evaluation') {
|
|
9
|
+
console.error(lang === 'zh'
|
|
10
|
+
? `报告 ${id} 是 BatchEvaluationReport。该命令需要单次 EvaluationReport;请使用其中的 child reportId。`
|
|
11
|
+
: `Report ${id} is a BatchEvaluationReport. This command requires an EvaluationReport; use a child reportId from the batch.`);
|
|
12
|
+
throw new CliExit(1);
|
|
13
|
+
}
|
|
14
|
+
return report;
|
|
15
|
+
}
|
|
16
|
+
export function parseLastWindow(spec) {
|
|
17
|
+
// "7d" / "24h" / "30m" → ISO timestamp (from = now - spec)
|
|
18
|
+
const m = /^(\d+)([dhm])$/.exec(spec);
|
|
19
|
+
if (!m)
|
|
20
|
+
return null;
|
|
21
|
+
const n = Number(m[1]);
|
|
22
|
+
const unit = m[2];
|
|
23
|
+
const ms = unit === 'd' ? n * 86400_000 : unit === 'h' ? n * 3600_000 : n * 60_000;
|
|
24
|
+
return new Date(Date.now() - ms).toISOString();
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../../src/cli/commands/_shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAgB,MAAM,YAAY,CAAC;AAYhD,MAAM,UAAU,uBAAuB,CAAC,MAA6B,EAAE,EAAU,EAAE,IAAa;IAC9F,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI;YACzB,CAAC,CAAC,MAAM,EAAE,0EAA0E;YACpF,CAAC,CAAC,UAAU,EAAE,8GAA8G,CAAC,CAAC;QAChI,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,2DAA2D;IAC3D,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,EAAE,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IACnF,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAoDA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwF3D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { CliExit } from '../cli-exit.js';
|
|
4
|
+
import { tCli, langFromArgv } from '../i18n.js';
|
|
5
|
+
import { COMMON_OPTIONS } from '../parse-run-config.js';
|
|
6
|
+
import { parseArgsStrictOrExit } from '../parse-strict.js';
|
|
7
|
+
const DEFAULT_SAMPLE_FILENAMES = ['eval-samples.json', 'eval-samples.yaml', 'eval-samples.yml'];
|
|
8
|
+
function findSamplesInDir(dir) {
|
|
9
|
+
for (const name of DEFAULT_SAMPLE_FILENAMES) {
|
|
10
|
+
const candidate = join(dir, name);
|
|
11
|
+
if (existsSync(candidate))
|
|
12
|
+
return candidate;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function sampleSearchDirs(target, cwd) {
|
|
17
|
+
const dirs = [];
|
|
18
|
+
const add = (dir) => {
|
|
19
|
+
const abs = resolve(dir);
|
|
20
|
+
if (!dirs.includes(abs))
|
|
21
|
+
dirs.push(abs);
|
|
22
|
+
};
|
|
23
|
+
if (target) {
|
|
24
|
+
const absTarget = resolve(target);
|
|
25
|
+
if (existsSync(absTarget)) {
|
|
26
|
+
const stat = statSync(absTarget);
|
|
27
|
+
if (stat.isDirectory()) {
|
|
28
|
+
add(absTarget);
|
|
29
|
+
add(dirname(absTarget));
|
|
30
|
+
add(dirname(dirname(absTarget)));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const parent = dirname(absTarget);
|
|
34
|
+
add(parent);
|
|
35
|
+
add(dirname(parent));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
add(cwd);
|
|
40
|
+
return dirs;
|
|
41
|
+
}
|
|
42
|
+
function findDefaultSamplesPath(target, cwd) {
|
|
43
|
+
for (const dir of sampleSearchDirs(target, cwd)) {
|
|
44
|
+
const samplesPath = findSamplesInDir(dir);
|
|
45
|
+
if (samplesPath)
|
|
46
|
+
return samplesPath;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
export async function execute(argv) {
|
|
51
|
+
const lang = langFromArgv(argv);
|
|
52
|
+
const { values, positionals } = parseArgsStrictOrExit({
|
|
53
|
+
args: argv,
|
|
54
|
+
allowPositionals: true,
|
|
55
|
+
options: {
|
|
56
|
+
...COMMON_OPTIONS,
|
|
57
|
+
json: { type: 'boolean', default: false },
|
|
58
|
+
gate: { type: 'boolean', default: false },
|
|
59
|
+
executor: { type: 'string' },
|
|
60
|
+
model: { type: 'string' },
|
|
61
|
+
samples: { type: 'string' },
|
|
62
|
+
timeout: { type: 'string' },
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
const target = positionals[0] ?? null;
|
|
66
|
+
const executorName = values.executor ?? 'claude';
|
|
67
|
+
const model = values.model ?? 'sonnet';
|
|
68
|
+
const timeoutRaw = values.timeout;
|
|
69
|
+
const timeoutSec = timeoutRaw != null ? Number(timeoutRaw) : 8;
|
|
70
|
+
const timeoutMs = Math.max(1000, Math.floor((Number.isFinite(timeoutSec) ? timeoutSec : 8) * 1000));
|
|
71
|
+
const cwd = process.cwd();
|
|
72
|
+
const samplesPath = values.samples ? resolve(values.samples) : findDefaultSamplesPath(target, cwd);
|
|
73
|
+
let samples;
|
|
74
|
+
let requires;
|
|
75
|
+
if (samplesPath) {
|
|
76
|
+
try {
|
|
77
|
+
const { loadSamples } = await import('../../inputs/load-samples.js');
|
|
78
|
+
const loaded = loadSamples(samplesPath);
|
|
79
|
+
samples = loaded.samples;
|
|
80
|
+
requires = loaded.requires;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
84
|
+
process.stderr.write(tCli('cli.common.warn_load_samples_failed', lang, { path: samplesPath, message: msg }));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const { runDoctor } = await import('../../doctor/index.js');
|
|
88
|
+
const { renderDoctorReportText, renderDoctorReportJson } = await import('../../doctor/renderer.js');
|
|
89
|
+
let report;
|
|
90
|
+
try {
|
|
91
|
+
report = await runDoctor({
|
|
92
|
+
target,
|
|
93
|
+
cwd,
|
|
94
|
+
executorName,
|
|
95
|
+
model,
|
|
96
|
+
timeoutMs,
|
|
97
|
+
lang,
|
|
98
|
+
samples,
|
|
99
|
+
requires,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
// CliExit 透传(防御性,目前 runDoctor 不抛 CliExit,但保持四个 catch 一致)。
|
|
104
|
+
if (err instanceof CliExit)
|
|
105
|
+
throw err;
|
|
106
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
107
|
+
console.error(tCli('cli.doctor.no_skill_found', lang, { path: target ?? cwd }));
|
|
108
|
+
console.error(`(${msg})`);
|
|
109
|
+
throw new CliExit(1);
|
|
110
|
+
}
|
|
111
|
+
if (report.skills.length === 0) {
|
|
112
|
+
console.error(tCli('cli.doctor.no_skill_found', lang, { path: target ?? cwd }));
|
|
113
|
+
throw new CliExit(1);
|
|
114
|
+
}
|
|
115
|
+
const isJson = values.json;
|
|
116
|
+
const isGate = values.gate;
|
|
117
|
+
if (isJson) {
|
|
118
|
+
console.log(renderDoctorReportJson(report));
|
|
119
|
+
}
|
|
120
|
+
else if (isGate) {
|
|
121
|
+
// gate 模式: 静默 stdout, fail 时简短 stderr 摘要(供 CI 抓 exit code)
|
|
122
|
+
if (report.outcome === 'failed') {
|
|
123
|
+
const summary = lang === 'zh'
|
|
124
|
+
? `doctor failed: ${report.totals.fail} 个 skill 未通过 (${report.totals.warn} warn / ${report.totals.pass} pass)`
|
|
125
|
+
: `doctor failed: ${report.totals.fail} skills did not pass (${report.totals.warn} warn / ${report.totals.pass} pass)`;
|
|
126
|
+
console.error(summary);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
if (samplesPath && samples) {
|
|
131
|
+
process.stderr.write(tCli('cli.doctor.samples_detected', lang, { path: samplesPath }) + '\n');
|
|
132
|
+
}
|
|
133
|
+
renderDoctorReportText(report, lang);
|
|
134
|
+
}
|
|
135
|
+
throw new CliExit(report.outcome === 'failed' ? 1 : 0);
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-debias.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/eval-debias.ts"],"names":[],"mappings":"AAQA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF3D"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { CliExit } from '../cli-exit.js';
|
|
3
|
+
import { tCli, langFromArgv } from '../i18n.js';
|
|
4
|
+
import { COMMON_OPTIONS, DEFAULT_REPORTS_DIR } from '../parse-run-config.js';
|
|
5
|
+
import { parseArgsStrictOrExit } from '../parse-strict.js';
|
|
6
|
+
import { requireEvaluationReport } from './_shared.js';
|
|
7
|
+
export async function execute(argv) {
|
|
8
|
+
const lang = langFromArgv(argv);
|
|
9
|
+
const [kind, reportId, ...rest] = argv;
|
|
10
|
+
if (!kind) {
|
|
11
|
+
console.log(usage(lang));
|
|
12
|
+
throw new CliExit(1);
|
|
13
|
+
}
|
|
14
|
+
if (kind !== 'length') {
|
|
15
|
+
console.error(`Unknown debias validation kind: ${kind}. Use "length".`);
|
|
16
|
+
throw new CliExit(1);
|
|
17
|
+
}
|
|
18
|
+
if (!reportId) {
|
|
19
|
+
console.error('Usage: omk eval debias length <reportId>');
|
|
20
|
+
throw new CliExit(1);
|
|
21
|
+
}
|
|
22
|
+
const { values } = parseArgsStrictOrExit({
|
|
23
|
+
args: rest,
|
|
24
|
+
options: {
|
|
25
|
+
...COMMON_OPTIONS,
|
|
26
|
+
'reports-dir': { type: 'string', default: DEFAULT_REPORTS_DIR },
|
|
27
|
+
samples: { type: 'string' },
|
|
28
|
+
variant: { type: 'string' },
|
|
29
|
+
'judge-models': { type: 'string' },
|
|
30
|
+
'bootstrap-samples': { type: 'string', default: '1000' },
|
|
31
|
+
seed: { type: 'string' },
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
const { parseJudgeModelsArgOrExit } = await import('../parse-run-config.js');
|
|
35
|
+
const cliJudgeModels = values['judge-models'] !== undefined
|
|
36
|
+
? parseJudgeModelsArgOrExit(values['judge-models'])
|
|
37
|
+
: undefined;
|
|
38
|
+
if (cliJudgeModels && cliJudgeModels.length > 1) {
|
|
39
|
+
console.error(tCli('cli.common.judge_models_single_only', lang, { cmd: 'eval debias' }));
|
|
40
|
+
throw new CliExit(2);
|
|
41
|
+
}
|
|
42
|
+
const { createFileStore } = await import('../../server/report-store.js');
|
|
43
|
+
const store = createFileStore(resolve(values['reports-dir']));
|
|
44
|
+
const report = requireEvaluationReport(await store.get(reportId), reportId, lang);
|
|
45
|
+
const samplesPath = values.samples ?? report.meta?.request?.samplesPath;
|
|
46
|
+
if (!samplesPath) {
|
|
47
|
+
console.error('Cannot find samples path. Pass --samples <path> or ensure report has request.samplesPath.');
|
|
48
|
+
throw new CliExit(1);
|
|
49
|
+
}
|
|
50
|
+
const { loadSamples } = await import('../../inputs/load-samples.js');
|
|
51
|
+
const { samples } = loadSamples(samplesPath);
|
|
52
|
+
const debiasJudges = cliJudgeModels
|
|
53
|
+
?? (report.meta?.judgeModels?.[0]
|
|
54
|
+
? [{ executor: report.meta.judgeModels[0].executor, model: report.meta.judgeModels[0].model }]
|
|
55
|
+
: []);
|
|
56
|
+
if (debiasJudges.length === 0) {
|
|
57
|
+
console.error(tCli('cli.common.no_judge_model', lang));
|
|
58
|
+
throw new CliExit(1);
|
|
59
|
+
}
|
|
60
|
+
process.stderr.write(lang === 'zh'
|
|
61
|
+
? '\n⚠ eval debias 会重判所有 sample × variant,judge 成本大约翻倍。\n'
|
|
62
|
+
: '\n⚠ eval debias will re-judge all sample × variant pairs; judge cost will roughly double.\n');
|
|
63
|
+
const { createExecutor } = await import('../../executors/index.js');
|
|
64
|
+
const judgeExecutor = createExecutor(debiasJudges[0].executor);
|
|
65
|
+
const judgeModel = debiasJudges[0].model;
|
|
66
|
+
const { validateLengthDebias, formatDebiasValidate } = await import('../../grading/debias-validate.js');
|
|
67
|
+
const seedVal = values.seed != null ? Number(values.seed) : undefined;
|
|
68
|
+
const bsRaw = Number(values['bootstrap-samples']) || 1000;
|
|
69
|
+
const result = await validateLengthDebias({
|
|
70
|
+
report,
|
|
71
|
+
samples,
|
|
72
|
+
judgeExecutor,
|
|
73
|
+
judgeModel,
|
|
74
|
+
variant: values.variant,
|
|
75
|
+
bootstrapSamples: Math.max(100, bsRaw),
|
|
76
|
+
seed: Number.isFinite(seedVal) ? seedVal : undefined,
|
|
77
|
+
onProgress: ({ sample_id, completed, total }) => {
|
|
78
|
+
process.stderr.write(` judging ${completed}/${total}: ${sample_id}\n`);
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
console.log(formatDebiasValidate(result));
|
|
82
|
+
}
|
|
83
|
+
function usage(lang) {
|
|
84
|
+
return lang === 'zh'
|
|
85
|
+
? '用法:omk eval debias length <reportId> [--samples <path>] [--judge-models <executor:model>]'
|
|
86
|
+
: 'Usage: omk eval debias length <reportId> [--samples <path>] [--judge-models <executor:model>]';
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=eval-debias.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-debias.js","sourceRoot":"","sources":["../../../../src/cli/commands/eval-debias.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,mCAAmC,IAAI,iBAAiB,CAAC,CAAC;QACxE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC;QACvC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,GAAG,cAAc;YACjB,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE;YAC/D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC3B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC3B,cAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClC,mBAAmB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;YACxD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACzB;KACF,CAAC,CAAC;IAEH,MAAM,EAAE,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAI,MAAM,CAAC,cAAc,CAAwB,KAAK,SAAS;QACjF,CAAC,CAAC,yBAAyB,CAAC,MAAM,CAAC,cAAc,CAAW,CAAC;QAC7D,CAAC,CAAC,SAAS,CAAC;IACd,IAAI,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,qCAAqC,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;QACzF,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IACzE,MAAM,KAAK,GAAgB,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAW,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClF,MAAM,WAAW,GAAI,MAAM,CAAC,OAA8B,IAAI,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC;IAChG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,2FAA2F,CAAC,CAAC;QAC3G,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,8BAA8B,CAAC,CAAC;IACrE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAkB,cAAc;WAC7C,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9F,CAAC,CAAC,EAAE,CAAC,CAAC;IACZ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI;QAChC,CAAC,CAAC,wDAAwD;QAC1D,CAAC,CAAC,6FAA6F,CAAC,CAAC;IAEnG,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACzC,MAAM,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,kCAAkC,CAAC,CAAC;IACxG,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,IAAI,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;QACxC,MAAM;QACN,OAAO;QACP,aAAa;QACb,UAAU;QACV,OAAO,EAAE,MAAM,CAAC,OAA6B;QAC7C,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;QACtC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;QACpD,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;YAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC;QAC1E,CAAC;KACF,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,KAAK,CAAC,IAAiB;IAC9B,OAAO,IAAI,KAAK,IAAI;QAClB,CAAC,CAAC,2FAA2F;QAC7F,CAAC,CAAC,+FAA+F,CAAC;AACtG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eval-gold.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/eval-gold.ts"],"names":[],"mappings":"AAQA,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+G3D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { CliExit } from '../cli-exit.js';
|
|
3
|
+
import { langFromArgv } from '../i18n.js';
|
|
4
|
+
import { COMMON_OPTIONS, DEFAULT_REPORTS_DIR } from '../parse-run-config.js';
|
|
5
|
+
import { parseArgsStrictOrExit } from '../parse-strict.js';
|
|
6
|
+
import { requireEvaluationReport } from './_shared.js';
|
|
7
|
+
export async function execute(argv) {
|
|
8
|
+
const lang = langFromArgv(argv);
|
|
9
|
+
const [sub, ...rest] = argv;
|
|
10
|
+
if (!sub) {
|
|
11
|
+
console.log(usage(lang));
|
|
12
|
+
throw new CliExit(1);
|
|
13
|
+
}
|
|
14
|
+
if (sub === 'init') {
|
|
15
|
+
const { values } = parseArgsStrictOrExit({
|
|
16
|
+
args: rest,
|
|
17
|
+
options: {
|
|
18
|
+
...COMMON_OPTIONS,
|
|
19
|
+
out: { type: 'string', default: './gold-dataset' },
|
|
20
|
+
annotator: { type: 'string' },
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const { initGoldDataset } = await import('../../grading/gold-cli.js');
|
|
24
|
+
try {
|
|
25
|
+
const written = initGoldDataset(values.out, {
|
|
26
|
+
annotator: values.annotator,
|
|
27
|
+
});
|
|
28
|
+
console.log(lang === 'zh'
|
|
29
|
+
? `已在 ${values.out} 创建 ${written.length} 个文件:`
|
|
30
|
+
: `Created ${written.length} files in ${values.out}:`);
|
|
31
|
+
for (const p of written)
|
|
32
|
+
console.log(` ${p}`);
|
|
33
|
+
console.log(lang === 'zh'
|
|
34
|
+
? '\n下一步:编辑 annotations.yaml 加入真实标注,然后运行 omk eval gold validate'
|
|
35
|
+
: '\nNext step: edit annotations.yaml with real annotations, then run omk eval gold validate');
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error(err.message);
|
|
39
|
+
throw new CliExit(1);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (sub === 'validate') {
|
|
44
|
+
const { positionals } = parseArgsStrictOrExit({
|
|
45
|
+
args: rest,
|
|
46
|
+
allowPositionals: true,
|
|
47
|
+
options: { ...COMMON_OPTIONS },
|
|
48
|
+
});
|
|
49
|
+
const dir = positionals[0];
|
|
50
|
+
if (!dir) {
|
|
51
|
+
console.error('Usage: omk eval gold validate <dir>');
|
|
52
|
+
throw new CliExit(1);
|
|
53
|
+
}
|
|
54
|
+
const { validateGoldDataset } = await import('../../grading/gold-cli.js');
|
|
55
|
+
const result = validateGoldDataset(dir);
|
|
56
|
+
if (result.ok) {
|
|
57
|
+
console.log(lang === 'zh'
|
|
58
|
+
? `✓ gold dataset OK,共 ${result.sampleCount} 条标注`
|
|
59
|
+
: `✓ gold dataset OK — ${result.sampleCount} annotations`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.error(`✗ gold dataset has ${result.issues.length} issue(s):`);
|
|
63
|
+
for (const msg of result.issues)
|
|
64
|
+
console.error(` - ${msg}`);
|
|
65
|
+
throw new CliExit(1);
|
|
66
|
+
}
|
|
67
|
+
if (sub === 'compare') {
|
|
68
|
+
const reportId = rest[0];
|
|
69
|
+
if (!reportId) {
|
|
70
|
+
console.error('Usage: omk eval gold compare <reportId> --gold-dir <dir>');
|
|
71
|
+
throw new CliExit(1);
|
|
72
|
+
}
|
|
73
|
+
const { values } = parseArgsStrictOrExit({
|
|
74
|
+
args: rest.slice(1),
|
|
75
|
+
options: {
|
|
76
|
+
...COMMON_OPTIONS,
|
|
77
|
+
'gold-dir': { type: 'string' },
|
|
78
|
+
variant: { type: 'string' },
|
|
79
|
+
'reports-dir': { type: 'string', default: DEFAULT_REPORTS_DIR },
|
|
80
|
+
'bootstrap-samples': { type: 'string', default: '1000' },
|
|
81
|
+
seed: { type: 'string' },
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const goldDir = values['gold-dir'];
|
|
85
|
+
if (!goldDir) {
|
|
86
|
+
console.error('--gold-dir is required');
|
|
87
|
+
throw new CliExit(1);
|
|
88
|
+
}
|
|
89
|
+
const { loadGoldDataset } = await import('../../grading/gold-dataset.js');
|
|
90
|
+
const { compareGoldToReport, formatGoldCompare } = await import('../../grading/gold-cli.js');
|
|
91
|
+
const { createFileStore } = await import('../../server/report-store.js');
|
|
92
|
+
const { dataset, issues } = loadGoldDataset(goldDir);
|
|
93
|
+
if (!dataset) {
|
|
94
|
+
console.error('Cannot load gold dataset:');
|
|
95
|
+
for (const i of issues)
|
|
96
|
+
console.error(` - ${i.message}`);
|
|
97
|
+
throw new CliExit(1);
|
|
98
|
+
}
|
|
99
|
+
for (const i of issues)
|
|
100
|
+
console.error(`warn: ${i.message}`);
|
|
101
|
+
const store = createFileStore(resolve(values['reports-dir']));
|
|
102
|
+
const report = requireEvaluationReport(await store.get(reportId), reportId, lang);
|
|
103
|
+
const samples = Math.max(100, Number(values['bootstrap-samples']) || 1000);
|
|
104
|
+
const seedVal = values.seed != null ? Number(values.seed) : undefined;
|
|
105
|
+
const result = compareGoldToReport({
|
|
106
|
+
report,
|
|
107
|
+
gold: dataset,
|
|
108
|
+
variant: values.variant,
|
|
109
|
+
samples,
|
|
110
|
+
seed: Number.isFinite(seedVal) ? seedVal : undefined,
|
|
111
|
+
});
|
|
112
|
+
console.log(formatGoldCompare(result, dataset));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
console.error(`Unknown subcommand: eval gold ${sub}. Use init / validate / compare.`);
|
|
116
|
+
throw new CliExit(1);
|
|
117
|
+
}
|
|
118
|
+
function usage(lang) {
|
|
119
|
+
return lang === 'zh'
|
|
120
|
+
? [
|
|
121
|
+
'omk eval gold — 管理 human-gold 标注集',
|
|
122
|
+
'',
|
|
123
|
+
'用法:',
|
|
124
|
+
' omk eval gold init [--out <dir>] [--annotator <name>]',
|
|
125
|
+
' omk eval gold validate <dir>',
|
|
126
|
+
' omk eval gold compare <reportId> --gold-dir <dir>',
|
|
127
|
+
].join('\n')
|
|
128
|
+
: [
|
|
129
|
+
'omk eval gold — manage human-gold annotation datasets',
|
|
130
|
+
'',
|
|
131
|
+
'Usage:',
|
|
132
|
+
' omk eval gold init [--out <dir>] [--annotator <name>]',
|
|
133
|
+
' omk eval gold validate <dir>',
|
|
134
|
+
' omk eval gold compare <reportId> --gold-dir <dir>',
|
|
135
|
+
].join('\n');
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=eval-gold.js.map
|