DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

@dsh-agentic-roleplay/state

State

用于角色扮演会话状态的 DSH 插件:每个会话使用一个 SQLite 数据库,并通过规范模型以服务形式向其他插件提供。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add @dsh-agentic-roleplay/state@0.10.1
README兼容性版本

兼容性与来源证明

State 以 @dsh-agentic-roleplay/state 发布,当前版本为 0.10.1。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
npm
Registry 更新时间
2026/11/4

版本

0.10.1stable
2026/11/3
0.10.0stable
2026/11/2
0.9.1stable
2026/10/31
查看其余 22 个版本收起版本
0.9.0stable
2026/10/31
0.8.2stable
2026/10/30
0.8.1stable
2026/10/30
0.7.3stable
2026/10/29
0.7.2stable
2026/10/28
0.7.1stable
2026/10/26
0.7.0stable
2026/10/26
0.6.1stable
2026/10/24
0.6.0stable
2026/10/24
0.5.0stable
2026/10/23
0.4.1stable
2026/10/22
0.4.0stable
2026/10/21
0.3.6stable
2026/10/20
0.3.5stable
2026/10/20
0.3.4stable
2026/10/19
0.3.3stable
2026/10/18
0.3.2stable
2026/10/17
0.3.1stable
2026/10/17

相关插件

正在加载相关插件…

最新版
0.10.1
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
1.7 MB
文件数
7
Surface
any
许可证
GPL-3.0-only
发布源
npm
GitHub
★ 0
周下载
2,017
安全扫描
✓ v0.10.1 扫描通过
最近提交
2026/11/3
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
0.3.0
stable
2026/10/15
0.2.1stable
2026/10/15
0.1.1stable
2026/10/13
0.1.0stable
2026/10/12

相关插件

继续浏览 memory-context 分类下经过校验的插件。

Experimental Session Search@deepseek-ai/dsh-experimental-session-search为 Agents 提供搜索和读取当前工作区早期会话的工具。Hindsight Coding Agents@vectorize-io/hindsight-coding-agents面向编程代理的仅反思式 Hindsight 长期记忆(可插拔支持多种运行框架:opencode、……),自动在后台导入(无需设置 CLI)。Contextdsh-context用于上下文洞察和管理的 DeepSeek Harness 插件,提供上下文仪表板和上下文命令,帮助了解上下文的构成及其演变过程。Memory Plugin@openviking/dsh-memory-plugin适用于 DeepSeek Harness 的 OpenViking 记忆与上下文套件

README

@dsh-agentic-roleplay/state

The persistent session-state and memory service for DSH Agentic Roleplay, maintained by Firefox2100.

Most users should install @dsh-agentic-roleplay/all. Install this package separately when another DSH plugin needs the roleplay database, repositories, recall engine, or model-facing record tools without the complete roleplay interface.

A DeepSeek Harness plugin that keeps the state of roleplay sessions: one SQLite database per session, reached through repositories over canonical models. It does no orchestration and has no UI, so it can be installed on its own to get a roleplay database and state management without the rest of the roleplay bundle. Other plugins use it through the roleplayState service. Model-facing tools are included and can be enabled through its configuration.

Requires DSH 0.2 and Node 22.19 or later (it uses the built-in node:sqlite).

dsh plugin --profile <name> add @dsh-agentic-roleplay/state

Using it from another plugin

import type {} from '@dsh-agentic-roleplay/state'            // types `ctx.roleplayState`
import type { Context } from '@deepseek-ai/cordis'

export const inject = ['roleplayState']

export function apply(ctx: Context) {
  // Creates sessions/<uuid>/session.sqlite and opens it.
  const session = ctx.roleplayState.createSession('/path/to/sessions', {
    name: 'First night',
    world: { id: 'blackwater-observatory', name: 'The Blackwater Observatory' },
  })

  session.transaction(() => {
    const mayor = session.characters.add({ name: 'Eleanor Graves', /* … */ control: 'agent' })
    session.characterStates.create(mayor.id, { publicState: '…', innerState: '…', activity: '…' })
    session.intents.add(mayor.id, { type: 'agenda', name: '…', /* … */ })
  })

  session.characters.findByName('the mayor')       // by name or alias, ignoring case
  session.characterStates.update(1, { activity: 'looking for the key' }, { expectedVersion: 3 })
}

The service creates and opens sessions under a sessions folder you give it, shares one connection per session, and closes them all when the plugin unloads:

MethodDoes
createSession(sessionsDir, init)Creates the session folder and database and returns its repositories. The id is generated (UUID v4) unless given. Nothing is left behind if it fails.
openSession(sessionsDir, id)Returns the repositories of an existing session.
listSessions(sessionsDir)The metadata of every session under the folder (name, world, creation time, last played time, turns). A session that cannot be read is reported in problems, not thrown.
closeSession(sessionsDir, id)Releases the connection; opening again reconnects.
deleteSession(sessionsDir, id)Closes the session and removes its folder.

