DSH Plugins Marketplace

DSH Plugins

Plugins

/

Sessions & Messages

/

dsh-session-clock

x

dsh-session-clock

Manifest valid★ 1

DSH Session Clock: per-session clock injection + cross-round/inter-session idle gaps, as a companion plugin to the built-in dsh-time-context. Per-session clock injection for DeepSeek Harness with durable idle-gap tracking. A companion to the built-in dsh-time-context.

hasBundlePatch

dsh-session-clock

给 DeepSeek Harness 的「会话时钟」插件——按会话授时,并给出跨轮、跨会话的空闲间隔。 定位是宿主内置 @deepseek-ai/dsh-time-context 的补充插件,不是替代品。

English | 中文

status license node

dsh-hot-reloader — 改完插件源码不用重启
dsh-session-clock — 按会话授时与空闲间隔(本仓库)
dsh-second-opinion — 卡住时把问题交给另一个独立会话,要一份第二意见
dsh-onebot-companion — QQ 通道一体化:出站沉默守卫 / 行为规则 / 对话节奏 / 人设 / 语音

一句话说明

DSH 内置的 time-context 已经很擅长「告诉模型现在几点、距上一条消息过了多久」。 本插件不重复它,只补三件它结构上做不到的事:

能力dsh-time-context(内置)dsh-session-clock(本插件)
当前时间戳✅ 每轮首步➖ 不重复(full 模式下才复刻)
浏览器时区✅➖ 不重复
距上一条模型可见消息多久✅➖ 不重复
只给「指定会话」授时❌ 对所有 agent 一视同仁✅ sessions / exceptSessions 白名单
/正则/、* 通配匹配会话❌✅
跨会话指针(任何会话上次活跃多久前)❌ 不感知会话边界✅
距上一次「用户主动说话」多久❌ 只算模型可见消息✅ 排除定时/主动/工具触发的轮次
重启后间隔依然成立⚠️ 依赖会话内事件✅ 持久化到 $DSH_HOME/session-clock/activity.json
agent 主动查询(session_clock 工具)❌✅
HTTP 状态观测面❌✅

为什么需要它

DSH 内置的 @deepseek-ai/dsh-time-context 每个 turn 的首步都会注入一条三行消息:

Time sampled while preparing turn 8, step 1: 2026-10-13T10:14:10+08:00[Asia/Shanghai]
Browser time zone for this request: Asia/Shanghai. Interpret otherwise-unqualified dates and times in this zone.
Elapsed since the preceding model-visible message: 2h 15m 3s.

第三行在每轮第一步其实已经等于「距上次对话过去多久」——因为 step 1 执行时本轮的 user/message 还没提交,基线落在上一轮最后一条模型可见消息上。这一点本插件承认并且 不去动它(这也是本插件默认 mode: supplement 的原因)。

但它有两个结构性缺口:

  1. 它是全局的。 所有 agent、所有会话一视同仁,没法做到「只给这几个会话授时」。 在 QQ 群、定时任务、子代理混跑的场景里,token 花在了不需要的会话上。
  2. 它感知不到会话边界。 它知道「距上一条消息」,但不知道「距别的会话上次活跃」, 也不知道「用户上次主动开口是多久前」(定时唤醒、主动搭话也会产生模型可见消息, 把这条基线冲掉)。

本插件就补这两点。注入格式刻意沿用与 time-context 完全一致的时间戳/时长写法 (2026-10-13T10:14:10+08:00[Asia/Shanghai]、1d 2h 3m 4s),两条注入放在一起不打架。


功能详解

1. 按会话授时

sessions: ['onebot-*', 'session-*']      # 白名单,支持 * 通配与 /正则/
exceptSessions: ['/^onebot-group-.*$/']  # 黑名单,优先级高于白名单
  • '*'(默认)等于全部会话。
  • 'onebot-*' 匹配所有 QQ 通道会话;'/^session-36f4.*/' 走正则。
  • 非法正则自动退化为字面量匹配,不会让插件崩掉。

