oh-my-knowledge 0.35.0 → 0.37.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 +5 -3
- package/README.zh.md +5 -3
- package/dist/assets/agent-skills/omk/SKILL.md +4 -2
- package/dist/assets/agent-skills/omk/references/commands.md +121 -2
- package/dist/authoring/evolver.js +1 -1
- package/dist/cli/commands/doctor.js +21 -5
- package/dist/cli/commands/eval/index.js +7 -6
- package/dist/cli/commands/evolve.d.ts +11 -0
- package/dist/cli/commands/evolve.js +105 -5
- package/dist/cli/commands/list.d.ts +25 -0
- package/dist/cli/commands/list.js +118 -0
- package/dist/cli/commands/promote.d.ts +24 -0
- package/dist/cli/commands/promote.js +158 -0
- package/dist/cli/commands/rollback.d.ts +20 -0
- package/dist/cli/commands/rollback.js +95 -0
- package/dist/cli/commands/sample.d.ts +1 -0
- package/dist/cli/commands/sample.js +10 -4
- package/dist/cli/lib/cell-format.d.ts +17 -0
- package/dist/cli/lib/cell-format.js +19 -0
- package/dist/cli/lib/cmd-flags.d.ts +1 -0
- package/dist/cli/lib/i18n-dict/common.d.ts +1 -1
- package/dist/cli/lib/i18n-dict/common.js +8 -0
- package/dist/cli/lib/i18n-dict/list.d.ts +3 -0
- package/dist/cli/lib/i18n-dict/list.js +36 -0
- package/dist/cli/lib/i18n-dict/promote.d.ts +3 -0
- package/dist/cli/lib/i18n-dict/promote.js +54 -0
- package/dist/cli/lib/i18n-dict/rollback.d.ts +3 -0
- package/dist/cli/lib/i18n-dict/rollback.js +22 -0
- package/dist/cli/lib/i18n-dict.d.ts +4 -1
- package/dist/cli/lib/i18n-dict.js +6 -0
- package/dist/cli/lib/progress.d.ts +3 -0
- package/dist/cli/lib/progress.js +22 -0
- package/dist/cli/lib/run-tally.js +1 -1
- package/dist/cli/lib/shared.js +1 -1
- package/dist/cli/lib/source-probe.d.ts +15 -0
- package/dist/cli/lib/source-probe.js +129 -0
- package/dist/doctor/endpoint-rule.d.ts +60 -0
- package/dist/doctor/endpoint-rule.js +381 -0
- package/dist/doctor/health/load-custom-dimensions.d.ts +6 -0
- package/dist/doctor/health/load-custom-dimensions.js +43 -3
- package/dist/doctor/index.js +9 -2
- package/dist/eval-core/evaluation-reporting.d.ts +1 -0
- package/dist/eval-core/evaluation-reporting.js +6 -4
- package/dist/eval-workflows/batch-evaluation-workflow.js +3 -2
- package/dist/eval-workflows/run-evaluation.js +2 -2
- package/dist/executors/codex-cli.js +5 -1
- package/dist/inputs/skill-loader.js +6 -3
- package/dist/managed/index.d.ts +2 -0
- package/dist/managed/index.js +2 -0
- package/dist/managed/list-view.d.ts +58 -0
- package/dist/managed/list-view.js +70 -0
- package/dist/managed/promote-gate.d.ts +40 -0
- package/dist/managed/promote-gate.js +37 -0
- package/dist/managed/store.d.ts +25 -2
- package/dist/managed/store.js +137 -11
- package/dist/observability/experience.d.ts +2 -0
- package/dist/observability/experience.js +31 -2
- package/dist/observability/inbox.js +31 -5
- package/dist/observability/review-state.js +22 -11
- package/dist/observability/soft-standards/llm-extractor.js +3 -3
- package/dist/observability/soft-standards/skill-standards-store.d.ts +1 -0
- package/dist/observability/soft-standards/skill-standards-store.js +77 -14
- package/dist/observability/soft-standards/types.d.ts +2 -2
- package/dist/renderer/doctor-detail-renderer.d.ts +9 -0
- package/dist/renderer/doctor-detail-renderer.js +114 -0
- package/dist/renderer/html-renderer.d.ts +3 -2
- package/dist/renderer/html-renderer.js +102 -102
- package/dist/renderer/icons.d.ts +29 -0
- package/dist/renderer/icons.js +66 -0
- package/dist/renderer/layout.js +81 -68
- package/dist/renderer/observation-inbox/styles.d.ts +1 -1
- package/dist/renderer/observation-inbox/styles.js +53 -53
- package/dist/renderer/report-shell.d.ts +77 -0
- package/dist/renderer/report-shell.js +223 -0
- package/dist/renderer/skill-detail-renderer.js +147 -352
- package/dist/renderer/skill-health-renderer.js +50 -73
- package/dist/renderer/skill-list-renderer.js +358 -306
- package/dist/renderer/summary.js +272 -162
- package/dist/renderer/test-view.d.ts +4 -3
- package/dist/renderer/test-view.js +386 -135
- package/dist/server/report-server.js +142 -28
- package/dist/server/report-store.d.ts +1 -1
- package/dist/server/report-store.js +16 -15
- package/dist/server/skill-index.js +5 -4
- package/dist/types/doctor.d.ts +24 -2
- package/dist/types/doctor.js +1 -1
- package/dist/types/managed.d.ts +17 -3
- package/dist/types/observability.d.ts +6 -6
- package/dist/types/report.d.ts +9 -4
- package/package.json +1 -1
|
@@ -12,20 +12,9 @@
|
|
|
12
12
|
* - 报告视觉和 eval HTML 保持一致,读者无学习成本切换
|
|
13
13
|
*/
|
|
14
14
|
import { confidenceOf } from '../observability/skill-health-analyzer.js';
|
|
15
|
-
import { COLORS, e,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
yellow: 'var(--yellow)',
|
|
19
|
-
red: 'var(--red)',
|
|
20
|
-
};
|
|
21
|
-
const HEALTH_BAND_LABEL = {
|
|
22
|
-
green: { zh: '健康', en: 'Healthy' },
|
|
23
|
-
yellow: { zh: '待观察', en: 'Watch' },
|
|
24
|
-
red: { zh: '需关注', en: 'Attention needed' },
|
|
25
|
-
};
|
|
26
|
-
function fmtPct(rate, digits = 0) {
|
|
27
|
-
return `${(rate * 100).toFixed(digits)}%`;
|
|
28
|
-
}
|
|
15
|
+
import { COLORS, e, t } from './layout.js';
|
|
16
|
+
import { icon } from './icons.js';
|
|
17
|
+
import { reportShell } from './report-shell.js';
|
|
29
18
|
function fmtTimeRange(from, to) {
|
|
30
19
|
if (!from || !to)
|
|
31
20
|
return '—';
|
|
@@ -34,67 +23,27 @@ function fmtTimeRange(from, to) {
|
|
|
34
23
|
return fromDate === toDate ? fromDate : `${fromDate} → ${toDate}`;
|
|
35
24
|
}
|
|
36
25
|
/**
|
|
37
|
-
*
|
|
26
|
+
* 数据来源水印 (spec §六 强制要求) + 低 N 可信度提醒。
|
|
38
27
|
*/
|
|
39
|
-
function
|
|
28
|
+
function renderWatermark(report, lang) {
|
|
40
29
|
const { meta, overall } = report;
|
|
41
|
-
// Statistical-confidence guard: below the segment threshold a hard health band
|
|
42
|
-
// overstates certainty (1 segment + 1 failure judged the same as 50). When the
|
|
43
|
-
// overall confidence is not high, mute the colour and append an N caveat.
|
|
44
|
-
// Legacy reports (pre-confidence) fall back to deriving from segmentCount, so old
|
|
45
|
-
// JSON never renders `undefined confidence`.
|
|
46
30
|
const confidence = overall.confidence ?? confidenceOf(meta.segmentCount);
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
? 'var(--text-faint)'
|
|
50
|
-
: HEALTH_BAND_COLOR[overall.healthBand];
|
|
51
|
-
// underpowered 时色带已静音为灰,标签也不报硬结论(需关注 / 健康),改为「样本不足」,跟灰底 + caveat 一致。
|
|
52
|
-
const bandLabel = confidence === 'underpowered'
|
|
53
|
-
? (lang === 'zh' ? '样本不足' : 'Insufficient N')
|
|
54
|
-
: HEALTH_BAND_LABEL[overall.healthBand][lang === 'zh' ? 'zh' : 'en'];
|
|
55
|
-
const confCaveat = lowConfidence
|
|
56
|
-
? `<div class="card-sub" style="color:var(--text-faint)">${lang === 'zh'
|
|
31
|
+
const confCaveat = confidence !== 'high'
|
|
32
|
+
? `<div style="color:var(--text-faint);margin-top:6px">${lang === 'zh'
|
|
57
33
|
? `⚠ 样本量 ${meta.segmentCount} 段,可信度${confidence === 'underpowered' ? '不足' : '偏低'},色带仅供参考`
|
|
58
34
|
: `⚠ N=${meta.segmentCount} segments — ${confidence} confidence; band is indicative`}</div>`
|
|
59
35
|
: '';
|
|
60
36
|
const tracePath = e(meta.tracePath);
|
|
61
37
|
const kbPath = meta.kbPath ? e(meta.kbPath) : '—';
|
|
62
|
-
const timeRange = fmtTimeRange(meta.timeRange.from, meta.timeRange.to);
|
|
63
38
|
const warning = lang === 'zh'
|
|
64
|
-
? '本报告仅反映指定时间窗内观察到的 skill
|
|
39
|
+
? '本报告仅反映指定时间窗内观察到的 skill 使用情况,不代表 skill 的绝对质量,也不能替代 offline eval 的对照验证。'
|
|
65
40
|
: 'Report reflects only observed skill usage in the given window. Does not imply absolute skill quality, does not replace offline eval.';
|
|
66
|
-
return
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<div class="cards" style="margin-bottom:20px">
|
|
71
|
-
<div class="card" style="flex:0 0 auto;min-width:160px;border-left:4px solid ${bandColor}">
|
|
72
|
-
<div class="card-label">${lang === 'zh' ? '整体健康度' : 'Overall health'}</div>
|
|
73
|
-
<div class="card-value" style="color:${bandColor}">${bandLabel}</div>
|
|
74
|
-
<div class="card-sub">${lang === 'zh' ? '加权盲区' : 'weighted gap'} ${fmtPct(overall.weightedGapRate, 1)} · ${lang === 'zh' ? '原始盲区' : 'raw gap'} ${fmtPct(overall.gapRate, 1)}</div>
|
|
75
|
-
${confCaveat}
|
|
76
|
-
</div>
|
|
77
|
-
<div class="card">
|
|
78
|
-
<div class="card-label">${lang === 'zh' ? '会话 / 段 / 工具调用' : 'Sessions / Segments / Tool calls'}</div>
|
|
79
|
-
<div class="card-value" style="font-size:18px">${meta.sessionCount} / ${meta.segmentCount} / ${meta.toolCallCount}</div>
|
|
80
|
-
<div class="card-sub">${lang === 'zh' ? '工具失败率' : 'tool fail rate'} ${fmtPct(meta.toolFailureRate, 1)} · ${meta.messageCount.toLocaleString()} ${lang === 'zh' ? '条消息' : 'messages'}</div>
|
|
81
|
-
</div>
|
|
82
|
-
<div class="card">
|
|
83
|
-
<div class="card-label">${lang === 'zh' ? '时间窗' : 'Time window'}</div>
|
|
84
|
-
<div class="card-value" style="font-size:18px">${timeRange}</div>
|
|
85
|
-
<div class="card-sub">${lang === 'zh' ? '生成于' : 'generated'} ${new Date(meta.generatedAt).toISOString().split('T')[0]}</div>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
|
|
89
|
-
<div style="padding:10px 14px;background:var(--info-bg);border-left:3px solid var(--accent);border-radius:var(--radius);margin-bottom:20px;font-size:12px;line-height:1.6">
|
|
90
|
-
<div style="color:var(--text-secondary);margin-bottom:4px"><strong>${lang === 'zh' ? '水印' : 'Watermark'}</strong> (spec §六)</div>
|
|
91
|
-
<div style="color:var(--text-muted);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px">
|
|
92
|
-
trace: ${tracePath}<br>
|
|
93
|
-
kb: ${kbPath}
|
|
94
|
-
</div>
|
|
41
|
+
return `<div class="rs-panel" style="background:var(--info-bg);font-size:12px;line-height:1.6">
|
|
42
|
+
<div style="color:var(--text-secondary);margin-bottom:4px;font-weight:600">${lang === 'zh' ? '数据来源' : 'Source'}</div>
|
|
43
|
+
<div style="color:var(--text-muted);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px">trace: ${tracePath}<br>kb: ${kbPath}</div>
|
|
95
44
|
<div style="color:var(--text-muted);margin-top:6px;font-style:italic">${warning}</div>
|
|
96
|
-
|
|
97
|
-
|
|
45
|
+
${confCaveat}
|
|
46
|
+
</div>`;
|
|
98
47
|
}
|
|
99
48
|
/**
|
|
100
49
|
* 每 skill 一张 card (复用 v0.17 A 的 ki-card 结构)。
|
|
@@ -262,20 +211,48 @@ function renderDeadKbSection(report, lang) {
|
|
|
262
211
|
* 主入口: 生成完整 HTML。
|
|
263
212
|
*/
|
|
264
213
|
export function renderSkillHealthReport(report, lang = 'zh') {
|
|
265
|
-
const
|
|
266
|
-
|
|
214
|
+
const zh = lang === 'zh';
|
|
215
|
+
const { meta, overall } = report;
|
|
216
|
+
const confidence = overall.confidence ?? confidenceOf(meta.segmentCount);
|
|
217
|
+
// 整体健康分 = (1 - 加权盲区) × 100;underpowered 时不给硬分。
|
|
218
|
+
const score = confidence === 'underpowered' ? null : Math.round((1 - overall.weightedGapRate) * 100);
|
|
219
|
+
const scoreLabel = score == null
|
|
220
|
+
? (zh ? '样本不足' : 'Low N')
|
|
221
|
+
: overall.healthBand === 'green' ? (zh ? '健康' : 'Healthy')
|
|
222
|
+
: overall.healthBand === 'yellow' ? (zh ? '待观察' : 'Watch')
|
|
223
|
+
: (zh ? '需关注' : 'Attention');
|
|
267
224
|
const skillsSorted = Object.values(report.bySkill).sort((a, b) => b.segmentCount - a.segmentCount);
|
|
268
225
|
const cards = skillsSorted
|
|
269
226
|
.map((skill, i) => renderSkillCard(skill, COLORS[i % COLORS.length], lang))
|
|
270
227
|
.join('\n');
|
|
228
|
+
const statsBar = `<div class="rs-stats">
|
|
229
|
+
<div class="rs-stat rs-stat--total"><span class="rs-stat-num">${meta.sessionCount}</span><span class="rs-stat-label">${zh ? '会话' : 'Sessions'}</span></div>
|
|
230
|
+
<div class="rs-stat rs-stat--total"><span class="rs-stat-num">${meta.segmentCount}</span><span class="rs-stat-label">${zh ? '段' : 'Segments'}</span></div>
|
|
231
|
+
<div class="rs-stat rs-stat--total"><span class="rs-stat-num">${meta.toolCallCount}</span><span class="rs-stat-label">${zh ? '工具调用' : 'Tool calls'}</span></div>
|
|
232
|
+
<div class="rs-stat ${overall.weightedGapRate >= 0.3 ? 'rs-stat--fail' : overall.weightedGapRate >= 0.1 ? 'rs-stat--warn' : 'rs-stat--pass'}"><span class="rs-stat-num">${Math.round(overall.weightedGapRate * 100)}%</span><span class="rs-stat-label">${zh ? '加权盲区' : 'Weighted gap'}</span></div>
|
|
233
|
+
</div>`;
|
|
271
234
|
const body = [
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
<
|
|
276
|
-
${cards}
|
|
277
|
-
</
|
|
235
|
+
statsBar,
|
|
236
|
+
renderWatermark(report, lang),
|
|
237
|
+
`<div class="rs-panel">
|
|
238
|
+
<div class="rs-panel-title">${zh ? '各 skill 健康度' : 'Per-skill health'} <small>${zh ? '按使用量降序' : 'sorted by usage'}</small></div>
|
|
239
|
+
${cards || `<div class="rs-empty">${zh ? '本期无 skill 数据' : 'No skill data'}</div>`}
|
|
240
|
+
</div>`,
|
|
278
241
|
renderDeadKbSection(report, lang),
|
|
279
242
|
].filter(Boolean).join('\n');
|
|
280
|
-
return
|
|
243
|
+
return reportShell({
|
|
244
|
+
dim: 'observe',
|
|
245
|
+
icon: '👁',
|
|
246
|
+
kindTitle: zh ? '生产观察报告' : 'Observe Report',
|
|
247
|
+
skillName: zh ? 'Skill 健康度日报' : 'Skill Health Daily',
|
|
248
|
+
metaItems: [
|
|
249
|
+
`${icon('clock', { size: 13 })} ${fmtTimeRange(meta.timeRange.from, meta.timeRange.to)}`,
|
|
250
|
+
`${icon('calendar', { size: 13 })} ${new Date(meta.generatedAt).toISOString().slice(0, 16).replace('T', ' ')}`,
|
|
251
|
+
],
|
|
252
|
+
score,
|
|
253
|
+
scoreLabel,
|
|
254
|
+
backHref: `/${lang === 'zh' ? '' : '?lang=en'}`,
|
|
255
|
+
backLabel: zh ? '返回工作台' : 'Back to dashboard',
|
|
256
|
+
body,
|
|
257
|
+
}, lang);
|
|
281
258
|
}
|