dsh-task-timer:對話底部工作時長 pill 與側邊欄合計

前言

在 DeepSeek Harness(DSH)裏跑 agent,儀表盤已經能拆出模型時間、工具時間和 token,但「這條對話 agent 實際幹了多久」和「從首條消息到最後一動過了多久」仍是兩個不同問題。若把 ask_user_question 等你回答的整段都算進工具時間,掛機越久讀數越大,和直覺裏的「工作時長」對不上。側邊欄會話行右側若只顯示 55分鐘,也容易被讀成「跑了 55 分鐘」,而不是「55 分鐘前有過活動」。

下面介紹社區插件 dsh-task-timer(維護者 ShuaihuiMou,分類:客戶端)。它在對話底部 composer dock 增加帶時鐘圖標的工作時長 pill,在彈窗裏補充創建對話至今;在左側邊欄 Settings/用戶名行上方彙總全部對話合計使用時長與合計 token,並把工作區每條會話的時間補成與懸停卡一致的「N 前」讀法。插件以 MIT 許可證發佈,當前 npm 包版本 1.6.0,要求宿主 dsh >= 0.2.1-rc.5。

這是什麼

dsh-task-timer 是 DSH 的客戶端插件:宿主側註冊 taskTimer 會話投影,瀏覽器側向 conversation.composer.dock 與 sidebar.footer.action 注入 UI,不另開 RPC、不爲合計時長解壓全量歷史日誌。

社區目錄爲獨立站點,與 DeepSeek/幻方無官方從屬關係;安裝前請自行查看倉庫源碼與許可證。插件隨當前 DSH 進程權限運行。

核心功能

對話底部:工作時長 pill

pill 排在官方 activity(TPS)與 usage(Token)之後,主標籤格式爲「數值在前、名稱在後」,例如 51分24秒 · 工作時長。時長顯示規則:不足 1 分鐘顯示到 0.1 秒;不足 1 小時顯示分秒;滿 1 小時後顯示「X小時Y分」且不再顯示秒,分鐘不會溢出爲 60 分等寫法。

工作時長口徑與儀表盤 sessionStats 對齊,不再自行摺疊整份事件日誌:

工作時長 = llmMs + toolMs - awaitMs

llmMs、toolMs 直接取自儀表盤已在用的 sessionStats 投影。插件唯一自行累計的是 awaitMs:對 ask_user_question、request_user_input、exit_plan_mode(含 mcp__<server>__ask_user_question 等帶 MCP 前綴的副本)在 tool/call 到 tool/result 之間的跨度配對記賬,再從讀數中扣除。未結算的等待不扣;turn/end 時未結算的等待丟棄,與 sessionStats 一致。用戶輸入間隙、輪次間空閒本就不在 llmMs/toolMs 裏,無需再減。

早於 1.4.0 的版本曾把「等你回答」的時間算進工作時長;README 說明口徑修正後 pill 與側邊欄合計同步生效。工具審批彈窗在日誌中無對應事件,仍按工具時間計,爲已知邊界。

點擊 pill 打開彈窗:展示儀表盤沒有的 創建對話至今,以及僅在確有扣減時顯示的 已扣除等待回答。模型時間、工具時間不在彈窗重複——「N輪N步」pill 已分開列出。彈窗樣式優先複用 ui-chat 的 stat-dialog.module.css 類名,底色使用儀表盤卡片同款 bg-layer-2。

創建對話至今是牆鍾跨度:最後一次對話活動 - 對話內容起點。起點爲第一條承載對話內容的事件(非 header 的 createdAt;無內容事件時退回 createdAt);終點爲日誌裏最新一條推進對話的事件,不是 Date.now(),對話空閒時該數停住,有新活動再前移。打開彈窗時立即刷新,打開期間每秒 tick;收起後每分鐘輪詢,對話已空閒且追上終點時不啓秒級定時器。

側邊欄:合計時長與 token

在用戶名行上方注入兩行(縱向疊放,非並排):

  • 1小時29分 · 對話總時長
  • 3.3M · 對話總token

數據來源爲側邊欄已有的 sessions.list 快照與各會話投影:每行時長爲 sessionStats.llmMs + sessionStats.toolMs - taskTimer.awaitMs,逐行先減 awaitMs 再求和。已連接會話優先用 projectionsBySession 實時值;冷會話用投影檢查點緩存。origin === "subagent" 的子會話行不計入,避免與父會話工具時間重複。沒有任何工作時長記錄時不渲染時長行;側邊欄摺疊爲 56px 軌道時整段隱藏。

token 合計讀 tokenUsage 投影四桶(uncachedInputTokens、cacheReadTokens、cacheWriteTokens、outputTokens),口徑與 ui-chat UsagePill 整份日誌 token 總量一致,緊湊格式與內置 usage pill 相同。無 token 記錄時不渲染 token 行;僅有 token 無時長時 token 行仍可單獨顯示。

工作區會話行:「N 前」

ui-workspace 的 timeLabel 無對外 slot,也無法二次註冊 workspace locale。插件在瀏覽器可用 MutationObserver 時,僅匹配會話行內帶 _sessionRow/_time 後綴的節點,按 time.ago 模板(如 {t}前)冪等改寫文本節點,避免誤傷聊天消息上的 _time;剛剛、待回答、待審批 等狀態詞不改。

安裝與啓用

DSH 安裝目錄下 CLI 爲 resources/runtime/cli/bin/dsh.cmd(已加入 PATH 時可寫 dsh)。從公開倉庫安裝到 desktop profile:

& "<dsh>" plugin --profile desktop add github:ShuaihuiMou/dsh-task-timer

將 <dsh> 替換爲本機實際路徑。安裝後按 DSH 桌面端慣例在設置中啓用插件 bundle;具體啓用入口以當前 DSH 版本 UI 爲準。不要使用未在文檔中出現的臆造安裝命令。

典型用法

安裝並啓用後無需額外配置文件:

  1. 打開任意對話,在底部 composer dock 查看 工作時長 pill,數值隨 agent 的 llm/工具活動更新,等你回答的段落會從讀數中扣除。
  2. 點擊 pill,查看 創建對話至今 與可選的 已扣除等待回答;對話無人操作時「創建對話至今」不會隨掛窗時間上漲。
  3. 在左側邊欄用戶名上方查看全部對話(不含 subagent 子會話)的合計時長與 token。
  4. 在工作區列表中,會話右側時間應讀成「55分鐘前」一類表述,與懸停卡一致。

適用場景與注意

適合需要區分 agent 淨工作秒數 與 對話從首條內容到最後活動的牆鍾跨度、並在側邊欄一眼看到多對話合計時長與 token 的 DSH 桌面用戶。

使用時請注意:

  • 工作時長依賴宿主 sessionStats 與自研 awaitMs 配對規則一致;問句類工具未返回前,await 未結算,讀數與儀表盤工具時間 temporarily 可能看起來「還沒扣完」。
  • 側邊欄合計不讀盤解壓歷史,依賴列表與投影緩存;極冷會話以檢查點爲準。
  • 非瀏覽器裝配(如 SSR 冒煙)無 MutationObserver 時會話行「前」後綴裝飾不會掛載,其餘 pill 行爲以該環境是否注入 client 爲準。

結尾

dsh-task-timer 在不大改宿主的前提下,用 taskTimer 投影和 composer/sidebar 注入,把「扣掉等你回答的時間」的工作時長、 capped 的「創建對話至今」、多對話合計時長與 token、以及工作區時間讀法統一到一套可覈對的口徑。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