@dsh-agentic-roleplay/state

identitytested: passnpmGPL-3.0-only condition deviation

DSH plugin for roleplay session state: one SQLite database per session, exposed to other plugins as a service over canonical models.

📦 体积
469.08 MB · large
🔌 Network
undeclared
✅ Sandbox
pass
🏷️ Versions
28

Who this is for

  • people who run long sessions and need session control
下载量 / Downloads
0
依赖体积 / node_modules
469.08 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

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

Sandbox test results

條件偏離 —— 本結果在 DSHIO/T 21 v0.9 條件下產生(內存 1g、CPU 1.5、T4 超時 60s,未記鏡像 digest)。偏離條款:5.1.3(内存 768MB)、5.1.3(CPU 1 核)、5.1.6(T4 超时 90s)、5.1.2(镜像 digest)。按 DSHIO/T 21 §8.2,該判定不得與標準條件結果比較,不得用作認證依據。
StageResult
T0 static check—
T1 install✓
T2 list✓
T3 mount✓
T4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

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)

Rendered from the README published on npm. Formatted only, not edited.

Embed the badge

Two badges, each using its own site's identity: left is the **standard** (published by DSHIO), right is the **testing organization** (deepseekbase, which ran the inspection). Each links to the standard text and the test report.

DSHIO/T 10deepseekbase

Markdown(推荐,两个一起)

[![DSHIO/T 10](https://deepseekbase.com/badge/std.svg)](https://dshio.org/10/) [![deepseekbase](https://deepseekbase.com/badge/dsh-agentic-roleplay-state.svg)](https://deepseekbase.com/zh/plugins/dsh-agentic-roleplay-state/)

Note: this is not a certification. DSHIO/T 32 is not in effect.

Versions

Published on npm::28,最后更新 2026-11-05

Links

GitHub · Homepage · npm

Frequently asked

How do I install @dsh-agentic-roleplay/state?
Run dsh plugin --profile web add @dsh-agentic-roleplay/state in DSH, or paste the package name into the DSH Desktop plugin page.
What if it fails to install?
Check your DSH version first (dsh --version), then look at the first error in the test-results section. If it still fails, open an issue on the repository.
How do I uninstall it?
Run dsh plugin --profile web remove @dsh-agentic-roleplay/state.

Same category

Compare with peers

PluginDownloadsVerdictSize
dsh-persona-dafeiyu23.2Kpass0.2 MB
dsh-feiyu-mood13.0Kpass6.66 MB
@tnnevol/dsh-codex-auth9.6Kinstall_failed—
dsh-whale-loli6.9Kpass0.15 MB
dsh-agent-persona5.5Kpass9.86 MB
@istarry/dsh-assistant-profile5.2Kpass18.1 MB
dsh-custom-mode4.7Kpass0.55 MB
dsh-persona-switcher4.0Kpass0.67 MB