dsh-plugin-usage 0.2.0 → 0.2.2

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 CHANGED
@@ -89,12 +89,25 @@ dsh web --patch /path/to/dsh-plugin-usage/cordis.yml
89
89
 
90
90
  插件**不自己记录原始日志**,而是折叠 DSH 已持久化的会话日志:
91
91
 
92
- - DSH 的 agent loop 会把每次模型调用的用量以 `assistant/message` 会话事件(携带 `usage`:输入/输出/缓存命中/缓存创建 Token 与 `message.source.{provider,model}`)写入会话日志(`~/.dsh/sessions/`)。
93
- - 插件启动时**回填(backfill)全部历史会话**,之后每 2s 增量扫描活跃会话(内存),每 30s 增量扫描持久化会话(按 seq 水位)。
94
- - 覆盖范围:所有 agent loop 调用(含子代理)。compaction / session-title 等辅助调用不写入会话日志,不在统计范围内。
95
- - 去重:按会话内 `(turn, step)` 去重——同一 `(turn, step)` 的后续用量事件**替换**先前样本,而不是重复累计。
92
+ - DSH 的 agent loop 把每次模型调用的用量写进会话日志:`assistant/message` 携带
93
+ `usage`(输入/输出/缓存命中/缓存创建 Token)与 `message.source.{provider,model}`;
94
+ 重试或失败但已计费的调用记为 `assistant/attempt`(无 `usage` 字段,usage 在其
95
+ `stream` 的最后一个 `usage` chunk 里)。日志是 v4 zstd(`~/.dsh/sessions/**/session.v4.jsonl.zstd`)。
96
+ - 读取走官方 0.2.x 访问器:活跃会话 `ctx.sessions.list()` + `session.snapshotEvents(seq)`;
97
+ 持久化会话 `ctx.sessionPersistence.list()`(`{header, revision, eventCount?}`)+
98
+ `open(id, 'read')` → `handle.read(offset)`,并按 `revision` 跳过未变更的日志。
99
+ - 启动时**回填(backfill)全部历史会话**,之后每 2s 扫描活跃会话、每 30s 扫描持久化会话
100
+ (按 seq 水位 + revision)。
101
+ - 覆盖范围:所有 agent loop 调用(含子代理)。compaction / session-title 等辅助调用不写入
102
+ 会话日志,不在统计范围内。
103
+ - 计费口径对齐官方 `tokenUsage` 投影:同一 `(turn, step)` 的后续样本**替换**先前样本;
104
+ 但 `llm/retry-started` 之后的重试是新的计费调用,**累加**。fork 会话按
105
+ `inheritedEventCount` 跳过父会话前缀,不重复计费。
106
+ - 无 `message.source` 的结算按最近的 `request/context` / `request/header` 路由归因。
96
107
  - 费用 = `(输入×输入价 + 输出×输出价 + 缓存命中×缓存命中价 + 缓存创建×缓存创建价) / 1e6`,价格表可改。
97
- - 价格表持久化:官方 DSH settings 服务可用时,价格表经 `usage.prices` settings 命名空间持久化(重启后保留,并出现在官方 Plugins 配置页);否则回退到进程内存(仅本次运行有效)。
108
+ - 价格表就是插件配置:`src/host/index.js` 导出 schemastery `Config`,DSH 在
109
+ Plugins 配置页生成表单并存入 profile patch(重启保留);客户端定价编辑走官方
110
+ `ctx.configForms.get('usage')`,不可用时回退 `usage/prices` RPC。
98
111
 
99
112
  > 动态插件形态下数据保存在进程内存中,重启后自动从会话日志重新回填,无需落盘文件。
100
113
 
@@ -104,13 +117,13 @@ dsh web --patch /path/to/dsh-plugin-usage/cordis.yml
104
117
  src/
105
118
  ├── host/
106
119
  │ ├── index.js Host 入口:接线 fold / scan / query / settings / aggregate / rpc / client-source,驱动定时扫描