2. 跨轮与跨会话间隔

每条注入一行,形如:

Session clock for onebot-group-2000000002-mv40ioj5: previous user message 3d 4h 12m 9s ago; any session last active 12m 3s ago (session-36f403a5-...), turn 42.
  • previous user message ... ago:距上一次用户主动发言(不含注入消息、不含定时唤醒)。
  • any session last active ... ago:跨会话指针——任何一个被跟踪的会话上次动过是多久前, 括号里是那个会话 id。用来回答「我是不是刚在另一个窗口问过你」。
  • turn 42:本会话累计轮次数。
  • 各子句可用 includeUserGap / includeGlobalIdle / includeTurnCount 逐个关掉。

3. 持久化

状态写到 $DSH_HOME/session-clock/activity.json(默认 ~/.dsh/session-clock/activity.json)。

DSH 重启后内存里的会话对象是新的,但文件里的间隔基线还在,所以「距上次对话多久」 在重启后依然算得对——这是内置插件做不到的。写盘是延迟合并 + 原子替换 (tmp 文件 → renameSync),不会因为断电留下半个 JSON。

4. agent 可主动查询

注册了一个 session_clock 工具:

action作用
now本会话(或 session_id 指定)当前时间 + 各类空闲时长
list最近活跃的会话及空闲时长(limit 控制条数)

模型可以直接回答「我多久没来了」,而不必依赖注入。

5. HTTP 观测面

只在 loopback(127.x.x.x / localhost / ::1 / *.localhost)可访问,非本机一律 403:

方法路径作用
GET/session-clock当前状态(enabled / mode / 计数 / 上次决策原因)
GET/session-clock/list已跟踪会话及空闲时长
GET/session-clock/logs环形日志缓冲(最近 300 条)
POST/session-clock/toggle开/关注入
POST/session-clock/flush立即落盘
POST/session-clock/forget忘掉某个会话(body {"session": "<id>"})

/session-clock 里的 lastDecision 会告诉你上一次为什么没注入(例如 mode=supplement 只在首步注入)——这个插件每轮只补一条,错过首步就整轮静默, 没有这个字段会很难区分「没轮到」和「坏了」。


环境要求

前置插件

插件版本说明
@deepseek-ai/dsh-time-context0.2.0-rc.2宿主内置。必须存在但不要改动它——本插件默认 supplement 模式与它并存(见「与 time-context 共存」)

time-context 由 @deepseek-ai/dsh-base 组合包提供,你不需要单独安装。 本插件不 import 它,只在语义上补它结构上给不出的维度。

注意:dsh-experimental-schedule-bundle 也会随包插入同一个 dsh-time-context。 profile patch 里请保持单点挂载,插第二份会导致每 turn 首步注入两条逐字相同的消息。

DSH 宿主

项版本
DSH0.2.0-rc.2(本插件的开发与实测版本)
Electron44.0.0
Node(宿主内嵌)24.18.1
V815.2
Cordis4.0.4

依赖的宿主服务与接口

依赖必需说明
ctx.sessions✅inject = ['sessions']。取当前会话、读事件流
ctx.sessions.snapshotEvents()✅重建「距上次对话多久」的基线
ctx.on('session/event')✅追踪每条消息的 time 字段
@deepseek-ai/dsh-llm 的 createUserMessage⭕ 可选受控动态 import:try { ... } catch { undefined },拿不到就退回本地 deepFreeze({ id: randomUUID(), role: 'user', ... }) 等价物
webServer⭕ 可选没有它插件照常注入,只是看不到 HTTP 观测面
ctx.reflect.provide('sessionClock')⭕ 可选已用 try/catch 包裹,宿主没这个服务也不影响

零运行时依赖:只用 node:crypto / node:fs / node:path / node:url, 外加 ./time.js 与 ./store.js 两个自带模块。

状态文件

