{"_id":"@buddhilive/dsh-session-stats","name":"@buddhilive/dsh-session-stats","dist-tags":{"alpha":"0.1.2-alpha.3","latest":"0.1.2-alpha.3"},"versions":{"0.1.2-alpha.3":{"name":"@buddhilive/dsh-session-stats","description":"Whole-log conversation counts and wall times projection (sessionStats) for the DeepSeek Harness","version":"0.1.2-alpha.3","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/session/session-stats"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./types":{"types":"./lib/types/types.d.ts","default":"./lib/types/types.js"},"./client":{"types":"./lib/types/client.d.ts","default":"./lib/types/client.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","peerDependencies":{"@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@buddhilive/dsh-llm":"^0.1.2-alpha.3","@buddhilive/dsh-session":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2","@buddhilive/dsh-session-projection":"^0.1.2-alpha.3"},"dependencies":{"zod":"^4.4.3"},"devDependencies":{"@deepseek-ai/cordis-plugin-include":"^1.0.7","@buddhilive/dsh-llm":"^0.1.2-alpha.3","@buddhilive/dsh-invariants":"^0.1.2-alpha.3","@deepseek-ai/cordis-plugin-loader":"^1.0.3","@buddhilive/dsh-session":"^0.1.2-alpha.3","@deepseek-ai/cordis":"^4.0.2","@buddhilive/dsh-session-projection":"^0.1.2-alpha.3"},"_id":"@buddhilive/dsh-session-stats@0.1.2-alpha.3","bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","_integrity":"sha512-K1i4HCAnNJ8FW8LO7R6+GsNv5MfD1WvbLrUZf/HKhPYf0L7edH0C/ewIIU2v2RyDhurFbPtNQf2wPXvPmh9UOA==","_resolved":"C:\\DevDojo\\Buddhi\\buddhi-ai-harness\\dist\\npm\\buddhilive-dsh-session-stats-0.1.2-alpha.3.tgz","_from":"file:C:/DevDojo/Buddhi/buddhi-ai-harness/dist/npm/buddhilive-dsh-session-stats-0.1.2-alpha.3.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-K1i4HCAnNJ8FW8LO7R6+GsNv5MfD1WvbLrUZf/HKhPYf0L7edH0C/ewIIU2v2RyDhurFbPtNQf2wPXvPmh9UOA==","shasum":"a589b5bcc59e077636b55747f080a77a5bab226e","tarball":"https://registry.npmjs.org/@buddhilive/dsh-session-stats/-/dsh-session-stats-0.1.2-alpha.3.tgz","fileCount":17,"unpackedSize":46163,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDD3WLsIO3i5I5p3pLJvPNZ1/BZEil6IPflxKTvbL7j8AiEAhV8sCScsScppG4PV+LtePzuMTmGgsss6TjKoqLIB5yg="}]},"_npmUser":{"name":"buddhilive","email":"visitbudkavin@gmail.com"},"directories":{},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-session-stats_0.1.2-alpha.3_1788166641746_0.12602213847017385"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T08:57:21.509Z","0.1.2-alpha.3":"2026-08-31T08:57:21.894Z","modified":"2026-08-31T08:57:22.176Z"},"maintainers":[{"name":"buddhilive","email":"visitbudkavin@gmail.com"}],"description":"Whole-log conversation counts and wall times projection (sessionStats) for the DeepSeek Harness","homepage":"https://github.com/Buddhilive/buddhi-ai-harness#readme","repository":{"type":"git","url":"git+https://github.com/Buddhilive/buddhi-ai-harness.git","directory":"packages/session/session-stats"},"bugs":{"url":"https://github.com/Buddhilive/buddhi-ai-harness/issues"},"license":"MIT","readme":"---\ndescription: \"面向客户端与维护者的全日志会话计数与墙钟时间说明，用于选择、组合或排查 sessionStats 投影单元。\"\nkind: \"package-reference\"\n---\n\n# @buddhilive/dsh-session-stats\n\n[English](README.md) | 中文\n\n## 概述\n\n`dsh-session-stats` 提供全日志会话数字——轮/步计数以及 LLM、工具、首 token、解码墙钟时间——以 `sessionStats` 投影单元的形式对外提供。客户端从注册表的快照与变更流中读取数字，且由于它们从完整持久日志折叠而来，分页或压缩都无法改变它们。在已挂载投影注册表的组合中选择它，例如 Web 聊天包（其统计条是参考消费者）；没有注册表的装配不受影响，其消费者回退到窗口口径计数。设置与字段语义在前；折叠内部细节放在下方可折叠的开发者章节中。\n\n## 目录\n\n- [使用本包](#use-this-package)\n- [理解实现](#understand-the-implementation)\n- [进一步探索](#further-exploration)\n- [模型体验](#model-experience)\n- [已知限制与延期工作](#known-limitations-and-deferred-work)\n- [开发备注](#dev-note)\n\n-----\n\n<a id=\"use-this-package\"></a>\n## 使用本包\n\n当客户端需要显示不受分页与压缩影响的全会话数字时，在会话存储与投影注册表旁挂载此插件。只有存在注册表时单元才会注册。\n\n### 组合\n\n```yaml\n- name: '@buddhilive/dsh-session'\n- name: '@buddhilive/dsh-session-projection'\n- name: '@buddhilive/dsh-session-stats'\n```\n\n### 各字段含义\n\n| 字段 | 含义 |\n|---|---|\n| `turns` | 含至少一个已关闭步的不同轮次；被拒绝或空轮不计 |\n| `steps` | 已关闭的步——完成、失败、取消与 max-tokens 的步全部计入 |\n| `llmMs` | 组装出消息的步的模型墙钟时间之和 |\n| `toolMs` | 匹配的 `tool/call` → `tool/result` 墙钟时间之和 |\n| `ttftMs` / `ttftSteps` | 首 token 延迟之和及其承载步数 |\n| `decodeMs` / `decodeTokens` | 上报用量的步的解码墙钟时间与提供方输出 token 之和 |\n\n每个字段在首个贡献事件之前均为 0；已装配的注册表恒提供该键，因此客户端读取值本身，而非键的存在性。客户端通过投影 seam 的快照与变更流渲染全日志数字；参考消费者是 Web 聊天统计条，其窗口折叠以相同字段名充当无单元时的回退。\n\n### 失败与恢复\n\n没有投影注册表时单元是惰性的：`inject` 使 fiber 保持挂起，不注册任何内容，因此其他装配缺少 `sessionStats` 键。卸载插件会移除该键，因为注册是挂载 fiber 上的 effect。被崩溃打断的步在会话重新加载后计入，届时崩溃恢复补写合成的 `step/end`。\n\n-----\n\n<a id=\"understand-the-implementation\"></a>\n## 理解实现\n\n<details>\n<summary>实现细节——点击展开</summary>\n\n本节解释数字背后的折叠；可观察行为已在[使用本包](#use-this-package)中完整说明。\n\n### 设计理念\n\n该单元是对已提交会话事件的纯折叠：`step/end` 是被计数的步事件，因为 agent loop 对每个进入的步在 `finally` 中恰好追加一条，因此完成、失败、取消与 max-tokens 的步都会落地一条。若改按已组装的 assistant 消息计数，则会多算 max-tokens 的 usage 宿主消息（空内容、被排除在 surface 之外），并少算被取消的步（在消息组装前已中止）。墙钟折叠逐字段对齐客户端窗口折叠。\n\n### 源码地图\n\n| 文件 | 职责 |\n|---|---|\n| [`src/index.ts`](src/index.ts) | 插件入口：`inject`、在挂载 fiber 上注册单元 |\n| [`src/projection.ts`](src/projection.ts) | 折叠：状态形状、逐事件转换、wire 视图 |\n| [`src/types.ts`](src/types.ts) | `sessionStats` 投影键声明与字段类型的唯一归属 |\n\n### 数据模型\n\n折叠状态保存八个总计外加进行中的边界：`lastTurn`（最近一次被计数 `step/end` 的轮次）、`openStep`（打开步的边界事实，由其 `assistant/message` 关闭）与 `pendingCalls`（按 callId 记录的工具分发时间）。wire 视图是严格子集——八个总计——因此持久缓存的状态 schema 以边界字段扩展视图 schema。\n\n### 折叠规则\n\n- 不相关事件返回同一状态引用；注册表的 `Object.is` 门禁保持变更流安静。\n- 首 token 延迟记录首个非空 delta chunk，并在步内 `llm/retry` 后保留。\n- 解码时间与 token 只在同时携带首 token 与有效提供方用量报告的步上累加；与窗口折叠守卫节点用量一样忽略畸形用量。\n- 工具时间按 callId 配对 `tool/call` → `tool/result`；未解决的调用在 `turn/end` 时丢弃，因为结果总在其轮内落地，而撞上 `Object` 原型名的 callId 读作未匹配。\n\n</details>\n\n-----\n\n<a id=\"further-exploration\"></a>\n## 进一步探索\n\n当单元约定不够用时阅读以下页面。它们从驱动单元的注册表逐步进入相邻的会话包。\n\n- [会话投影子系统](../../../docs/subsystems/session-projection.zh.md)——驱动单元并提供快照与变更流值的注册表。\n- [会话投影注册表包](../session-projection/README.zh.md)——单元注册所依据的注册表约定。\n- [会话包映射](../README.zh.md)——相邻的持久化、投影、标题与遥测包。\n\n-----\n\n<a id=\"model-experience\"></a>\n## 模型体验\n\n无，因为 sessionStats 单元把已写入日志的步边界折叠成面向客户端的读模型，不注册任何面向模型的内容。\n\n#### KV Cache 影响\n\n无；本包从不组装或发送提供方请求。\n\n## 已知限制与延期工作\n\n<a id=\"known-limitations-and-deferred-work\"></a>\n\n\n这些限制说明数字描述什么、单元何时缺失。它们是当前包约束。\n\n- **步数统计的是已发生的工作，而非可见输出**——在产生任何可见内容前就失败的步仍以 `step/end` 关闭并计入；被崩溃打断的步在会话重新加载后计入，届时崩溃恢复补写合成的 `step/end`。\n- **被取消的步计数但不计时**——没有组装出 assistant 消息，其部分流式时间不进入任何墙钟数字；反之 max-tokens 的 usage 宿主消息贡献 surface 上看不到的模型时间。\n- **计数是日志口径，不是 surface 口径**——消息后来被压缩掉的步仍然计入；数字描述整个会话，而非当前模型可见 surface。\n- **仅在组合了投影注册表时挂载**——其他装配不提供 `sessionStats` 键，其消费者回退到窗口口径计数。\n\n<a id=\"dev-note\"></a>\n### 开发备注\n\n<details>\n<summary>维护者的工作上下文——点击展开</summary>\n\n无。\n\n</details>\n","readmeFilename":"README.zh.md","_rev":"1-aaba74f71861dd64d5e7edc331010eeb"}