107
- │ ├── settings.js 价格表 + 费用计算(内置 DeepSeek 常见模型默认价,可选 settings 命名空间持久化)
108
- │ ├── state.js 运行时状态:records / watermarks / backfill / dedup / index
120
+ │ ├── settings.js 价格表 + 费用计算(内置 DeepSeek 常见模型默认价,配置由 index.js 的 Config 承载)
121
+ │ ├── state.js 运行时状态:records / watermarks / revisions / lastSample / route / backfill / index
109
122
  │ ├── aggregate.js 增量聚合索引:add / remove / recordsInRange,供查询高效取数
110
- │ ├── fold.js 会话事件 → usage 记录(含会话内 (turn, step) 去重替换)
111
- │ ├── scan.js 启动回填 + 活跃/持久化会话的增量扫描(每 tick / 每 30s,按 seq 水位)
123
+ │ ├── fold.js 会话事件 → usage 记录(对齐官方 tokenUsage:替换槽、retry 累加、attempt/stream usage、路由归因)
124
+ │ ├── scan.js 启动回填 + 活跃/持久化会话增量扫描(0.2.x snapshotEvents / open+read,revision 跳过,水位修复)
112
125
  │ ├── query.js 聚合与查询:按天/按模型汇总、未定价检测、heatmap
113
- │ ├── rpc.js RPC 注册:usage/query、usage/prices、usage/client-source(动态 harness 与静态 connection 桥)
126
+ │ ├── rpc.js 传输注册:动态 harness / Typert 网关 / 静态安装的 Connection 共享 `/api` Fetch 路由(含旧版 `/usage` 前缀通道回退)
114
127
  │ ├── client-source.js 读取 src/client/index.js 实时提供给浏览器(动态插件形态)
115
128
  │ └── time.js 时间分桶:day/hour/minute 粒度与 step 网格(纯函数)
116
129
  ├── client/index.js Client half:设置页「用量统计」仪表盘(筛选/汇总卡/柱状图/模型表/定价配置),样式内联
@@ -129,12 +142,25 @@ npm test # node --test tests/
129
142
  ```
130
143
 
131
144
  `src/host/` 下的宿主逻辑(fold / scan / query / aggregate / time / settings 等)均为可直接
132
- import 的 ESM 模块,单元测试直接运行,无需启动 DSH harness。
145
+ import 的 ESM 模块,单元测试直接运行,无需启动 DSH harness。CI(Node 22/24)跑
146
+ install → build → test → bundle id 契约 → tarball 内容检查。
147
+
148
+ 兼容性:`engines.dsh` 声明 `>=0.2.0-rc.2 <0.3.0`(0.2.x 官方 API),更早版本依赖
149
+ `readFrom` / `Session.events` 回退路径。
133
150
 
134
151
  ## 说明 / Notes
135
152
 
136
153
  - 插件名 `usage`;动态插件运行在会话级,卸载后统计重新回填即可恢复。
137
- - 价格表持久化策略见「数据来源与口径」(官方 settings 可用时走 `usage.prices` 命名空间,否则进程内存回退)。
154
+ - 价格表持久化策略见「数据来源与口径」(插件 `Config` → 官方 Plugins 配置页 → profile patch;
155
+ 0.2.x 没有可用的 `settingsScope` / `settings.register`,旧路径已删除)。
156
+ - 静态安装的传输:DSH 0.2+ 注册在 Connection 共享 `/api` 通道的 exact Fetch 路由上
157
+ (`POST /api/usage/query`、`/api/usage/prices`、`/api/usage/client-source`,请求体为
158
+ args JSON,响应为 `{ ok, value }` / `{ ok, error }`);旧版宿主自动回退到 `/usage`
159
+ 前缀 RPC 通道。这条路由不依赖插件自身 fiber 注入 `webServer`——0.2.x 下后者会抛错并
160
+ 让通道静默消失(症状是查询一律 HTTP 405),见
161
+ [#1](https://github.com/bennett-dsh/dsh-plugin-usage/issues/1)。
162
+ - 客户端 bundle 的 loader id 在构建时取自 `package.json#name`,因此 scoped 名、
163
+ npm alias、`file:` tarball 等安装形态都能正常注册(不要手改 `lib/client/index.js`)。
138
164
 
139
165
  ## 开源协议 / License
140
166
 
package/image-1.png ADDED
Binary file
package/image.png ADDED
Binary file