$DSH_HOME/session-clock/activity.json     # 默认;DSH_HOME 缺省时退回 ~/.dsh
  • 原子写(tmp + renameSync),格式 { version: 1, sessions: {...}, global: {...} }
  • MAX_RECORDS = 5000,超出时按 lastSeenAt 裁剪最旧的
  • 删掉这个文件 = 清空所有间隔记录(重启后间隔从零开始)

安装

dsh plugin --profile <你的profile> add link:/绝对路径/dsh-session-clock

或者从 npm/GitHub 装(若已发布):

dsh plugin --profile <你的profile> add dsh-session-clock

装好后通常无需重启:宿主内置的 HMR 会监听到 profile 清单变化并自动 reconcile。 用 /session-clock 看状态,enabled: true 且 ready: true 即为已装载。 若状态接口 404,说明这次 reconcile 没成功,再重启 DSH 一次。

与 time-context 共存

默认就是共存模式。 不要动 profile patch 里的 time-context 条目—— 它在 dsh-base 与 dsh-experimental-schedule-bundle 里都有引用,插第二份会导致 每个 turn 首步注入两条逐字相同的消息(这是 DSH 已知的坑,profile patch 的注释里有记录)。

如果你想用本插件整体替代 time-context:

  1. 在 profile 的 cordis.patch.yml 里把 - id: time-context 加 disabled: true;
  2. 本插件配 mode: full。

full 模式会完整复刻那三行 + 本插件自己的一行。


配置项

在 profile 的 cordis.patch.yml 里:

- id: session-clock
  name: dsh-session-clock
  config:
    mode: supplement
    timeZone: Asia/Shanghai
    sessions: ['*']
    refreshIntervalMs: 60000
键默认说明
enabledtrue总开关
mode'supplement'supplement = 只补增量;append = 额外给「距上一轮结束多久」;full = 复刻 time-context 三行
timeZone''(进程时区)IANA 时区;非法值会让插件停用并在状态里报错
refreshIntervalMs60000同一会话两次注入的最小间隔(ms);0 = 不节流
sessions['*']授时会话白名单,支持 * 与 /regex/
exceptSessions[]会话黑名单,优先级高于白名单
stateFile''状态文件路径,默认 $DSH_HOME/session-clock/activity.json
minGapSeconds0空闲不足这么多秒就不注入(避免刚说完话又报一次)
includeUserGaptrue输出「距上次用户主动发言」子句
includeGlobalIdletrue输出跨会话指针子句
includeIdleSinceTurnEndtrue输出「距上一轮结束」(supplement 模式下不生效)
includeSessionIdtrue注入行里带会话 id
includeTurnCounttrue注入行里带轮次计数
skipSubagentstrue跳过 origin === 'subagent' 的会话(数量多、生命周期短,省 token)
logInjectiontrue每次注入写一条宿主日志
traceDecisionsfalse每次跳过也写日志(排查用)
quietfalse关闭常规 info 日志

已知限制

  • 只在每轮首步注入。 supplement / append 模式一轮一条,因为时间戳与逐步语义 已经由 time-context 承担。需要每步都报请用 mode: full。
  • 整秒精度。 沿用 1d 2h 3m 4s 的写法,不带毫秒。
  • refreshIntervalMs 是节流而非保证。 它只压制「距上次注入太近」的情况。
  • 跨会话指针只覆盖被本插件跟踪过的会话。 全新会话第一次出现前不在表里。
  • previous user message 依赖注入消息把自身 source.kind 标成 session-clock。 若其它插件也往历史里塞 user 角色消息且不标来源,会被计入。
  • 未做客户端(浏览器)侧任何东西。 纯宿主插件。

⚠️ 自用免责声明

