A side-chat plugin for DSH (DeepSeek Harness). Type /side in any session and a read-only side chat slides out on the right. It copies the current session's context as its memory, inherits the main agent's persona and model, but is restricted to read-only tools — and is fully released when closed.
/sideto open: a side chat panel slides in from the right (≥1280px viewport: real layout sidebar that squeezes the conversation; narrow viewport: falls back to an overlay drawer that works at any width)- Context copied, not shown: the main session's history is fully copied into the independent agent's session as its memory, but the panel only shows the side chat's own new messages
- Output matches the main UI: the side chat is a real independent agent — it inherits the main agent's complete preset (persona / system prompt / skills) via
agentPresets.composeFromand reuses the main agent's model - Read-only tool whitelist: only
read/glob/grep/read_image/web_search/skill/job_list/job_output/ask_user_question/cordis_inspect_*/get_goal/list_agents; nobash,write,edit, or any other mutating tool - Markdown rendering: built-in lightweight Markdown renderer (tables, code blocks, headings, lists, bold/italic/inline code, links, blockquotes, rules) styled with the main theme's CSS variables
- Close = release: clicking "关闭" calls
AgentHandle.dispose()— the agent stops and its session is removed; nothing is persisted or retained - No ungrouped workspace sessions: the side session is archived in the workspace registry as soon as it is created, so it never appears in the workspace / ungrouped session list
- Works while the main agent runs: the panel button (and sending a message) auto-rebuilds the agent from the last known main agent when no
/sidecommand was run (e.g. after a restart or after closing)
- In the DSH Web plugin page, create a new Cordis plugin
- host code: paste the full contents of
plugin/host.js - client code: paste the full contents of
plugin/client.js - Run the plugin and approve it
The code is plain JavaScript function bodies (
return { apply(ctx) { … } }) — no imports, JSX, or TypeScript, so the dynamic plugin sandbox loads it directly.
/side
- The main session shows "侧边聊天已打开(只读模式,已复制 N 条上下文)" and the panel slides out on the right
- Chat independently inside the panel — it remembers the main session, shares the main UI's persona, but can only read, never modify
- Click "关闭" in the panel header to release everything (the command row also offers an "打开面板" button to reopen it)
| Layer | File | Responsibility |
|---|---|---|
| Host | plugin/host.js |
Registers the /side command; creates a real independent agent via sessions + agents (seed = main session events, composeFrom inherits the preset, tools.restrict enforces the read-only whitelist); archives the side session (workspaceRegistry.archiveSession) so it never appears in the workspace; auto-rebuilds the agent from the last main agent on open/send when the handle is missing; exposes ensureOpen / getState / send / close RPC via harness.handle; getState uses session.firstLiveSeq to render only the live segment |
| Client | plugin/client.js |
details slot (wide-window sidebar) + shell.overlay slot (narrow-window drawer); conversation.chat.commandview (key side) drives opening event-driven; 500ms polling fallback; lightweight Markdown renderer |
Data flow: Client sends a message → host.call('side.send') → agent.followup() → the independent agent runs its full loop (same preset model + read-only tools) → output lands in its session → Client polls getState and streams the display.
- The independent agent runs on a brand-new forked session; it never writes back to the main session's log, so the main UI is unaffected
- Dynamic plugin definitions are process-local and are lost on restart — re-install to use again
- While the plugin runs, the
detailsslot is occupied, so the built-in tool-details panel is shadowed; it returns automatically once the plugin stops
MIT — see LICENSE.