🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话时钟 xfgil/dsh-session-clock

DeepSeek Harness
xfgil12 天前有提交已提供中文文档扫描:含敏感能力

给 DeepSeek Harness 的「会话时钟」插件——按会话授时,并给出跨轮、跨会话的空闲间隔。

30.6/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add xfgil/dsh-session-clock
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · other
装得上吗
本站尚未做安装检查
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 12 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 7 处,展示前 7 条)
  • 读取本地文件
    lib/store.js:49
    if (!existsSync(file)) return;
  • 读取本地文件
    lib/store.js:50
    const parsed = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/store.js:83
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    lib/store.js:86
    writeFileSync(tmp, JSON.stringify(payload), 'utf8');
  • 写入本地文件
    lib/store.js:87
    renameSync(tmp, file);
  • 读取本地文件
    lib/store.js:152
    if (existsSync(tmp)) unlinkSync(tmp);
  • 删除本地文件
    lib/store.js:152
    if (existsSync(tmp)) unlinkSync(tmp);
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 会话时钟:按会话注入时间,记录跨轮、跨会话的空闲间隔,是内置 dsh-time-context 的补充插件。

README

由 DeepSeek 最新模型翻译生成
dsh-session-clock 给 DeepSeek Harness 的「会话时钟」插件——按会话授时,并给出跨轮、跨会话的空闲间隔。 定位是宿主内置 @deepseek-ai/dsh-time-context 的补充插件,不是替代品。 | dsh-hot-reloader — 改完插件源码不用重启 | | dsh-session-clock — 按会话授时与空闲间隔(本仓库) | | dsh-second-opinion — 卡住时把问题交给另一个独立会话,要一份第二意见 | | dsh-onebot-companion — QQ 通道一体化:出站沉默守卫 / 行为规则 / 对话节奏 / 人设 / 语音 | 一句话说明 DSH 内置的 time-context 已经很擅长「告诉模型现在几点、距上一条消息过了多久」。
展开完整文档(README 剩余 1 节)
dsh-session-clock

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

| 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. 智能体可主动查询

注册了一个 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-context | 0.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 宿主

| 项 | 版本 |
| DSH | 0.2.0-rc.2(实测于该版本) |
| Electron | 44.0.0 |
| Node(宿主内嵌) | 24.18.1 |
| V8 | 15.2 |
| Cordis | 4.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 版本:>=0.2.0-rc.2 <0.3.0-0(开发与验证所用为 0.2.1-rc.2)。

1. npm / 插件管理器(推荐)

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

2. 从源码挂链接

git clone https://github.com/xfgil/dsh-session-clock.git D:\Plugins\dsh-session-clock
dsh plugin --profile <你的profile> add link:/绝对路径/dsh-session-clock

link: 方式的好处是改完源码不用重新安装。

3. 下载 Release 附件

在 Releases 页面下载对应版本的源码压缩包,解压到任意目录,再用上面的 link: 命令挂进 profile。
装好后通常无需重启:宿主内置的 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

| 键 | 默认 | 说明 |
| enabled | true | 总开关 |
| mode | 'supplement' | supplement = 只补增量;append = 额外给「距上一轮结束多久」;full = 复刻 time-context 三行 |
| timeZone | ''(进程时区) | IANA 时区。检测不到就按北京时间来,不会停摆(见下) |
| fallbackTimeZone | 'Asia/Shanghai' | timeZone 为空且进程时区是 UTC/取不到、或配置值非法时落到的时区 |
| refreshIntervalMs | 60000 | 同一会话两次注入的最小间隔(ms);0 = 不节流 |
| sessions | [''] | 授时会话白名单,支持 与 /regex/ |
| exceptSessions | [] | 会话黑名单,优先级高于白名单 |
| stateFile | '' | 状态文件路径,默认 $DSH_HOME/session-clock/activity.json |
| minGapSeconds | 0 | 空闲不足这么多秒就不注入(避免刚说完话又报一次) |
| includeUserGap | true | 输出「距上次用户主动发言」子句 |
| includeGlobalIdle | true | 输出跨会话指针子句 |
| includeIdleSinceTurnEnd | true | 输出「距上一轮结束」(supplement 模式下不生效) |
| includeSessionId | true | 注入行里带会话 id |
| includeTurnCount | true | 注入行里带轮次计数 |
| skipSubagents | true | 跳过 origin === 'subagent' 的会话(数量多、生命周期短,省 token) |
| logInjection | true | 每次注入写一条宿主日志 |
| traceDecisions | false | 每次跳过也写日志(排查用) |
| quiet | false | 关闭常规 info 日志 |

时区:检测不到就是北京时间

timeZone 留空表示「用进程时区」。但进程时区是 UTC 或取不到时(容器、服务器、装系统没选区域),不再当成有效时区 —— 跟着 UTC 走会让这个实例系统性偏 8 小时。
配置值写成不存在的 IANA 名也一样:都不会让插件停摆,而是落到 fallbackTimeZone(默认 Asia/Shanghai)并照常注入。

状态端点里能看出走的是哪条路:

| timeZoneSource | 含义 |
| detected | 用了进程时区(或你显式配置的那个) |
| fallback | 没检测到,落到了 fallbackTimeZone;原因在 timeZoneError |

浏览器通道没有时区(QQ / 网关来的消息)时,注入行会直接写「none reported — this message did not come from a browser. Use Asia/Shanghai as the authoritative zone」, 不再让模型去问用户是哪个时区 —— 那一行时间戳本身就是准的。

已知限制

- 只在每轮首步注入。 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——它由官方维护,比这个插件可靠。本插件解决的是它覆盖不到的那一小块。

License

MIT © 2026 xfgil
预览分享卡片长什么样 ↓xfgil/dsh-session-clock
分享 · DeepSeek Harness Hub
xfgil/dsh-session-clock

给 DeepSeek Harness 的「会话时钟」插件——按会话授时,并给出跨轮、跨会话的空闲间隔。

回到顶部