DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

CancerTiN /

CancerTiN/dsh-set-session-title

Verified

A model-facing set_session_title tool for DeepSeek Harness (dsh) — let the agent rename its own session.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@38f5d729

dsh-set-session-title

A model-facing set_session_title tool for DeepSeek Harness (dsh) — the agent can rename its own session.

中文说明

Why this exists

DSH owns session titles properly: they are log-only session/title events (zero tokens) served by @deepseek-ai/dsh-session-title, written either by a deterministic first-prompt fallback or by an optional LLM provider.

What is missing is a way for the agent to fix one. Automatic titling can produce a content-free result — observed on a real session: the provider overwrote a usable fallback with the bare phrase 会话标题 ("session title"), i.e. the instruction's own vocabulary echoed back (discussion #8289). The rename capability itself exists (SessionTitleService.rename(session, title), the GUI rename dialog, the host's own delivery path uses it), but 0.2.0-rc.2 exposes it to no model-facing surface:

  • no tool;
  • no session CLI subcommand (plugin and duplicate only);
  • /api guarded by an authority-bound signed cookie whose launch token is a per-process randomBytes() value that is never persisted, so a local process cannot legitimately obtain it.

This plugin adds exactly that one existing service call as a tool. It does not touch authentication, storage, or the session log directly — the capability is granted by composing the row.

Behaviour

Write appends a session/title event with source: { kind: "user" }
Pinning a user-sourced title is authoritative: in-flight automatic generation is superseded and later prompts schedule none (an explicit refresh is the deliberate unpin)
Scope the calling agent's own session (exec.agent.session)
Normalization trimmed, terminal control sequences removed, capped at the deployment's maxTitleBytes (dsh-base ships 80); input that normalizes to empty is rejected
Cost changes no message in the conversation and adds no tokens

Install

# recommended: git spec pinned to a release tag (reproducible, and immune to the tarball caveat below)
dsh plugin --profile <name> add github:CancerTiN/dsh-set-session-title#v0.1.1

# drop the #v0.1.1 fragment to follow the default branch instead of a pinned release

# a tarball URL works too — read the caveat below before picking one
dsh plugin --profile <name> add https://github.com/CancerTiN/dsh-set-session-title/archive/refs/tags/v0.1.1.tar.gz

The manifest declares dsh.bundle.patch, so add appends dsh-set-session-title to the profile's dsh.profile.bundles and its patch inserts the tool row into the composed tree.

Tarball-URL caveat. Under the pnpm bundled with the desktop app (11.7.0), a GitHub tarball URL installs once and then fails on every later resolve that reuses the same pnpm store — ERR_PNPM_MISSING_TARBALL_INTEGRITY, where deleting the lockfile and --force both change nothing. Reproduced and reported upstream as discussion #8294. A git spec is unaffected because it resolves to a commit-addressed gitHosted entry, which pnpm does not subject to the integrity requirement; a tarball URL is still fine when the store has not seen it (or on a newer pnpm).

On 0.2.0-rc.2 the desktop app picked the tool up without a restart (the client-side tool schema updated mid-session and the call succeeded immediately). Other builds may need the profile restarted.

Requirements

Both injected services ship with dsh-base, so the default web / desktop / headless compositions satisfy them:

service role
tools tool registry
sessionTitle @deepseek-ai/dsh-session-title (row id session-title)

A composition missing either one fails loud at load instead of registering a tool that cannot work.

Usage

Ask the agent, or call it from a skill. Argument:

{"title": "安装终端插件并核验连通性"}

Result:

{"title": "安装终端插件并核验连通性", "eventSeq": 1307}

Read back either way (both should show the new title):

# the projection cache the GUI reads; seq matches the returned eventSeq
python3 -c "import json;print(json.load(open('$DSH_HOME/storages/session_projcache/sessions/$DSH_SESSION_ID.json'))['record']['rows']['title'])"

# the durable log; the last session/title event's source.kind should be "user"
zstd -dc "$DSH_HOME"/sessions/*/"$DSH_SESSION_ID"/session.v4.jsonl.zstd | grep session/title | tail -1

Why this package has zero dependencies

This is a hard constraint, not a style choice.

Declaring an in-box package (for example @deepseek-ai/dsh-tools, the documented home of defineTool) as a dependency makes pnpm materialize a second copy inside the profile. Module identity then splits for a module-local Symbol that keys a runtime surface of the tool registry, so ctx.tools[TOOL_RUNTIME_SCHEDULER] reads back undefined inside dsh-agent-loop and every tool call in that profile fails — bash, read, and this plugin's tool alike — with a bare Cannot read properties of undefined (reading 'prepare'). Reproduced and isolated on 0.2.0-rc.2; written up in discussion #8287.

So lib/index.js imports nothing and the tool definition is hand-written JSON Schema. ctx.tools.register() requires only output: { schema, render } plus a schema inside the supported subset (type / properties / required / additionalProperties / items / enum / const and the description annotation) — which is what defineTool compiles a declaration into. The trade-off: register() does not wrap execute with schema validation, so the single argument is checked by hand.

Verified on

@deepseek-ai/dsh-desktop-runtime 0.2.0-rc.2, macOS, session format v4 — both a headless profile and the desktop app's live session:

{"type":"tool/call","seq":1306,"data":{"name":"set_session_title","arguments":"{\"title\":\"安装终端插件并核验连通性\"}"}}
{"type":"session/title","seq":1307,"data":{"title":"安装终端插件并核验连通性","messageSeqs":[],"source":{"kind":"user"}}}

messageSeqs: [] is the signature of rename(): the title is explicit, not derived from a prompt.

Limitations

  • Only the calling session can be renamed; there is no cross-session rename and no target-id argument.
  • A non-agent caller (plain host-side execution) is rejected.
  • A deployment that does not compose session-title fails loudly at load — deliberate, so the tool can never appear without the capability behind it.

Uninstall

dsh plugin --profile <name> remove dsh-set-session-title

Titles already written stay in the session log: a title is a log fact, not plugin state.

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 38f5d7293ac4

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout