dsh-ronge-adaptive-skill-archive 5.2.0 → 5.3.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 +7 -6
- package/client.js +23 -1
- package/docs/claims.md +4 -3
- package/docs/dsh-compatibility.md +4 -4
- package/index.js +1 -1
- package/lib/intelligence/compose.js +11 -0
- package/lib/intelligence/draft.js +17 -0
- package/package.json +1 -1
- package/scripts/benchmark-live.mjs +83 -0
- package/test/fixtures/live-ab-tasks.json +14 -0
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
<sub>会话右侧的「技能」抽屉:推荐 / 组队计划 / 经验 / 安全与更新,都在一个面板里。</sub>
|
|
32
32
|
</p>
|
|
33
33
|
|
|
34
|
-
> **v5.
|
|
34
|
+
> **v5.3.0 发布说明**:本 README 是当前发布稿。三大新能力 `plan → compose → draft`(任务拆解 / 技能组队 / 按缺口造技能)与 12 领域包为本次发布新增;每条声明的证据、实测状态与未验证项统一记录在 **[docs/claims.md](docs/claims.md)**。benchmark 数字见 **[docs/benchmark.md](docs/benchmark.md)**(2026-10-30 快照)。
|
|
35
35
|
|
|
36
36
|
## 为什么需要 v5
|
|
37
37
|
|
|
@@ -59,8 +59,8 @@ v5 的驾驶舱把这条链路补全:
|
|
|
59
59
|
npx dsh-ronge-adaptive-skill-archive
|
|
60
60
|
# 想先体检:npx dsh-ronge-adaptive-skill-archive doctor
|
|
61
61
|
|
|
62
|
-
# 2) 把打印出的这一行交给任意 DSH 会话里的 Agent 执行(v5.
|
|
63
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.
|
|
62
|
+
# 2) 把打印出的这一行交给任意 DSH 会话里的 Agent 执行(v5.3.0 发布后可用)
|
|
63
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.3.0
|
|
64
64
|
|
|
65
65
|
# 3) 刷新页面 → 右上角「技能」→ 右侧抽屉;计划模式 / 沉浸模式切换
|
|
66
66
|
```
|
|
@@ -209,6 +209,7 @@ v5.0.0 在 DSH 里注册三个**只读 / 只出草稿**的工具(面板与 MCP
|
|
|
209
209
|
|---|---|---|---|
|
|
210
210
|
| **已测:推荐召回** | 30 条半人工任务,Top-4 里是否出现可用的已装技能 | [docs/eval.md](docs/eval.md) | Recall@4 = 0.9(27/30),运行于 v2.7.2 工作树,**引用需注明口径** |
|
|
211
211
|
| **已测:库检索** | 24 条任务在 6,399 索引里的类目命中 | [docs/eval.md](docs/eval.md) | Category Hit@5 等指标见文档;Hit@5 偏松,不能证明技能好用 |
|
|
212
|
+
| **v5:真实任务 A/B** | 12 条任务、baseline/plugin 两 arm、成功/tokens/toolCalls/wallMs | [docs/benchmark-live.md](docs/benchmark-live.md)(尚未运行,不预填) | 没有记录文件就没有数字 |
|
|
212
213
|
| **v5:规划 / 组队 / 效率** | planCoverage **0.333**、compositionValidity **1.00**、capabilityCoverage **0.717**、hintRecall **0.45**、gapDetection **1.00**(宽松口径:不假装已覆盖)、contextTokens mean **131.5** / p95 **193**(延迟为单机快照,不对外作 SLA);基线 keyword 0.083/0.217/0.25/0.532;installLoad **0.3** | [docs/benchmark.md](docs/benchmark.md)(60 条 held-out,2026-10-30) | 指标是半人工基准,不等于真实成功率;installLoad 0.3 必须一起读 |
|
|
213
214
|
|
|
214
215
|
规则:
|
|
@@ -246,8 +247,8 @@ v5.0.0 在 DSH 里注册三个**只读 / 只出草稿**的工具(面板与 MCP
|
|
|
246
247
|
| 方式 | 命令 | 适合 |
|
|
247
248
|
|---|---|---|
|
|
248
249
|
| **npx 助手** | `npx dsh-ronge-adaptive-skill-archive`(体检:`npx dsh-ronge-adaptive-skill-archive doctor`) | 第一次用;不装东西,只体检 + 打印安装命令 |
|
|
249
|
-
| **npm** | `plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.
|
|
250
|
-
| **GitHub tag** | `plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.
|
|
250
|
+
| **npm** | `plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.3.0` | v5.3.0 发布到 npm 后可用 |
|
|
251
|
+
| **GitHub tag** | `plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.3.0` | 固定版本、可审源码 |
|
|
251
252
|
| **本地目录** | `plugin_manager install_bundle target="/absolute/path/to/dsh-ronge-adaptive-skill-archive"` | 开发、改代码、离线 |
|
|
252
253
|
|
|
253
254
|
> v5.0.0 打 tag / 发布 npm 之前,`@5.0.0` 会 404:请先用本地目录,或安装当时最新的已发布版本。安装后 DSH 需**重启**才会加载新的 Host 模块;浏览器刷新加载 Client。
|
|
@@ -356,7 +357,7 @@ MIT。见 [LICENSE](LICENSE)。索引中的技能元数据归原作者,边界
|
|
|
356
357
|
**Install** (in a DSH session):
|
|
357
358
|
|
|
358
359
|
```bash
|
|
359
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.
|
|
360
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.3.0
|
|
360
361
|
# then open any session → 「技能」 → switch Plan / Immersive
|
|
361
362
|
```
|
|
362
363
|
|
package/client.js
CHANGED
|
@@ -271,6 +271,8 @@ window.__ModuleLoader__.load({
|
|
|
271
271
|
intelStages: '阶段',
|
|
272
272
|
intelInstalledCount: '已安装技能',
|
|
273
273
|
intelReviewGap: '缺少独立复核技能:计划未假装复核',
|
|
274
|
+
intelReviewSuggestions: '可安装的复核候选',
|
|
275
|
+
intelDraftQuality: '草稿质量',
|
|
274
276
|
intelPlanOptions: '方案',
|
|
275
277
|
intelPlanFast: '快速',
|
|
276
278
|
intelPlanBalanced: '均衡',
|
|
@@ -565,6 +567,8 @@ window.__ModuleLoader__.load({
|
|
|
565
567
|
intelStages: 'Stages',
|
|
566
568
|
intelInstalledCount: 'Installed skills',
|
|
567
569
|
intelReviewGap: 'No independent reviewer: plan does not fake a review',
|
|
570
|
+
intelReviewSuggestions: 'Reviewer candidates',
|
|
571
|
+
intelDraftQuality: 'Draft quality',
|
|
568
572
|
intelPlanOptions: 'Plans',
|
|
569
573
|
intelPlanFast: 'Fast',
|
|
570
574
|
intelPlanBalanced: 'Balanced',
|
|
@@ -4118,7 +4122,18 @@ window.__ModuleLoader__.load({
|
|
|
4118
4122
|
),
|
|
4119
4123
|
),
|
|
4120
4124
|
plan.reviewGap
|
|
4121
|
-
? h(
|
|
4125
|
+
? h(
|
|
4126
|
+
'div',
|
|
4127
|
+
{ className: 'sf-intel-note' },
|
|
4128
|
+
t('intelReviewGap'),
|
|
4129
|
+
Array.isArray(plan.reviewGapSuggestions) && plan.reviewGapSuggestions.length
|
|
4130
|
+
? h(
|
|
4131
|
+
'span',
|
|
4132
|
+
{ className: 'sf-intel-suggest' },
|
|
4133
|
+
' · ' + t('intelReviewSuggestions') + ': ' + plan.reviewGapSuggestions.join(', '),
|
|
4134
|
+
)
|
|
4135
|
+
: null,
|
|
4136
|
+
)
|
|
4122
4137
|
: null,
|
|
4123
4138
|
intelPlans.length > 1
|
|
4124
4139
|
? h(
|
|
@@ -4346,6 +4361,13 @@ window.__ModuleLoader__.load({
|
|
|
4346
4361
|
)
|
|
4347
4362
|
: null,
|
|
4348
4363
|
),
|
|
4364
|
+
draft.quality && Number.isFinite(Number(draft.quality.score))
|
|
4365
|
+
? h(
|
|
4366
|
+
'div',
|
|
4367
|
+
{ className: 'sf-intel-meta' },
|
|
4368
|
+
h('span', { className: 'sf-badge' }, t('intelDraftQuality') + ': ' + draft.quality.score + ' (' + String(draft.quality.grade || '') + ')'),
|
|
4369
|
+
)
|
|
4370
|
+
: null,
|
|
4349
4371
|
badgeRow(
|
|
4350
4372
|
[
|
|
4351
4373
|
h('span', { className: 'sf-intel-k', key: 'intel-safety-label' }, t('intelSafety')),
|
package/docs/claims.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
| 智能评测 | `test/fixtures/intelligence-cases.json` + `scripts/benchmark.mjs` | 60 条;数字见下 |
|
|
16
16
|
| 已安装推荐评测 | `docs/eval.md` + `scripts/eval-real.mjs` | 30 条,v2.7.2 工作树;需 v5 复跑 |
|
|
17
17
|
| 库检索评测 | `docs/eval.md` + `scripts/eval-discover.mjs` | 24 条,v2.8.1 工作树;需 v5 复跑 |
|
|
18
|
-
| 单元/集成测试 | `npm test` | **
|
|
18
|
+
| 单元/集成测试 | `npm test` | **125/125 通过**(2026-10-30) |
|
|
19
19
|
| Host E2E | `verify/host-e2e.mjs` | **20/20**(含 v5 端点) |
|
|
20
20
|
| UI E2E | `verify/ui-e2e.mjs` | **27/27** |
|
|
21
21
|
| DSH 兼容 | `docs/dsh-compatibility.md` | DSH Desktop 0.2.1-rc.3;安装/重启/迁移 |
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
| C3 | **installLoad 0.3**:计划中约 30.0% 技能需先安装;planCoverage 不是成功率、不是已装可用率 | 同上 | verified(必须一起引用) |
|
|
58
58
|
| C4 | hintRecall 0.45 是当前短板(AI 领域 0.00,多个领域 0.20);latency 是机器相关单次墙钟,不作为对外 SLA | `docs/benchmark.md` | verified |
|
|
59
59
|
| C5 | 已安装推荐 Recall@4 = 0.9(27/30)、discover Hit@5 0.958 等为旧版半人工基线 | `docs/eval.md` | needs-human(v5 复跑) |
|
|
60
|
-
| C6 |
|
|
60
|
+
| C6 | 真实任务 A/B(12 条) | `scripts/benchmark-live.mjs` + `docs/benchmark-live.md` | **awaiting-real-runs**(工具已交付,未运行) |
|
|
61
|
+
| C7 | 效率提升百分比 | `efficiencyEstimate` 只给 `method:'estimate'`;benchmark 不测真实任务 token 节省 | **unsupported**(禁止写具体百分比) |
|
|
61
62
|
|
|
62
63
|
### D. v5 新能力(已交付)
|
|
63
64
|
|
|
@@ -74,7 +75,7 @@
|
|
|
74
75
|
|
|
75
76
|
| # | 事项 | 状态 |
|
|
76
77
|
|---|---|---|
|
|
77
|
-
| E1 | 测试数 55/57 旧冲突 | 已统一为 **
|
|
78
|
+
| E1 | 测试数 55/57 旧冲突 | 已统一为 **125/125**(2026-10-30);发布前以 `npm test` 为准 |
|
|
78
79
|
| E2 | README 版本 3.0.0 | 已改为 v5.0.0;发布前与 package/tag 同步 |
|
|
79
80
|
| E3 | 技能条数 vs 仓库数 | 已分开写:6,399 条技能 / 4,007 仓库 |
|
|
80
81
|
| E4 | 索引 vs stars 快照日期 | 已分别标注 2026-10-28 / 2026-10-30 |
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
# npm(推荐)
|
|
10
|
-
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.
|
|
10
|
+
plugin_manager install_bundle target=dsh-ronge-adaptive-skill-archive@5.3.0
|
|
11
11
|
|
|
12
12
|
# GitHub tag(固定版本、可审源码)
|
|
13
|
-
plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.
|
|
13
|
+
plugin_manager install_bundle target=git+https://github.com/bugtakue/dsh-ronge-adaptive-skill-archive.git#v5.3.0
|
|
14
14
|
|
|
15
15
|
# 本地目录(开发)
|
|
16
16
|
plugin_manager install_bundle target=/absolute/path/to/dsh-ronge-adaptive-skill-archive
|
|
@@ -38,11 +38,11 @@ plugin_manager install_bundle target=/absolute/path/to/dsh-ronge-adaptive-skill-
|
|
|
38
38
|
|
|
39
39
|
## 已验证
|
|
40
40
|
|
|
41
|
-
- `npm test`:
|
|
41
|
+
- `npm test`:125/125(含 DSH 兼容性静态检查)
|
|
42
42
|
- Host E2E:20/20(真实 loopback HTTP + raw.githubusercontent.com)
|
|
43
43
|
- UI E2E:27/27
|
|
44
44
|
- `npm run check:dsh`:manifest / factory id / slots / routes / 数据迁移 / market index 全部通过
|
|
45
|
-
- npm registry 安装 v3.0.0 历史验证;v5.
|
|
45
|
+
- npm registry 安装 v3.0.0 历史验证;v5.3.0 发布后以 registry 为准;市场索引 format 1 托管在 `https://bugtakue.github.io/dsh-ronge-adaptive-skill-archive/plugin-market.json`
|
|
46
46
|
|
|
47
47
|
## 已知边界
|
|
48
48
|
|
package/index.js
CHANGED
|
@@ -3247,7 +3247,7 @@ function loadCapabilityIndex() {
|
|
|
3247
3247
|
}
|
|
3248
3248
|
|
|
3249
3249
|
async function loadIntelligence() {
|
|
3250
|
-
if (!intelligenceModule) intelligenceModule = await import('./lib/intelligence/index.js')
|
|
3250
|
+
if (!intelligenceModule) intelligenceModule = await import('./lib/intelligence/index.js?v=' + encodeURIComponent(PKG_VERSION))
|
|
3251
3251
|
return intelligenceModule
|
|
3252
3252
|
}
|
|
3253
3253
|
|
|
@@ -673,6 +673,16 @@ export function composeSkillPlan(input = {}) {
|
|
|
673
673
|
|
|
674
674
|
const coverageRatio = selection.required.length ? selection.covered.size / selection.required.length : 1
|
|
675
675
|
const criticalMissing = missing.filter((entry) => entry.critical).length
|
|
676
|
+
const reviewGapSuggestions = reviewGap
|
|
677
|
+
? pool
|
|
678
|
+
.filter((candidate) => !candidate.installed)
|
|
679
|
+
.filter((candidate) => {
|
|
680
|
+
const caps = candidate.profile.capabilities || []
|
|
681
|
+
return ['code-review', 'security-audit', 'fact-checking', 'layout-review', 'contract-review', 'testing'].some((capability) => caps.includes(capability))
|
|
682
|
+
})
|
|
683
|
+
.slice(0, 3)
|
|
684
|
+
.map((candidate) => candidate.name)
|
|
685
|
+
: []
|
|
676
686
|
const cleanStages = trimStages(stages, maxSkills, 5)
|
|
677
687
|
const estimates = {
|
|
678
688
|
efficiency: efficiencyEstimate({
|
|
@@ -704,6 +714,7 @@ export function composeSkillPlan(input = {}) {
|
|
|
704
714
|
ok: cleanStages.length > 0,
|
|
705
715
|
ready: cleanStages.length > 0 && criticalMissing === 0 && missing.length === 0,
|
|
706
716
|
reviewGap,
|
|
717
|
+
reviewGapSuggestions,
|
|
707
718
|
pattern: ALLOWED_PATTERNS.has(pattern) ? pattern : 'sequential',
|
|
708
719
|
stages: cleanStages,
|
|
709
720
|
missing,
|
|
@@ -306,6 +306,21 @@ function resolveContext(input) {
|
|
|
306
306
|
* metadata, never writes or executes anything.
|
|
307
307
|
* @param {{task?:string, plan?:object, missing?:object[], existingNames?:string[], context?:string}} input
|
|
308
308
|
*/
|
|
309
|
+
function draftScore({ lint, safety, evalCases, content, name }) {
|
|
310
|
+
let score = 100
|
|
311
|
+
const issues = lint && Array.isArray(lint.issues) ? lint.issues : []
|
|
312
|
+
score -= issues.filter((issue) => issue && issue.severity === 'error').length * 20
|
|
313
|
+
score -= issues.filter((issue) => issue && issue.severity === 'warn').length * 5
|
|
314
|
+
if (!content || content.length < 500) score -= 15
|
|
315
|
+
if (!Array.isArray(evalCases) || evalCases.length < 3) score -= 10
|
|
316
|
+
if (safety && safety.available && safety.level === 'high') score -= 60
|
|
317
|
+
else if (safety && safety.available && safety.level === 'medium') score -= 15
|
|
318
|
+
if (!name || name.length < 6) score -= 10
|
|
319
|
+
score = Math.max(0, Math.min(100, Math.round(score)))
|
|
320
|
+
const grade = score >= 85 ? 'A' : score >= 70 ? 'B' : score >= 55 ? 'C' : 'D'
|
|
321
|
+
return { score, grade }
|
|
322
|
+
}
|
|
323
|
+
|
|
309
324
|
export function draftSkill(input = {}) {
|
|
310
325
|
const { plan, task, decomposition } = resolveContext(input)
|
|
311
326
|
const missing = Array.isArray(input.missing) && input.missing.length
|
|
@@ -430,9 +445,11 @@ export function draftSkill(input = {}) {
|
|
|
430
445
|
})
|
|
431
446
|
const safety = runSecurityScan(content)
|
|
432
447
|
const similar = findSimilarNames(name, existingNames)
|
|
448
|
+
const quality = draftScore({ lint, safety, evalCases, content, name })
|
|
433
449
|
|
|
434
450
|
return {
|
|
435
451
|
ok: lint.ok && !(safety.available && safety.level === 'high'),
|
|
452
|
+
quality,
|
|
436
453
|
name,
|
|
437
454
|
description,
|
|
438
455
|
whenToUse,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ronge-adaptive-skill-archive",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "DSH-native skill intelligence cockpit: task decomposition, cross-domain multi-skill composition, skill authoring, local recommendations and safety scans for DeepSeek Harness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Live A/B protocol for task-level evidence. This script NEVER fabricates
|
|
4
|
+
* model runs: it either prints the protocol or aggregates records produced by
|
|
5
|
+
* a real DSH run.
|
|
6
|
+
*
|
|
7
|
+
* usage:
|
|
8
|
+
* node scripts/benchmark-live.mjs --dry-run
|
|
9
|
+
* node scripts/benchmark-live.mjs --record runs.json --out report.json
|
|
10
|
+
*
|
|
11
|
+
* run record shape:
|
|
12
|
+
* [{ taskId, arm: "baseline"|"plugin", success: true, tokens: 12000,
|
|
13
|
+
* toolCalls: 8, wallMs: 45000, notes: "..." }]
|
|
14
|
+
*/
|
|
15
|
+
import fs from 'node:fs'
|
|
16
|
+
import path from 'node:path'
|
|
17
|
+
import { fileURLToPath } from 'node:url'
|
|
18
|
+
|
|
19
|
+
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
20
|
+
const TASKS_FILE = path.join(ROOT, 'test', 'fixtures', 'live-ab-tasks.json')
|
|
21
|
+
const args = process.argv.slice(2)
|
|
22
|
+
const flag = (name) => args.indexOf(name)
|
|
23
|
+
const value = (name) => (flag(name) >= 0 ? args[flag(name) + 1] : null)
|
|
24
|
+
const tasks = JSON.parse(fs.readFileSync(TASKS_FILE, 'utf8'))
|
|
25
|
+
const dryRun = flag('--dry-run') >= 0
|
|
26
|
+
const recordFile = value('--record')
|
|
27
|
+
const outFile = value('--out')
|
|
28
|
+
|
|
29
|
+
if (!dryRun && !recordFile) {
|
|
30
|
+
console.error('use --dry-run to print the protocol, or --record <file> to aggregate real run records')
|
|
31
|
+
process.exit(1)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function aggregate(records) {
|
|
35
|
+
const byArm = {}
|
|
36
|
+
for (const arm of ['baseline', 'plugin']) {
|
|
37
|
+
const rows = records.filter((record) => record.arm === arm)
|
|
38
|
+
const success = rows.filter((record) => record.success === true).length
|
|
39
|
+
const sum = (key) => rows.reduce((total, record) => total + (Number(record[key]) || 0), 0)
|
|
40
|
+
byArm[arm] = {
|
|
41
|
+
runs: rows.length,
|
|
42
|
+
successRate: rows.length ? Math.round((success / rows.length) * 1000) / 1000 : null,
|
|
43
|
+
meanTokens: rows.length ? Math.round(sum('tokens') / rows.length) : null,
|
|
44
|
+
meanToolCalls: rows.length ? Math.round((sum('toolCalls') / rows.length) * 10) / 10 : null,
|
|
45
|
+
meanWallMs: rows.length ? Math.round(sum('wallMs') / rows.length) : null,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return byArm
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (dryRun) {
|
|
52
|
+
const protocol = {
|
|
53
|
+
schema: 'skill-intelligence-live-ab/v1',
|
|
54
|
+
status: 'awaiting-real-runs',
|
|
55
|
+
tasks: tasks.length,
|
|
56
|
+
arms: ['baseline', 'plugin'],
|
|
57
|
+
instruction: 'Run each task twice (same model, same tools, same time budget). Arm "baseline" = no skill archive tools/panel; arm "plugin" = use skill_archive_plan then execute. Record success/tokens/toolCalls/wallMs per run.',
|
|
58
|
+
tasksDetail: tasks,
|
|
59
|
+
recordShape: { taskId: 'video-01', arm: 'baseline|plugin', success: true, tokens: 12000, toolCalls: 8, wallMs: 45000, notes: 'evidence' },
|
|
60
|
+
note: 'No numbers are produced until a real run is recorded; this script does not call a model.',
|
|
61
|
+
}
|
|
62
|
+
console.log(JSON.stringify(protocol, null, 2))
|
|
63
|
+
process.exit(0)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const raw = JSON.parse(fs.readFileSync(path.resolve(process.cwd(), recordFile), 'utf8'))
|
|
67
|
+
if (!Array.isArray(raw)) throw new Error('record file must be a JSON array')
|
|
68
|
+
const taskIds = new Set(tasks.map((task) => task.id))
|
|
69
|
+
for (const record of raw) {
|
|
70
|
+
if (!record || !taskIds.has(record.taskId)) throw new Error('unknown taskId: ' + JSON.stringify(record && record.taskId))
|
|
71
|
+
if (record.arm !== 'baseline' && record.arm !== 'plugin') throw new Error('arm must be baseline or plugin')
|
|
72
|
+
}
|
|
73
|
+
const report = {
|
|
74
|
+
schema: 'skill-intelligence-live-ab/v1',
|
|
75
|
+
status: 'recorded',
|
|
76
|
+
generatedAt: new Date().toISOString(),
|
|
77
|
+
tasks: tasks.length,
|
|
78
|
+
records: raw.length,
|
|
79
|
+
arms: aggregate(raw),
|
|
80
|
+
caveat: 'Task-level A/B; success is human/rubric reviewed, tokens/time are runner-reported. Do not compare across models or task sets.',
|
|
81
|
+
}
|
|
82
|
+
if (outFile) fs.writeFileSync(path.resolve(process.cwd(), outFile), JSON.stringify(report, null, 2) + '\n')
|
|
83
|
+
console.log(JSON.stringify(report, null, 2))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{"id":"video-01","domain":"video","task":"做一条 30 秒产品发布宣传片,竖屏,带字幕和配乐","deliverable":"mp4","checks":["时长 30±3 秒","竖屏 1080x1920","字幕与音频同步"]},
|
|
3
|
+
{"id":"video-02","domain":"video","task":"把这段培训录屏剪成 2 分钟横屏视频,加章节标题","deliverable":"mp4","checks":["横屏 1920x1080","章节标题出现","导出可播放"]},
|
|
4
|
+
{"id":"office-01","domain":"office","task":"把会议录音整理成 Word 纪要,含决议、行动项和负责人","deliverable":"docx","checks":["有决议/行动项/负责人","docx 可打开","无占位符"]},
|
|
5
|
+
{"id":"office-02","domain":"office","task":"把 Excel 销售数据做成 8 页发布 PPT,带图表和结论","deliverable":"pptx","checks":["8 页左右","至少 2 张图表","结论页存在"]},
|
|
6
|
+
{"id":"office-03","domain":"office","task":"检查这份 docx 合同的金额、日期和付款条款是否一致","deliverable":"docx-report","checks":["逐条列出差异","金额/日期有出处","风险项标注"]},
|
|
7
|
+
{"id":"code-01","domain":"coding","task":"修复 React 组件测试失败并补一个回归测试","deliverable":"code","checks":["测试通过","新增回归用例","说明根因"]},
|
|
8
|
+
{"id":"data-01","domain":"data","task":"分析这份 CSV 的月度趋势,输出图表和三条结论","deliverable":"report","checks":["图表可打开","结论有数字支撑","口径说明"]},
|
|
9
|
+
{"id":"research-01","domain":"research","task":"调研 2026 年 AI 视频工具市场,给出 5 个来源和对比","deliverable":"report","checks":["至少 5 个来源","有对比维度","引用可访问"]},
|
|
10
|
+
{"id":"marketing-01","domain":"marketing","task":"为新品写一版小红书种草文案,含 3 个卖点和行动号召","deliverable":"text","checks":["3 个卖点","有 CTA","符合平台语气"]},
|
|
11
|
+
{"id":"security-01","domain":"security","task":"审查一个第三方 SKILL.md 的安装脚本风险,重点看 shell 与凭据","deliverable":"report","checks":["列出风险级别","有复现/证据","给修复建议"]},
|
|
12
|
+
{"id":"plugin-01","domain":"engineering","task":"做一个 DSH 面板插件,加一个设置项并验证安装/卸载","deliverable":"code","checks":["插件可启用","设置项生效","可卸载"]},
|
|
13
|
+
{"id":"productivity-01","domain":"productivity","task":"把本周零散笔记整理成周报,附下周三个优先事项","deliverable":"docx","checks":["结构完整","三个优先级","无虚构事实"]}
|
|
14
|
+
]
|