Session ids become folder names, so only a UUID v4 is accepted. The package also exports the same operations as plain functions (createSession, openSession, createSessionStore, …) for code that does not run inside DSH, such as tests.

The records API and the model-facing tools

The package owns how a story is remembered, not only where it is stored:

  • session.edit(edit) changes the story's records (character states, events with who took each in, beliefs, threads) together or not at all. It checks the whole edit first and throws InvalidEditError naming every problem, so a model's mistakes can be reported back to it. parseRecordsEdit(json) reads the wire format models write (snake_case) and recordsEditSchema({ characters, changes }) is its JSON schema, for a model's structured output or a tool's parameters.
  • session.records(scope) reads the records back in the same wire format.
  • session.recall({ characterId, situation, turn, policy }) is what a character is reminded of: events it took in and things it believes, by who the situation mentions, shared words and tags, importance and story-time recency; with policy.flaky the older and less important are told as faded or vague, or are gone. Age is elapsed story time from session.clock, never turn count; an unimportant event has a six-story-day half-life. It counts what it brings back as recalled, which makes it last longer.
  • session.recallStored(query, { queryVector? }) adds the session's search index to the cues: texts that match the situation by words and, with the vector of the situation, by meaning. session.searchEvents({ text, vector?, fromTurn, toTurn, minImportance, limit }) finds what happened by the same two searches, merged by reciprocal rank.
  • session.recallRanked(query, signal, { queryVector? }) is the call for anything that reminds a character of something: recall, ranked by meaning when a plugin has registered a ranker with roleplayState.rankMemories(ranker) (an embedding model, a reranker; see docs/capabilities.md). session.recallCandidates(query) gives what could be recalled, with the text to match, for a ranker. With explain: true in the query each recalled thing carries why: the cues of the moment (people named, words shared, place), what each search scored it, how much it matters, how long ago it was, how much of it is left in mind and what it was ranked by.
  • session.knowledge is the closed-world awareness graph for locations, items and directed exits (learn, knows, get, list, forget). Directional relationships are the corresponding character-to-character edges. Awareness grants identity only, not current state or whereabouts. session.planKnownMove plans through only a character's known places and exits; planMove remains the authoritative world planner.
  • session.factions, , , and store persistent organisations separately from characters that act in scenes. Membership is many-to-many; relationships involving factions are directional and double as closed-world awareness edges.

