Skip to content

feat(dsh): DSH's own host services for dsh plugins; matrix on rutis 0.9 - #306

Merged
yuanhao merged 4 commits into
mainfrom
feat/dsh-host-services
Oct 12, 2026
Merged

yuanhao merged 4 commits into
mainfrom
feat/dsh-host-services

Conversation

@yuanhao

@yuanhao yuanhao commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Goal: raise how many DeepSeek harness (DSH) plugins work in yoagent. Result: 3 → 4 of the top 20, plus a clear map of what blocks the rest.

Approach. The compatibility matrix showed most DSH plugins waiting for services of the DSH host. DSH ships the common ones as packages, and they run headless. plugins/dsh/host-services.json lists them as rows:

  • dsh-fs-local, dsh-attachment-local, dsh-credentials-local (these provide fs, attachments and credentials themselves; loading the interface package beside one conflicts);
  • dsh-storage, dsh-session-persistence;
  • dsh-skill, dsh-skill-filesystem.

The compatibility probe and the frontend examples load them before the plugins.

Credentials safety. These services keep data, and read credentials (.credentials.yaml, .env), under DSH_HOME, else ~/.dsh. So the DSH runtime gets a home of its own and never the user's real DSH keys by default:

  • the probe uses a temp dir;
  • the examples use YOAGENT_DSH_HOME, else $TMPDIR/yoagent-dsh-home.

Point YOAGENT_DSH_HOME at ~/.dsh to share them on purpose. New in yoagent-frontend: PluginHostBuilder::env(runtime, name, value) and host::rows_from_file.

Matrix, re-measured on rutis 0.9 (in CI via plugin-matrix.yml, not locally: loading packages runs third-party code):

  • DSH: 3 → 4 usable. @dfy-plugins/dsh-visualize now works, and the missing-service lists shrank (e.g. dsh-image-generation now waits only on settings).
  • What still blocks the rest is DSH's app: its web UI (4 packages), model layer (llm), agents / subagents, and settings. settings needs DSH's app boot (config editor, profile context, Cordis loader), so I stopped there rather than imitate an API we don't control.
  • pi: unchanged at 12/20.

Tests: dsh_host_services_start_headless_in_their_own_dsh_home checks, from inside the runtime, that all six services exist with DSH_HOME set to a temp dir. All DSH tests (7), the frontend suites, the terminal pty check and the handoff demo (which loads the services) pass locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG

yuanhao and others added 4 commits October 12, 2026 13:50
…credentials, storage, session persistence, skills)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
Many dsh plugins wait for services of the DSH host. DSH ships the common
ones as packages that run headless; plugins/dsh/host-services.json lists
them (dsh-fs-local, dsh-attachment-local, dsh-credentials-local,
dsh-storage, dsh-session-persistence, dsh-skill, dsh-skill-filesystem —
the -local packages provide fs/attachments/credentials themselves).

They keep data and read credentials under DSH_HOME, else ~/.dsh, so the
DSH runtime gets a home of its own: the probe a temp dir, the frontend
examples YOAGENT_DSH_HOME else $TMPDIR/yoagent-dsh-home (new
PluginHostBuilder::env and host::rows_from_file).

Plugin compatibility, re-measured on rutis 0.9 (CI, plugin-matrix.yml):
DSH 3 -> 4 of 20 usable (@dfy-plugins/dsh-visualize); the rest need DSH's
app (web UI, llm, agents, settings — settings needs DSH's app boot, not
provided). pi unchanged at 12/20.

Test: dsh_host_services_start_headless_in_their_own_dsh_home (all six
services present inside the runtime, DSH_HOME a temp dir).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
…claims, tests

- yoagent-frontend `DshHome`: YOAGENT_DSH_HOME (an empty one is unset —
  DSH would read it as ~/.dsh), else a private owner-only (0700) dir per
  run, removed on drop (was a fixed shared /tmp path, error ignored);
  env() = DSH_HOME and, for a private home, DSH_AGENTS_HOME inside it, so
  ~/.agents skills stay out too.
- PluginHostBuilder::env for a runtime that is not started fails `start`.
- coding_agent / handoff_agent load the host services only with
  `--dsh-services`: their own DSH plugins need none of them, and they give
  plugins the filesystem and a credentials reader.
- Docs say what a separate home does and does not keep out: not the
  inherited environment (DSH's credentials service reads it first), the
  project's .env and skill folders, or the filesystem (dsh-fs-local).
- Tests: dsh_test proves isolation (a plugin reads a key from the given
  DSH_HOME's .credentials.yaml, source `file`; nothing created under HOME);
  host_test: env reaches only its runtime, a typo'd runtime is an error;
  unit tests for rows_from_file, the shared list and DshHome (0700,
  removed on drop). The probe names the cause when host-services.json
  cannot be read, and sets DSH_AGENTS_HOME too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
… counts failures

- plugins/dsh/fixture-needs-services.ts: a dsh tool plugin injecting all
  six host services; its tool reads a key through `credentials`.
  dsh_test `a_dsh_plugin_needing_host_services_runs_only_with_them`: with
  host-services.json loaded its tool answers from the given DSH_HOME;
  without, the plugin never starts and the tool is never offered.
- scripts/ecosystem-matrix.mjs: the summary counts packages that failed
  to load or install (DSH's 4 + 12 + 3 left out modsearch's failure) and
  says the DSH numbers are with the host services loaded; the report is
  regenerated from the same results (--from-json, no new probe).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7iq5hpndSiHQcnAsywKuG
@yuanhao
yuanhao merged commit 74251c9 into main Oct 12, 2026
17 checks passed
@yuanhao
yuanhao deleted the feat/dsh-host-services branch October 12, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant