中文EN

@dsh-agentic-roleplay/state

memory已测通过npmGPL-3.0-only

为 DSH 角色扮演插件提供持久化 SQLite 会话状态、故事记忆与回忆、数据仓库以及面向模型的记录工具。

下载量 / Downloads
4,524
依赖体积 / node_modules
469.08 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add @dsh-agentic-roleplay/state

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

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:

Method · Does

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, factionStates, factionMemberships, factionRelationships and factionIntents 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 e

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:28,最后更新 2026-11-05

链接

GitHub · Homepage · npm

同类插件