Tools registered with the DSH tool registry (defineTool, typed output, honoring the call's signal), resolved through that binding: list_characters, get_character, search_events, recall_memories, list_threads, and, only when the plugin is configured with writeTools: true, update_character_state, record_event, remember, open_thread, resolve_thread. They fail with a plain message for an agent that works in no roleplay session. Characters and other one-shot sub-agents see none of them (they are started with no tools).

Configuration

FieldDefaultMeaning
journalModedeletedelete keeps each session in a single file that can be copied; wal allows readers during writes.
writeToolsfalseAlso register the model-facing tools that change the records. Leave off where another agent is responsible for them.

Layers

LayerWhat it is
Canonical modelThe types in dsh-roleplay-model (re-exported here): Character, CharacterState, CharacterIntent, SessionMetadata, …
RepositoriesMetadataRepository, CharacterRepository, CharacterStateRepository, IntentRepository: the only access to the data. They take and return canonical models and throw the errors below.
SQLite implementationMaps rows to models and back; the only place that knows tables and SQL.
DriverSqlDriver / SqlDatabase: the few operations the implementation needs (exec, run, get, all, transaction). nodeSqliteDriver is built on node:sqlite.

Everything is synchronous, as the embedded SQLite libraries are.

This is an independent community project, not an official DSH package. Documentation · Source · Issues · GPL-3.0-only

The session

A session is the folder sessions/<uuid>/ with its database session.sqlite. The database is the only file the state needs; with the default journal mode it stays a single file that can be copied or archived.

The world itself is not stored. metadata keeps a world reference: the world's stable id (the id in its world.json, not a database id), its name, and optionally a version, a fingerprint of the content the session was started from, its source, and free-form extra fields. It is saved as one document, so provenance can grow without a schema change.

The metadata also carries what a list of sessions shows: the session's name (chosen when it is created), its creation time, the time of the last play (absent until a turn has been played) and the number of turns played. Whatever plays a turn calls metadata.recordTurn(), which counts it and sets the time.

Characters have session-local integer ids. source_id keeps the id the character had in the world, so a session can be traced back to its world; characters created during play have none.

Schema (version 1)

TableHolds
metadataKey/value rows: session.id, session.name, session.created_at, session.last_played_at, session.turns, world (JSON), plus free-form namespaced entries.
charactersThe definition: name, age, gender, pronouns, kind, tier, role, summary, personality, background, appearance, speech, and control (player or agent, chosen for the session). source_id is unique.
character_aliasesOne row per alias, in order, with a case-folded key for lookup.
character_stateThe state that changes in play: public state, inner state, activity, version, updated_at. One row per character.
character_emotionOptional baseline and immediate valence/arousal/dominance of a state.
intentsA character's intents: type, name, description, status, horizon, priority, urgency, plan, open threads, constraints, deadline.
relationships, consolidation_itemsHow a character stands towards another (a profile per direction: label, summary, familiarity, trust, affinity, tension) and the characters and places made up in play that still have to be fitted into the world. lintWorld reports what is inconsistent. The edit can make characters, places and ways when it is the authoring variant (recordsEditSchema({ authoring: true })).
entity_knowledgeExplicit character-to-location/item/exit awareness: the first learned turn and optional last directly observed turn. Absence means unknown; current facts remain in state, perception and memory.
factions, faction_aliases, faction_state, faction_memberships, faction_relationships, faction_intentsOrganisations, their institutional state and strategy, many-to-many membership, and directional relationships involving a faction.
slots, items, item_holdings, openers, event_itemsThings (one kind for items, equipment and containers: quantity, condition, notable, hidden, the slot it is worn in, a container state, an owner), where each is (a place, a character's hands or a slot, or inside a container item), the places on the body something can be worn (with defaults, data per session), what opens each lock (on items and exits), and which events are about which items. does what a character does with a thing (take, drop, give, put, wear, remove, open, close, lock, unlock, reveal) by the rules of the story and says every reason when it cannot.

Events are the ground truth; perceptions (which stay revisable: updatePerception, addPerception), memories and summaries are derived from them and can be rebuilt. The repositories are events, memories, threads, summaries and pendingCommits next to the ones for characters.

Deleting a character deletes everything that belongs to it. The tables are STRICT, enumerations and ranges are CHECK constraints, and foreign keys are enforced. The file records its schema version in user_version and carries an application id, so a file that is not a session database is refused.

Changing the schema

Migrations are applied in order when a session is opened and are never edited once released: a change is a new entry in src/sqlite/schema.ts, and a test pins the migrations of each release. A database from a newer version is refused rather than damaged.

Before a file that is behind the latest schema is upgraded, it must pass SQLite's quick integrity check (a damaged file is refused with CorruptDataError, untouched) and a copy of it as it was is written to migration-backups/schema-<version>.sqlite beside the database, once per old version. migrationBackupPath(location, version) says where.

Errors

ErrorWhen
NotFoundErrorA row, character or session file does not exist.
ConflictErrorA repeated source_id, a state created twice, a stale expectedVersion, or creating a session where one exists.
InvalidValueErrorA value is outside what the schema allows.
SchemaErrorThe file is not a session database, or comes from a newer version.
CorruptDataErrorStored data cannot be read back as a model.
factionStates
factionMemberships
factionRelationships
factionIntents
  • roleplayState.bind(resolver) tells the tools which roleplay session an agent works in (the plugin that runs the agents supplies it, with the turn being played and the memory policy).
  • changeItem
    clock, time_logThe story's own time: one row with the mode (simulated or real) and the instant, and every step it took (start, elapsed, real, skip, resync) with the turn and round. session.clock starts it, moves it forward, sets it in either direction when the mode changes, and tells when a round began.
    routine_windows, engagements, engagement_participantsThe recurring day of each character (windows of the day with what it is doing and where, first fit applies) and dated commitments with who made them and whether they were kept. session.routines and session.engagements; agendaAt merges them with the character's goals (intents).
    locations, exits, placementsPlaces (with features), the ways between them (one direction each, open / locked / blocked, optional travel seconds) and where things stand (a character: place, position, feature; the same table will place items). session.planMove / session.move move a character over open exits only (InvalidMoveError names every reason); the edit wire format can make places, change exits and move characters.
    eventsWhat objectively happened: turn, round, text, importance (1 to 5), tags. event_involves lists the characters an event is about. Events are immutable: a draft until sealed, final afterwards (events.seal()); updating or removing a sealed one throws ConflictError.
    perceptionsWhat one character took in of an event, in its own terms: mode (witnessed, heard, told, inferred), content, a gist for when it fades, an accuracy label (never shown to the character), and how often it was recalled. One per character and event.
    memories, memory_evidenceWhat a character believes or knows beyond single events: kind, text, subjects, importance, confidence, formation turn, and the perceptions that support or contradict it.
    story_threadsThings not settled yet: promises, mysteries, goals; open or resolved.
    summariesThe account of the story for the conversation's head: digests of recent turns and chapters of older ones, each with the turns it covers.
    recall_items, recall_fts, recall_vocab, recall_vecThe search index: one row per perception, memory and event, indexed by words (FTS5) and, once vectors are stored, by meaning (sqlite-vec, cosine, partitioned by character). store.recallIndex lists the texts without a vector (pending), stores vectors (store, which fixes the model and dimensions of the session's vectors) and searches (lexical, vector). Vector support is optional: without the extension everything but vector works.
    pending_commitsRecorded rounds whose events and memories are not written yet, kept so that a failure loses nothing.