dsh-session-persistence-mysql
Manifest valid★ 3deepseek harness 插件 替换会话持久化引擎为 MySQL 数据库
@sandersyao/dsh-session-persistence-mysql
English | 中文
The MySQL durable session-persistence backend for the DeepSeek Harness — a concrete SessionPersistence (the dsh-session-persistence seam). Load it as a plugin; it registers ctx.sessionPersistence and persists the event-sourced SessionEvent log into MySQL, behavior-contract-equivalent to the JSONL backend, with read/write split support.
Install & usage
import { MysqlSessionPersistence } from '@sandersyao/dsh-session-persistence-mysql'
await ctx.plugin(MysqlSessionPersistence, {
connection: { tablePrefix: process.env.SESSION_TABLE_PREFIX ?? process.env.MYSQL_TABLE_PREFIX },
})
// ctx.sessionPersistence is now MySQL-backed.
Guides
- Try it in a dsh profile without touching existing sessions —
docs/DSH_PROFILE_TRIAL.md. - Production / npm install &
cordis.patch.ymlintegration (replace the default JSONL backend) —docs/DEPLOYMENT.md§8.
Companion plugins (distributed dsh deployment)
This plugin runs alongside three sibling plugins on a shared MySQL to form a distributed dsh
deployment: dsh-storage-mysql and dsh-credentials-mysql switch the default storage and
credentials backends to MySQL, and dsh-workspace-bootstrap declaratively bootstraps a default
workspace so the first session can start on an empty database.
| Plugin | GitHub repository | npm package page |
| --- | --- | --- |
| @sandersyao/dsh-workspace-bootstrap | https://github.com/sandersyao/dsh-workspace-bootstrap | https://www.npmjs.com/package/@sandersyao/dsh-workspace-bootstrap |
| @sandersyao/dsh-storage-mysql | https://github.com/sandersyao/dsh-storage-mysql | https://www.npmjs.com/package/@sandersyao/dsh-storage-mysql |
| @sandersyao/dsh-credentials-mysql | https://github.com/sandersyao/dsh-credentials-mysql | https://www.npmjs.com/package/@sandersyao/dsh-credentials-mysql |
Configuration
Credentials, table prefix and pool tuning come from environment variables / a .env file (see .env.example). The plugin Config is fully optional — environment is the source of truth for credentials (never hard-code a password).
Each variable reads the plugin-exclusive SESSION_* first and falls back to the shared MYSQL_* — the same pattern as dsh-storage-mysql(STORAGE_*) and dsh-credentials-mysql(CREDENTIALS_*): the MySQL plugins can share one MYSQL_* deployment yet each be configured independently (own database / table prefix).
| Exclusive SESSION_* | Fallback MYSQL_* | Default | Purpose |
|---|---|---|---|
| SESSION_HOST / SESSION_PORT | MYSQL_HOST / MYSQL_PORT | 127.0.0.1 / 3306 | Write (primary) host. |
| SESSION_USER / SESSION_PASSWORD | MYSQL_USER / MYSQL_PASSWORD | — (required) | Least-privilege DB user. |
| SESSION_DATABASE | MYSQL_DATABASE | — (required) | Target database. |
| SESSION_TABLE_PREFIX | MYSQL_TABLE_PREFIX | — (required) | Table prefix; validated against ^[A-Za-z0-9_]+$. |
| SESSION_READ_HOST / SESSION_READ_USER / SESSION_READ_PASSWORD | MYSQL_READ_* equivalents | (empty) | Read replica for read/write split; empty reuses the write connection (same-store mode). |
| SESSION_SSL_REQUIRED | MYSQL_SSL_REQUIRED | false | Reserved for TLS enforcement (deferred; may be provided by a cloud provider). |
| SESSION_POOL_SIZE / SESSION_POOL_QUEUE_LIMIT | MYSQL_POOL_* equivalents | 10 / 0 | Pool sizing. |
| SESSION_SCHEMA_AUTO_MIGRATE | MYSQL_SCHEMA_AUTO_MIGRATE | true | Auto-migrate schema on startup; false only validates. |
| SESSION_ENCRYPTION_KEY | MYSQL_ENCRYPTION_KEY | (empty) | Reserved for application-level field encryption (deferred; empty = plaintext). |
Test isolation. Automated tests (
vitest) run against a separate database to avoid touching the production one:SESSION_TEST_DATABASE(fallbackMYSQL_TEST_DATABASE, defaulttest) overridesSESSION_DATABASEduring tests, andMYSQL_ROOT_PASSWORDis used only by the test harness to create/grant the test DB. Seedocs/MANUAL_TEST_PLAN.md.
Storage layout
Two tables plus a schema-version table, all under MYSQL_TABLE_PREFIX:
${prefix}sessions— one row per materialized session (theSessionHeader).${prefix}events— the append-only event log;PRIMARY KEY (session_id, seq).${prefix}_meta— applied schema version.
The header row is written only in the same transaction as the first event batch (lazy materialization, atomic), so a created-but-never-appended session leaves no rows and is absent from list.
Read/write split
Write hooks (appendBatch, commitRepair) use the write pool; read hooks (loadStored, readStoredRevision, loadStoredFrom, list, listSnapshots) use the read pool. When MYSQL_READ_HOST is unset the read pool reuses the write connection (same-store mode — what tests exercise). Read-replica lag does not break the seam contract: revisions only need to be stable while unchanged.
Durability and crash semantics
- Transactional append. Each batch commits in a single InnoDB transaction; the log is append-only and seq-contiguous. The composite primary key is the cross-process safety net for same-id double writes (the second writer is rejected on a key collision).
- No torn tail. Because writes are transactional, InnoDB atomicity makes a partially-written final record impossible, so the backend's
tornMarkeris alwaysundefinedandcommitRepaironly appends synthetic closers. This is a structural advantage over file backends. - Crash recovery. An interrupted final turn is preserved and durably closed with synthetic
tool/result/step/end/turn/end {interrupted}closers via the shared coordinator. Committed records are never rewritten. - Lazy materialization — the header and first batch commit atomically.
- Deadlock retry —
ER_LOCK_DEADLOCK(1213) retries with bounded backoff.
Schema & migration
Startup runs a connection test, idempotent CREATE TABLE IF NOT EXISTS, then reads ${prefix}_meta; an applied version higher than expected fails closed (no downgrade). With MYSQL_SCHEMA_AUTO_MIGRATE=false, a version mismatch fails instead of auto-migrating (production can run DDL out of band).
Model Experience
The backend adds no prompt or schema. Resume restores stored surface events as message history; crash repair marks an unanswered assistant call TOOL_NOT_STARTED and a call without a result TOOL_OUTCOME_UNKNOWN. Zero live-request tokens during ordinary persistence; readFrom seeks by seq for checkpoint consumers.
Known Limitations and Deferred Work
- No delete/archive API — the seam has none; pruning stored sessions is out-of-band
DELETEmaintenance. list()is unpaginated and unfiltered (seam constraint).- Cross-process lease mode is single-primary only (TD-008) — the opt-in
cluster.leasemode serializes writers through aleasesrow and fences everyappend; it assumes all lease traffic reaches one write primary (writePool). A dedicated lease-primary connection for multi-primary / read-split topologies, and reclamation of released or expired lease rows, are deferred. Both need a global monotonic fence sequence instead of the current per-rowfence_token + 1, which is only safe because released rows are kept (never deleted). - Plaintext by default — session events may contain sensitive content (conversations, tool results, request headers).
ENCRYPTION_KEYis a reserved extension point; application-level field encryption is deferred. Deployers should consider MySQL native TDE / at-rest encryption. - TLS/transport enforcement deferred —
MYSQL_SSL_REQUIREDis reserved; may be provided by a cloud provider. - Pinned to
^0.1.5-rc.xpeers — aligned with the dsh0.1.5-rc.xsession-persistence contract; upgrade together with@deepseek-ai/dsh-session/@deepseek-ai/dsh-session-persistence.
Compatibility
Versions
| Latest version | Published | Size |
|---|---|---|
| 0.1.1-rc.2 | — | — |
| 0.1.1 | — | — |
| 0.1.2-rc.1 | — | — |
| 0.1.5-rc.1 | — | — |
| 0.1.5-rc.2 | — | — |
Similar plugins
by TheM14
DeepSeek Harness 已归档会话管理与新预设续接插件。Archived-session management and preset continuation plugin for DeepSeek Harness.
★ 0
↓ 238/wk
MIT
JavaScript
Aug 21, 2026
dsh plugin --profile web add dsh-session-cleanerby MuWinds
DeepSeek Harness 插件-归档会话管理,支持释放、清除归档会话
★ 8
MIT
TypeScript
Sep 12, 2026
dsh plugin --profile web add @muwinds/dsh-archived-sessionsby lanlandeli
DeepSeek Harness 会话管理插件|归档与恢复、批量操作、工作区分组、子代理关系、活动详情、记录目录与安全文件清理
★ 3
TypeScript
Aug 18, 2026
dsh plugin --profile web add dsh-conversation-managerby peng7peng
dsh-terminal-manager
★ 0
MIT
TypeScript
Sep 13, 2026
dsh plugin --profile web add dsh-terminal-managerby awol2005ex3
DeepSeek Harness(`dsh`)插件:为单机的 harness 增加**用户管理**与**会话按用户隔离**。
★ 0
Apache-2.0
TypeScript
Aug 31, 2026
dsh plugin --profile web add dsh-user-managerby xmuwenxiang
Deepseek Harness插件,可以直接在Deepseek Harness中使用网页版deepseek进行聊天,并将聊天过程直接迁移到Deepseek Harness进一步进行开发。主要目的是节省前期方案讨论时的token
★ 11
↓ 72/wk
Apache-2.0
TypeScript
Sep 7, 2026
dsh plugin --profile web add dsh-webchat