@marsken/dsh-studio 0.1.12 → 0.1.14
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 +1 -1
- package/client.js +25 -25
- package/dist/client.js +25 -25
- package/docs/compatibility.md +1 -1
- package/docs/publish.md +2 -0
- package/package.json +1 -1
- package/src/host/dispatcher.js +1 -1
- package/src/host/quality.js +1 -1
- package/src/host/session-usage.js +11 -2
package/docs/compatibility.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
| 项 | 值 |
|
|
8
8
|
| --- | --- |
|
|
9
|
-
| dsh-studio | `package.json` `version: 0.1.
|
|
9
|
+
| dsh-studio | `package.json` `version: 0.1.14` |
|
|
10
10
|
| DeepSeek Harness | `0.2.2-rc.1`(`dsh --version`) |
|
|
11
11
|
| Node | `v24.22.2`(Linux 目标机);本机 Windows `v24.19.0` |
|
|
12
12
|
| 目标系统 | Ubuntu 24.04,`dsh web` 监听 `18080`,nginx `:80` 反代并注入 `dsh-auth-*` cookie |
|
package/docs/publish.md
CHANGED
|
@@ -127,6 +127,8 @@ token 只写进临时 npmrc(放在仓库外或 `tmp/` 且不提交),发完
|
|
|
127
127
|
| --- | --- | --- |
|
|
128
128
|
| `0.1.0` | 2026-11-13 | 首个公开版:看板 / 需求 / 用例回归 / 效能 / 设计评审四期 |
|
|
129
129
|
| `0.1.1` | 2026-11-13 | 补三张 README 截图(npm 页可看图);默认值与文档去掉公司内网信息 |
|
|
130
|
+
| `0.1.14` | 2026-11-15 | 修正成本口径的过期文案 |
|
|
131
|
+
| `0.1.13` | 2026-11-15 | 价目表编辑器 + 未配价目模型清单 |
|
|
130
132
|
| `0.1.12` | 2026-11-15 | 真实 token 成本(读会话日志 + 价目表计价) |
|
|
131
133
|
| `0.1.11` | 2026-11-15 | 需求变更影响面(接口 + 面板)、可跑用例口径修正、成本口径文档 |
|
|
132
134
|
| `0.1.10` | 2026-11-15 | shell/db 用例可跑、GitLab 核对结果常驻显示、事件带 truncated、角色归并 |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marsken/dsh-studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "DSH Studio: role-based multi-agent workspace (product / architect / developer / QA) with a live work board, GitLab + Feishu connection settings, all configurable from the web GUI.",
|
|
6
6
|
"main": "index.js",
|
package/src/host/dispatcher.js
CHANGED
|
@@ -295,7 +295,7 @@ export function runSummary() {
|
|
|
295
295
|
byModel: sort(byModel),
|
|
296
296
|
byPromptVersion: sort(byPrompt),
|
|
297
297
|
days: [...byDay.values()].sort((a, b) => (a.day < b.day ? -1 : 1)).slice(-14),
|
|
298
|
-
note: '
|
|
298
|
+
note: 'token 用量读自 studio-* 会话日志(每次模型调用都记一次);钱要显示得先在「成本与预算」里配价目表,没配的模型会单独列出来。',
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
package/src/host/quality.js
CHANGED
|
@@ -118,7 +118,7 @@ export function buildQuality(state, runs) {
|
|
|
118
118
|
},
|
|
119
119
|
cost: {
|
|
120
120
|
wired: false,
|
|
121
|
-
note: '
|
|
121
|
+
note: '成本按真实 token 用量算:读 studio-* 会话日志,按卡 / 按专家汇总;价目表没配时只给 token,花费显示未知。',
|
|
122
122
|
},
|
|
123
123
|
}
|
|
124
124
|
}
|
|
@@ -5,7 +5,7 @@ import { promisify } from 'node:util'
|
|
|
5
5
|
import { readdir, stat } from 'node:fs/promises'
|
|
6
6
|
import { homedir } from 'node:os'
|
|
7
7
|
import { join } from 'node:path'
|
|
8
|
-
import { parseUsageLines, summarizeUsage } from './usage.js'
|
|
8
|
+
import { isSubscriptionModel, parseUsageLines, priceOf as priceOfModel, summarizeUsage } from './usage.js'
|
|
9
9
|
|
|
10
10
|
const run = promisify(execFile)
|
|
11
11
|
const CACHE = new Map()
|
|
@@ -59,13 +59,21 @@ export async function collectSessionUsage(root = sessionsRoot()) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/** 按卡 / 按专家汇总 token 与钱;prices 来自 config.costs.prices。 */
|
|
62
|
-
export function aggregateUsage(sessions, tasks, prices, costOf) {
|
|
62
|
+
export function aggregateUsage(sessions, tasks, prices, costOf, priceOf) {
|
|
63
|
+
const unpriced = new Map()
|
|
63
64
|
const byCard = new Map()
|
|
64
65
|
const byExpert = new Map()
|
|
65
66
|
const totals = { calls: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
66
67
|
for (const session of sessions) {
|
|
67
68
|
const summary = summarizeUsage(session.usage)
|
|
68
69
|
const money = costOf(prices, session.usage)
|
|
70
|
+
// 哪些模型还没配价目:直接告诉用户要补哪几行,比只说「719 次未知」有用
|
|
71
|
+
for (const item of session.usage) {
|
|
72
|
+
const model = String(item.model ?? '(未记录模型)')
|
|
73
|
+
if (priceOfModel(prices, item.model) !== null) continue
|
|
74
|
+
if (isSubscriptionModel(item.model)) continue
|
|
75
|
+
unpriced.set(model, (unpriced.get(model) ?? 0) + 1)
|
|
76
|
+
}
|
|
69
77
|
for (const key of ['calls', 'input', 'output', 'cacheRead', 'cacheWrite', 'total']) totals[key] += summary[key]
|
|
70
78
|
const card = byCard.get(session.taskId) ?? { taskId: session.taskId, ...{ calls: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, cost: 0, unknownCalls: 0 }
|
|
71
79
|
for (const key of ['calls', 'input', 'output', 'cacheRead', 'cacheWrite', 'total']) card[key] += summary[key]
|
|
@@ -95,6 +103,7 @@ export function aggregateUsage(sessions, tasks, prices, costOf) {
|
|
|
95
103
|
unknownCalls: cards.reduce((sum, card) => sum + card.unknownCalls, 0),
|
|
96
104
|
},
|
|
97
105
|
cards: cards.slice(0, 50),
|
|
106
|
+
unpricedModels: [...unpriced.entries()].map(([model, calls]) => ({ model, calls })).sort((a, b) => b.calls - a.calls).slice(0, 10),
|
|
98
107
|
experts: [...byExpert.values()].map((row) => ({ ...row, cost: round(row.cost) })).sort((a, b) => b.total - a.total),
|
|
99
108
|
}
|
|
100
109
|
}
|