这个插件是给自己用的小工具,按「现状」提供,不附带任何保证。

  • 作者不是 DSH / DeepSeek 官方,本插件与官方没有关系,也不被官方背书。
  • 代码主要围绕作者自己的一个 profile 打磨(Windows + 国内时区 + QQ 通道 + 一堆第三方插件混跑),其它环境的兼容性没有验证过。
  • 它读取会话事件、写一个 JSON 状态文件、注册一个工具和几个 HTTP 路由。 虽然都有失败兜底,但不要在有合规要求的生产环境上不经审查地部署。
  • 依赖 DSH 的内部未公开接口:ctx.loader 的结构、session/event 与 agent/pre-step 的载荷形状、ctx.sessions / ctx.webServer / ctx.tools。 这些不是稳定 API,DSH 升级后随时可能坏。
  • 使用风险自负。因使用本插件造成的任何直接或间接损失,作者不承担责任。

如果你只是想让模型知道现在几点,先去用内置的 time-context—— 它由官方维护,比这个插件可靠。本插件解决的是它覆盖不到的那一小块。


开发

lib/
  index.js   # 主实现:事件订阅、注入决策、HTTP 观测面、工具注册
  store.js   # 持久化:延迟合并写 + 原子替换 + 条数裁剪
  time.js    # 时区校验、时间戳格式化、时长格式化
cordis.patch.yml
  • 零运行时依赖(只用 node: 内置模块)。对 @deepseek-ai/dsh-llm 的 createUserMessage 走受控动态 import,拿不到就退化为本地等价实现 (deepFreeze + randomUUID)——因为 DSH 的包解析路径随环境变化,静态 import 失败会让整个插件被静默跳过。
  • 时长与时间戳格式与 time-context 逐字对齐,方便两条注入并存:
lib/time.js     formatDuration(93784000) === '1d 2h 3m 4s'
lib/time.js     formatTimestamp(now, fmt, 'Asia/Shanghai') === '2026-10-13T09:52:39+08:00[Asia/Shanghai]'

本地热改的话,配合 dsh-hot-reloader 可以改完即生效、无需重启。


License

MIT © 2026 xfgil

Comments

Loading…

From the same category

billion-context

by ranxianglei

基本稳定可用 100K tokens is enough. Universal context-compression proxy for ALL AI coding agents,10w上下文足矣

Sessions & MessagesManifest valid

★ 1.3k

↓ 619.8k/wk

MIT

TypeScript

Oct 15, 2026

dsh plugin --profile web add billion-context

A DeepSeek coding agent harness: persistent shell, Ultra subagents, auto approval, Chrome MCP and session telemetry

Sessions & Messages

★ 1k

MIT

JavaScript

Index only — not installable

by Han-1413141

DeepSeek Harness session cost meter plugin: session/daily cost, budget, history, OpenCode Go quota, official & custom-provider balance, Codex-like token heatmap, peak/off-peak pricing with pre-switch

Sessions & MessagesManifest valid

★ 420

↓ 27.8k/wk

MIT

JavaScript

Oct 14, 2026

dsh plugin --profile web add dsh-cost-meter

by Nwflower

Import 14+ external agent chat histories (Claude Code, Codex, ChatGPT, Cursor, Gemini, Reasonix, opencode, ZCode, Grok Build, OpenClaw, Pi, Hermes, Kimi CLI, DSH) into DeepSeek Harness as resumable se

Sessions & MessagesManifest valid

★ 231

MIT

JavaScript

Oct 13, 2026

dsh plugin --profile web add dsh-chat-import

by Totoro-qaq

DeepSeek Harness plugin for previewable cross-preset session migration. Fixed-schema handoffs preserve state, source-model intent, and unresolved images; the original session stays untouched.

Sessions & MessagesManifest valid

★ 163

MIT

JavaScript

Oct 14, 2026

dsh plugin --profile web add dsh-plugin-bridge

by MichengAI

DSH Archive Manager — 在 DeepSeek Harness 中安全查看、恢复和管理已归档会话 · Safely view, restore, and manage archived sessions in DSH

Sessions & MessagesManifest valid

★ 135

↓ 17k/wk

Apache-2.0

JavaScript

Oct 14, 2026

dsh plugin --profile web add @michengai/dsh-archive-manager