dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Mobile-first DSH Web history loader: official tail-first first paint, bounded prefetch, early auto-load before Load earlier is the only option, touch/fling handling. Display-only; context unchanged. | 面向手机/小屏的 DSH Web 历史渐进加载:沿用官方尾部优先首屏、有界预取、提前补页、触摸/快速滑动停稳;只影响显示,不改变模型上下文。
English · 中文
DSH Web 历史会话渐进加载插件(面向手机/小屏):首屏最近消息 → 后台预读少量历史 → 接近已加载头部提前补页;支持触摸屏/移动端。只影响显示,Host 为模型组装的上下文不变。
Repository: · npm: dsh-fast-history (not published yet) · MIT
A mobile-first client-side plugin for DSH Web that progressively loads conversation history. The newest messages render first (the official tail-first behavior is preserved); older history is prefetched in the background and then loaded automatically as you approach the currently loaded head — tuned for phones and small screens. It only changes what is displayed; the model context assembled by the host is untouched.
Repository: · npm package: dsh-fast-history (not published yet) · MIT
This plugin fills those gaps without changing the host or the model context.
SessionFace.loadOlder() (0/1/2 configurable).loadOlder() directly because the official button is offscreen and beginPaging() would anchor to the oldest row.beginPaging() seat can land on the next pager). Desktop keeps the official pager path. A top pull loads exactly one page and never chains.From a checkout:
git clone https://github.com/OranImp/dsh-fast-history.git
dsh plugin --profile web add /absolute/path/to/dsh-fast-historyFrom a DSH agent session, the equivalent tool call is plugin_manager action=install_bundle target="/absolute/path/to/dsh-fast-history".
After the npm release, you can use the package name instead:
dsh plugin --profile web add dsh-fast-historyRefresh the Web GUI after installation (the client bundle is not HMR’d when pnpm run dev:web is not running).
Manual install: add "dsh-fast-history": "link:/absolute/path/to/dsh-fast-history" to the profile dependencies, append "dsh-fast-history" to dsh.profile.bundles, run pnpm install, and refresh.
Settings → General → History loading
Settings live in browser localStorage (dsh-fast-history.settings.v1), per browser, not host config.
Debug:
localStorage.setItem('dsh-fast-history.debug', '1'); // refresh
window.__DSH_FAST_HISTORY__.stats();
window.__DSH_FAST_HISTORY__.diagnostics();
window.__DSH_FAST_HISTORY__.setSettings({ prefetchPages: 0, preloadScreens: 2 });scrollTop correction are deferred until the gesture/inertia settles; a fast fling to the top may briefly show “Load earlier” before the load starts. This is intentional to avoid jank.scrollTop; desktop corrects a settled drift >2 px using the top visible row.SessionFace has no trim API; the plugin does not mutate private fields or eventSource.replace. Growth is bounded by user browsing + at most 2 prefetched pages (default 1) + up to 4 chain pages.加载更早 / 加载更多 / Load earlier / Load more; otherwise uses the structural fallback, then a direct loadOlder()..dshm-main / [data-dsh-mobile-frame]) the plugin binds the mobile conversation. On phones the early path is a direct loadOlder() with an old-top-row correction, and pager clicks are routed through the same anchored direct path — both dsh-mobile’s synthetic button.click() and a real tap. Desktop keeps the official pager behavior.From a checkout (tests are not included in the npm tarball):
node --test test/*.test.mjs
# optional Chromium fixture; requires Playwright + a Chromium build
python3 test/browser_test.py
# if the browser is not in Playwright's default location:
# CHROMIUM_PATH=/path/to/chrome python3 test/browser_test.pyDisable or remove the bundle in the profile, or from a shell run dsh plugin --profile web remove dsh-fast-history, then refresh. In a DSH agent session the tool call is plugin_manager action=remove_bundle target="dsh-fast-history".
面向手机/小屏的 DSH Web 历史会话渐进加载插件:首屏最近消息 → 后台预读少量历史 → 上滑自动加载更早。
只影响显示。插件不会发送 prompt、不会追加会话事件、不会改变 Host 为模型组装的上下文。
当前安装并已核对的 DSH 0.2.1-rc.2 / rc.3 官方行为(更新版本请重新验证):
本插件在官方分页接口之上补齐:
SessionFace.loadOlder() 预读 1 页(可配置 0/1/2),让第一次上滑通常无需等待。loadOlder() 直接请求;手机/粗指针上,加载后由插件把加载前的顶部可见消息行按原位置钉住(不在手指/惯性期间写 scrollTop)。真正到顶(≤4px)时:桌面点官方 pager,手机走直接加载 + 锚定校正,避免官方 beginPaging() 把视口落到下一个 pager。git clone https://github.com/OranImp/dsh-fast-history.git
dsh plugin --profile web add /absolute/path/to/dsh-fast-history如果是在 DSH Agent 会话里,等价的工具调用是: plugin_manager action=install_bundle target="/absolute/path/to/dsh-fast-history"。
npm 发布后,也可以直接用包名:
dsh plugin --profile web add dsh-fast-history安装后刷新 Web GUI(当前没有 pnpm run dev:web watcher,Client 变更不会 HMR)。
手动安装(如果插件管理器不可用):
package.json dependencies 中增加"dsh-fast-history": "link:/absolute/path/to/dsh-fast-history"。
dsh.profile.bundles 末尾增加 "dsh-fast-history"。pnpm install,刷新页面。Settings → General → 历史消息加载:
设置保存在浏览器 localStorage(dsh-fast-history.settings.v1),按浏览器生效;不是 Host 配置。
调试:
localStorage.setItem('dsh-fast-history.debug', '1'); // 刷新后生效
window.__DSH_FAST_HISTORY__.stats(); // 计数、页数、延迟、锚定漂移
window.__DSH_FAST_HISTORY__.diagnostics(); // 当前条件判定
window.__DSH_FAST_HISTORY__.setSettings({ prefetchPages: 0, preloadScreens: 2 });open();插件不会在首屏前预读。openState=open、hasMore、非 running、在尾部、页面可见、当前窗口 entries ≤ 400 时,延迟约 1.2s 调一次 loadOlder()。每页新增 entries > 400 或累计 > 600 即停止。首屏过重的单 Turn 会话直接跳过预取。max(96px, scroller.clientHeight × preloadScreens);默认 1.5 屏。接近已加载头部时即触发,不必看到 pager。wheel / touch / ArrowUp|PageUp|Home 输入;wheel 进入提前区即触发;触摸手势只记下待加载意图,手指抬起且滚动停稳后再触发,不会在手指移动中插入内容。同页脚本也可以合成这些事件或直接点官方 pager,因此这不是安全边界,只是交互门控。touchstart 后,手指向下滑(看更早内容)且进入提前区时,只记下待加载意图;手指抬起且滚动停稳(约 140ms)后才加载,避免和浏览器的滚动锚定/惯性抢位置。只处理单指,双指缩放和嵌套滚动区(代码块等)不触发。手机浏览器按窄视口/粗指针/触摸能力识别,不要求 dsh-mobile 专用布局;dsh-mobile 布局会优先绑定。loadOlder() 直连;真正到顶(≤4px)时桌面点官方 pager,手机用直接加载 + 自锚定。手机上的 pager 点击(包括 dsh-mobile 的 64px gate 合成 click 和真实手指点击)都改走同一条锚定直连;桌面仍保留官方 pager 行为。scrollTop 速度和单事件位移识别快速滑动;高速阶段不发起加载、不写 scrollTop,链式补页也暂停,等惯性停稳约 140ms 后再加载。快速滑到顶部时可能短暂看到“加载更早”,停稳后才补页,这是为了不打断滚动。scrollTop 仍在提前区内且 hasMore,桌面 80ms / 手机/粗指针 160ms 后自动再加载一页;一次接近最多 4 页(含第一次),头部离开提前区、历史耗尽、失败或切会话即停止。触摸进行中或高速滚动时链式补页暂停,停稳后继续。loadOlder(),加载前记录顶部可见行(data-chat-anchor-key + rect),加载后若行仍在则把它的位置钉回原处;手机也做这个校正,但只在手指/惯性停止后写 scrollTop,并加 120ms × 最多 6 次的延迟重试。真正在顶部(≤4px)且桌面时点击官方 pager,交给 Chat 自己的 beginPaging。顶部 direct 加载后如果仍在 0px(锚定失败),只加载一页、不链式补页,避免循环。[data-conversation-session] 识别;切换/视图切换/滚动容器复用都会 teardown 旧监听与定时器;旧异步结果按 generation 丢弃。SessionFace 没有裁剪已加载窗口的方法,插件也不会改私有字段或 eventSource.replace。内存增长仍由“用户浏览 + 最多 2 页预取(默认 1) + 一次接近最多 4 页提前加载”驱动;不预读整条历史。_older 容器),再失败走 loadOlder()。.dshm-main。提前区和真正到顶都用 loadOlder() 直连,并做旧顶部行校正;桌面顶部才点官方 pager。若你的手机 App 连接的是另一个 DSH profile,需要把本插件也安装到那个 profile。从源码 checkout 运行(npm tarball 不含 test/):
node --test test/*.test.mjs
# 可选:真实 Chromium fixture(需要 Playwright + Chromium)
python3 test/browser_test.py
# 如果 Playwright 浏览器不在默认缓存目录,设置 CHROMIUM_PATH:
# CHROMIUM_PATH=/path/to/chrome python3 test/browser_test.py浏览器 fixture 覆盖:预取 1 页、pager 仍在视口外时提前加载、提前区内自动续加载一页、官方 pager 手动仍可用、清理后不再自动加载、调试全局删除、dsh-mobile overlay 的手机上下文、无 overlay 的普通手机浏览器、快速滑动停稳前后不提前加载、body 焦点键盘 PageUp、resync 后重新预取、同会话 aria-hidden 重绑不重复预取、顶部无锚点时只点一次 pager 不续链、手机顶部无浏览器锚定时旧行仍保持、手机合成/真实 pager click 都改走锚定直连、无页面错误。
dsh plugin --profile web remove dsh-fast-history或在 DSH Agent 会话里用 plugin_manager action=remove_bundle target="dsh-fast-history"。
刷新页面。浏览器中的设置键可手动清理:
localStorage.removeItem('dsh-fast-history.settings.v1');
localStorage.removeItem('dsh-fast-history.debug');