@khorsheed/dsh-room 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -2
- package/README.en.md +83 -0
- package/README.i18n.yaml +3 -3
- package/README.md +61 -26
- package/lib/client.js +243 -243
- package/lib/typert.host.js +24 -12
- package/lib/typert.remote-client.js +9 -9
- package/package.json +4 -4
- package/README.zh.md +0 -48
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.1.1(2026-09-27)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
适配宿主 0.1.7-rc.2 线(verifiedHost 前移至 0.1.7-rc.2——3080 生产实证线随宿主基线切到 rc.2;rc.1→rc.2 无触及本包的宿主变更,全量构建+测试双绿)。
|
|
6
|
+
|
|
7
|
+
- README 落地房间主视图实拍截图
|
|
8
|
+
- 伴生工具行 `@khorsheed/dsh-room-tool` 0.1.1 修复 rc.1 挂载顺序下工具行静默惰死(核心服务改声明式 inject,见其 CHANGELOG)
|
|
9
|
+
|
|
10
|
+
## 0.1.0(2026-09-26)
|
|
11
|
+
|
|
12
|
+
首个公开发布。按单实例多模式提案(2026-08-26)拆出模型工具行(M4'②,worktrees 之后的第二对 core/companion)。
|
|
6
13
|
|
|
7
14
|
- **BREAKING**:模型可见的 `room_invite` / `room_task` / `room_message` 工具不再由 core 在 profile 根注册——拆为伴生包 `@khorsheed/dsh-room-tool`(不 `ctx.provide`、不声明 `dsh.bundle` 的不自挂载行),由各 agent preset 的 `agent.cordis.yml` 按名引用、按会话授予。迁移:安装伴生包并在目标 preset 加 `- id: room-tool / name: '@khorsheed/dsh-room-tool'`(web-dev 的 dev preset 已带此行);工具定义工厂(`roomInviteTool` / `roomTaskTool` / `roomMessageTool`)经 core 的 `./tool` 导出供伴生包复用,业务实现零复制,origin tag 归伴生包
|
|
8
15
|
- room 服务、成员 UI(成员 tab / 邀请对话框 / 任务板 / 通知闸门)与全部 Remote 行为不变
|
package/README.en.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# @khorsheed/dsh-room
|
|
2
|
+
|
|
3
|
+
English | [中文](README.md)
|
|
4
|
+
|
|
5
|
+
One session, a whole team of agents — invite DSH, Kimi, Codex or Claude Code members in, @-name them to hand out work, and let a coordinator run the plan while the accept/rework call stays with the human.
|
|
6
|
+
|
|
7
|
+
Getting several agents onto one piece of work today means copy-pasting between windows, or one-shot subagent calls that forget everything on return. Room makes the session itself the shared place: inviting the first member promotes the current session into a Room and seats the native DSH agent as the initial coordinator, and every member keeps its own native conversation across turns and restarts.
|
|
8
|
+
|
|
9
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-1.png" width="640" alt="an active Room: member receipts and run rows in the chat flow, with the @-member menu open above the composer">
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Inviting promotes the session** — no separate "create room" step: invite the first member into any session and it becomes a Room; the native DSH agent joins as the initial coordinator (named `dsh` in new rooms; existing rooms keep their recorded addressing names).
|
|
14
|
+
- **@-addressing with fan-out** — leading `@name` tokens address existing members, and several names fan out at once; a mention picked from the completion menu addresses explicitly even mid-sentence, while a hand-typed mention inside prose does not (the menu never creates members). Same-member turns share one queue, different members run concurrently, and durable request identities keep retries from duplicating accepted work.
|
|
15
|
+
- **Coordinator handoff** — any prepared member (DSH, Codex, Claude Code, Kimi) can take over via **Set as coordinator** in the Members tab; the handoff record carries the goal, the plan state, open tasks and recent context. A running coordinator cannot be replaced until its current turn settles.
|
|
16
|
+
- **Background delegation with correlated reports** — ordinary chat needs no formal plan: the coordinator dispatches a small background task with `room_message` and receives the completion report, correlated, at a turn boundary. Peer notifications between members (`member_message`, trailing `@name` replies) stay behind a human confirm/dismiss gate that never blocks coordinator task reports.
|
|
17
|
+
- **Durable goal plans with evidence review** — larger work becomes a formal goal: stages, hierarchical tasks, dependencies, execution attempts, submitted evidence, and explicit acceptance or rework. A finished generation is not accepted by default; dependent tasks unlock only after their prerequisites are accepted. Budgets bound goal-wide concurrency, total and per-task executions, and active goal time (paused time excluded); pause, resume, rebudget, cancel and complete stay human commands. After a restart, unresolved executions are marked uncertain and the plan pauses — reconciliation requires evidence, never a blind re-run.
|
|
18
|
+
- **Members keep their native sessions** — the Members tab holds names, providers, roles, working-directory overrides (blank inherits the Room's directory), effective configurations and session links; breadcrumbs and task links open the member's own conversation with its tools, duration and token usage. Room statistics for the native session are not a sum of member spend.
|
|
19
|
+
- **Shared model/effort controls** — coordinator and member composers share the core model/effort control; choosing a new configuration mid-run queues it for the next complete turn (tool continuations keep the current one), and frozen evaluation members reject changes. The original native DSH session keeps the host model selector and its semantics — it is not a local-agent member controller.
|
|
20
|
+
- **Live output, targeted stop** — members stream native text and reasoning into both their own conversation and the Room; final messages and tool records stay authoritative. Stopping a member interrupts only that member and preserves non-empty partial output with an explicit stopped/failed label, duration and session link; long replies expand from a compact preview.
|
|
21
|
+
- **Preset-gated chrome, fail-open** — the **Invite agent** header chip and the **Members** tab appear exactly when the session's preset composition grants the `@khorsheed/dsh-room-tool` row, fail open when the composition cannot be read, and always stay visible inside an existing Room.
|
|
22
|
+
|
|
23
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-invite.png" width="640" alt="the Members tab: the empty state that turns the session into a multi-agent collaboration room, and the session header's Invite agent entry">
|
|
24
|
+
|
|
25
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-2.png" width="640" alt="the Members tab: member cards with name, provider, role and model, plus the Set-as-coordinator action">
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
dsh plugin --profile web add @khorsheed/dsh-room
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The package mounts its own loader row and browser contribution; restart the web instance to activate. For external CLI members, install the local-agent core and the providers you want alongside it — without them the Room still works with the native DSH coordinator. The model-facing tools (`room_invite` / `room_task` / `room_message`) live in the `@khorsheed/dsh-room-tool` companion and are granted per session preset.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
dsh plugin --profile web remove @khorsheed/dsh-room
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Uninstalling removes the plugin's surfaces; persisted Room journals stay in their session logs.
|
|
40
|
+
|
|
41
|
+
## Compatibility
|
|
42
|
+
|
|
43
|
+
- npm release line (`@deepseek-ai/dsh@0.1.5-rc.1`): ✅ supported with one designed degrade — 0.1.5-rc.1 full-line boot-verified (42 packages including capture, 2026-09-25) through the three compat layers ([preset-registry dual-name probe](../../.agents/notes/implemented/bug-fix/2026-09-25-preset-registry-dual-name-probe.md), [dual-shape typert codecs](../../.agents/notes/implemented/bug-fix/2026-09-25-typert-codec-dual-shape.md), [typert faces carrying zod@4](../../.agents/notes/implemented/bug-fix/2026-09-25-typert-faces-carry-zod-v4.md)); `minHost` is pinned at 0.1.5-rc.1. External members require the local-agent family (core + providers), which is not yet published on npm: without it, member preparation, shared model/effort controls and the authenticated member tools answer unavailable, while native DSH Room functionality stays complete. Candidate-tarball fresh-install and upgrade checks on the npm host pass, retaining existing Room state.
|
|
44
|
+
- source line (deepseek-harness master): ✅ (verifiedHost: 0.1.7-rc.2 — also the 3080 production-verified line) — Session V4 adaptation: the main-agent followup's source moved to the producer-owned kind `room` (V4 native admission refuses the retired `kind: 'plugin'` wrapper at the durable write; a 0.1.5 host's `user/message` admission accepts any non-empty kind, so both lines write durably), and the read side accepts `room`, `plugin:@khorsheed/dsh-room` (the V3→V4 migrated form) and the released V3 wrapper. The `conversation.chat.node` rc.1 contract re-verified (the 5 room renderers touch neither hookContext nor the disclosure factory). DSH/Kimi coordinators, delegation, two-stage review and interruption recovery are exercised end to end — see the [acceptance record](../../docs/acceptance/room-coordinator-2026-09-19.md).
|
|
45
|
+
|
|
46
|
+
## Known Limitations
|
|
47
|
+
|
|
48
|
+
- **Peer notifications still need a human confirm** — `member_message` relays and trailing `@name` replies journal as pending until the human confirms or dismisses; only coordinator task reports bypass the gate.
|
|
49
|
+
- **External members depend on the local-agent family** — until the family is published and installed, CLI member preparation, shared controls and authenticated member tools degrade to unavailable (structured `local-agent-unavailable` at invite, journaled `failed` runs at dispatch); the native DSH member keeps working.
|
|
50
|
+
- **Codex/Claude runtime acceptance is still pending** — DSH and Kimi members have been exercised end to end; Codex/Claude authenticated runs have not, and the full P95 streaming gate remains open — the transport interval alone proves nothing about P95 latency.
|
|
51
|
+
- **A persisted Room needs Room to stay mounted** — the `room/*` event vocabulary is registered by the plugin into the session-event catalog (a temporary seam pending an official event-registration API), so a build without the plugin refuses the log by design.
|
|
52
|
+
- **Member chrome replicates host visuals** — identity and action styling track the host's chrome and need re-checking when upstream visuals change.
|
|
53
|
+
- **Cross-host paint measurement assumes a shared clock** — the local diagnostic does; remote-host measurements need clock alignment.
|
|
54
|
+
- **A green model reply does not prove storage landed** — persistence failures surface diagnostically.
|
|
55
|
+
|
|
56
|
+
## How it works
|
|
57
|
+
|
|
58
|
+
<details>
|
|
59
|
+
<summary>Internals (click to expand)</summary>
|
|
60
|
+
|
|
61
|
+
**Architecture.** The host half is `RoomService`, a Typert Remote service (provided as `room`) owning promotion, roster management, the human @-intake, the notification gate, the task board and run cancellation; dispatch records and first tasks execute through the `DispatchEngine`, durable goals through the `PlanService` (one serialized writer per room). The room's entire state is the session's `room/*` custom-event journal — log-only events: persistence and reload-replay come free, the model never sees them, and a harness without this plugin replays the session safely. Every read folds the journal through a pure replay; every mutation appends and flushes. Cold reads (`isRoom`/`getState`) answer from a persistence inspection without waking an agent; a mutation on a cold room cold-resumes the agent under the preset the log records. An `agent/pre-step` guard keeps a stale client or another input surface from waking the DSH model behind an external coordinator: a native turn must carry an explicit room-sourced dispatch, and user input is rerouted through the room intake or rejected when it cannot be forwarded losslessly.
|
|
62
|
+
|
|
63
|
+
**Event-vocabulary seam.** The plugin registers its `room/*` types into the session-persistence event catalog at apply time. The registration must land in the toolchain's module instance — a profile-installed plugin would otherwise resolve a second catalog copy and the read path would refuse room logs after restart — so the specifier is computed and resolved at runtime, and a top-level await lets the plugin loader block boot on it. This is a temporary seam pending an official event-registration API.
|
|
64
|
+
|
|
65
|
+
**Client.** The browser half mounts the generated Remote via `ctx.remote.$mount`, registers the zh/en dictionaries, and feeds a client-side `RoomStore`. Slot entries: the **Invite agent** session-header action (`conversation.session.header.actions`, order 30), the **Members** `conversation.view` tab (order 20; hiding happens at registration level — a hidden tab is unregistered, not an empty body), the `conversation.composer` takeover (priority -10: claims exactly cached-room sessions, yields to pending approval interactions, and renders the dock capsules and stats row itself because their official seats hide with the fallback), and five `conversation.chat.node` renderers (`room-speech` / `room-run` / `room-event` / `room-relay` / `room-task-line`).
|
|
66
|
+
|
|
67
|
+
**Tool-row split (M4').** The core registers no model-facing tools at the profile root: the `room_invite` / `room_task` / `room_message` factories live in `./tool` and ship untagged; the companion `@khorsheed/dsh-room-tool` mounts the row inside agent-preset compositions (granted per session) and applies its own tool-origin tag. `room_invite` and `room_message` promote the calling session into a room; `room_task` writes the shared board through the same host functions the capsule UI uses. External members reach `room_read` / `room_invite` / `room_message` / `room_plan` through the authenticated family bridge (`receiveMemberCommand`), where room and actor identity are host-owned, never tool arguments.
|
|
68
|
+
|
|
69
|
+
**Family coupling.** The only coupling to the local-agent family is a probed facade — `ctx.get('localAgent')` plus method-existence duck-typing, with types as type-only imports drift-checked at compile time. An absent facade degrades CLI members (structured `local-agent-unavailable` at invite, journaled `failed` runs at dispatch) and never fails the boot. The notification gate's `receiveMemberMessage` is duck-type-called by the family bridge and runtime-validated across the untyped package boundary.
|
|
70
|
+
|
|
71
|
+
**Model experience.** The current goal rides the top of the roster section in every member prompt; there is deliberately no blackboard fold — member prompts never consume the room's running log (speech/dispatch events are journaled for UI projection and replay only). Model-facing tools arrive with the session's preset grant, tagged by the companion package.
|
|
72
|
+
|
|
73
|
+
**Identity triangle.** cordis row id `room` (`cordis.patch.yml`) = `clientBundle('@khorsheed/dsh-room')` (`tsdown.config.ts`) = `src/invariant.ts` `PACKAGE_NAME`. Exports: `.` host service, `/client` (plugin `apply`/`inject` plus the `RoomRemote` type), `/tool` factories, `/types`, `/typert`, `/remote`, `/invariant`.
|
|
74
|
+
|
|
75
|
+
</details>
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
Part of the [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo (`packages/room`). Issues and contributions welcome there.
|
|
80
|
+
|
|
81
|
+
## Changelog
|
|
82
|
+
|
|
83
|
+
See [CHANGELOG.md](CHANGELOG.md).
|
package/README.i18n.yaml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bilingual-pair consistency record: the git blob hash of each side as of the
|
|
2
2
|
# last confirmed-consistent state. Both languages carry equal authority; after
|
|
3
3
|
# editing either side, bring the other along and re-record with:
|
|
4
|
-
# pnpm run verify-translation-pairing --write packages/room/README.md
|
|
5
|
-
packages/room/README.md:
|
|
6
|
-
packages/room/README.
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/room/README.en.md
|
|
5
|
+
packages/room/README.en.md: a2e6488ad32ad1e4477f0a75e5b586e0069cbc9b
|
|
6
|
+
packages/room/README.md: 43579f4f6dc5b2e5fa9415e96d6f584afe9752ba
|
package/README.md
CHANGED
|
@@ -1,48 +1,83 @@
|
|
|
1
1
|
# @khorsheed/dsh-room
|
|
2
2
|
|
|
3
|
-
English
|
|
3
|
+
[English](README.en.md) | 中文
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
一个会话,一整队 agent——把 DSH、Kimi、Codex、Claude Code 邀请进来,@ 名字派活;协调者拆目标、成员交证据,验收还是人说了算。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
让多个 agent 干同一件事,过去只能在几个窗口之间复制粘贴,或者靠一次性的子代理调用——返回即遗忘。Room 把会话本身变成共享的协作场所:邀请第一位成员,当前会话就升级为 Room,原生 DSH agent 入座初始协调者;每位成员跨轮次、跨重启都保留自己的原生会话。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-1.png" width="640" alt="一个进行中的 Room:聊天流里的成员回执与运行行,输入框上方展开的 @ 成员菜单">
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## 特性
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- **邀请即升级**——没有单独的「创建房间」步骤:在任意会话里邀请第一位成员,它就变成 Room;原生 DSH agent 入座初始协调者(新 Room 命名为 `dsh`,已有 Room 保留日志里记录的寻址名)。
|
|
14
|
+
- **@ 寻址与并行派发**——开头的 `@name` 指向已有成员,多个名字并行派发;从补全菜单选中的提及即使位于句中也明确寻址,手写在正文里的提及则不算(菜单永不创建成员)。同一成员的轮次共用一条队列,不同成员并发执行;请求带持久化身份,重试不会重复已接受的工作。
|
|
15
|
+
- **协调者交接**——任何准备好的成员(DSH、Codex、Claude Code、Kimi)都可以在成员页「设为协调者」;交接记录携带目标、计划状态、未结任务和最近上下文。协调者运行中时,必须等当前轮次落定才能替换。
|
|
16
|
+
- **后台委派、回报自动对账**——普通聊天不必建立正式计划:协调者用 `room_message` 派发小型后台任务,在轮次边界自动收到带关联标识的成果回报。成员之间的普通通知(`member_message`、回答末尾的 `@name`)仍走人工确认/忽略闸门——该闸门从不阻塞协调者任务回报。
|
|
17
|
+
- **耐久目标计划与证据验收**——较大工作建立正式目标:阶段、层级任务、依赖、执行尝试、提交的证据,以及明确的验收或返工。生成结束不等于验收通过;前置任务验收后,后续任务才有资格执行。预算约束整个目标的并发数、总执行次数、每项任务执行次数和目标推进时长(不含暂停时间);暂停、继续、调整预算、取消与完成都是人的指令。重启后未确定的执行标记为待核对、计划暂停——核对必须提供证据,绝不盲目重跑。
|
|
18
|
+
- **成员保留原生会话**——成员页记录名称、provider、角色、工作目录覆盖(留空继承 Room 目录)、有效配置与会话入口;面包屑与任务入口能进入成员自己的会话,查看工具、耗时与 token 用量。Room 原生会话的统计不是所有成员消耗的总和。
|
|
19
|
+
- **共享模型/强度控制**——协调者与成员输入栏共用同一套 core 模型/effort 控制;运行中选择新配置会排到下一完整轮次(工具续跑沿用本轮配置),冻结的评测成员拒绝变更。原生 DSH 主会话仍使用宿主模型选择器及其语义——它不是 local-agent 成员控制器。
|
|
20
|
+
- **实时输出与定向停止**——成员把原生正文与推理增量同时呈现在自己的会话和 Room 中;最终消息与工具记录仍是权威内容。定向停止只中断该成员,非空部分输出带明确的停止/失败标记、耗时与会话入口保留;长回答可从紧凑预览展开。
|
|
21
|
+
- **入口随 preset 授权显隐、失败放行**——「邀请 agent」chip 与「成员」tab 只在当前会话的 preset 组合授予 `@khorsheed/dsh-room-tool` 行时出现;读不到组合时保持可见(fail-open);已是 Room 的会话始终保留界面。
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-invite.png" width="640" alt="成员标签页:空态的「把会话变成多 agent 协作间」与会话头部的「邀请 agent」入口">
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
<img src="https://raw.githubusercontent.com/Khorsheed/dsh-web-basic/main/docs/screenshots/room-2.png" width="640" alt="成员页:成员卡片(名称、provider、角色、模型)与「设为协调者」操作">
|
|
18
26
|
|
|
19
|
-
|
|
27
|
+
## 安装
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
The coordinator composer and member composer use the same core model/effort control. Model directories retain native identifiers, aliases, display names and supported reasoning choices; candidate provenance and completeness remain in the directory contract. The shared picker shows model/effort choices, loading and actionable failures without catalog maintenance controls. Choosing a configuration while busy queues it for the next complete turn, including tool continuations; core owns current/pending state, revisions, cancellation and retry. Frozen evaluation members reject configuration changes. The original native DSH session still uses the host model selector and its semantics; it is not a local-agent member controller.
|
|
26
|
-
|
|
27
|
-
Live members stream native text and reasoning into both their own conversation and Room. Final messages and tool records remain authoritative. A targeted Stop interrupts only that member, preserving nonempty partial output with an explicit stopped/failed label, duration and child-session link. Long Room replies can expand from a compact preview. No P95 latency guarantee follows from the transport interval alone; measured acceptance is tracked separately.
|
|
29
|
+
```sh
|
|
30
|
+
dsh plugin --profile web add @khorsheed/dsh-room
|
|
31
|
+
```
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
本包自行挂载 loader 行与浏览器贡献;重启 web 实例后生效。需要外部 CLI 成员时,同时安装 local-agent core 和所需 provider——没有它们,Room 仍可与原生 DSH 协调者正常协作。面向模型的工具(`room_invite` / `room_task` / `room_message`)由伴生包 `@khorsheed/dsh-room-tool` 提供,按会话 preset 授权。
|
|
30
34
|
|
|
31
35
|
```sh
|
|
32
|
-
dsh plugin
|
|
36
|
+
dsh plugin --profile web remove @khorsheed/dsh-room
|
|
33
37
|
```
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
卸载移除本插件的全部界面;已持久化的 Room 日志保留在各自会话日志中。
|
|
36
40
|
|
|
37
41
|
## Compatibility
|
|
38
42
|
|
|
39
|
-
- npm
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
- npm 发布线(`@deepseek-ai/dsh@0.1.5-rc.1`):✅ 支持、带一处设计内降级——0.1.5-rc.1 全量 boot 实证通过(42 包含 capture,2026-09-25),经三层兼容修复([preset-registry 双名探测](../../.agents/notes/implemented/bug-fix/2026-09-25-preset-registry-dual-name-probe.md)、[typert codec 双形状](../../.agents/notes/implemented/bug-fix/2026-09-25-typert-codec-dual-shape.md)、[face 自带 zod@4](../../.agents/notes/implemented/bug-fix/2026-09-25-typert-faces-carry-zod-v4.md));`minHost` 钉在 0.1.5-rc.1。外部成员依赖 local-agent 家族(core + provider),该家族尚未发布到 npm:缺失时成员准备、共享模型/强度控制与认证成员工具返回不可用,原生 DSH Room 功能保持完整。候选 tarball 在 npm 宿主上的全新安装与升级检查通过,旧 Room 状态得到保留。
|
|
44
|
+
- 源码线(deepseek-harness master):✅(verifiedHost: 0.1.7-rc.2——也是 3080 生产实证线)——Session V4 适配:主 agent followup 的 source 改为生产者归属 kind `room`(V4 原生准入在落盘写入时拒收退役的 `kind: 'plugin'` 包装;0.1.5 宿主的 `user/message` 准入只查 kind 非空,两条线都能落盘),读侧兼认 `room`、`plugin:@khorsheed/dsh-room`(V3→V4 迁移形态)与 V3 包装存量。`conversation.chat.node` rc.1 契约复验通过(5 个 room 渲染器均不触 hookContext 与 disclosure 工厂)。DSH/Kimi 协调者、委派、两阶段验收与中断恢复已端到端实测——见[验收记录](../../docs/acceptance/room-coordinator-2026-09-19.md)。
|
|
45
|
+
|
|
46
|
+
## 已知限制
|
|
47
|
+
|
|
48
|
+
- **成员间通知仍需人工确认**——`member_message` 转发与回答末尾的 `@name` 先落 pending 日志,等人确认或忽略;只有协调者任务回报不经过这道闸门。
|
|
49
|
+
- **外部成员依赖 local-agent 家族**——家族发布并安装之前,CLI 成员准备、共享控制与认证成员工具降级为不可用(邀请时返回结构化 `local-agent-unavailable`,派发落 `failed` 运行记录);原生 DSH 成员不受影响。
|
|
50
|
+
- **Codex/Claude 运行验收仍待完成**——DSH 与 Kimi 成员已端到端实测;Codex/Claude 认证运行尚未验收,完整 P95 流式门槛也未关闭——通道间隔本身证明不了 P95 延迟。
|
|
51
|
+
- **已持久化的 Room 需要保持挂载本插件**——`room/*` 事件词汇表由插件注册进会话事件目录(等待官方注册 API 的临时 seam),未挂载的构建按设计拒读该日志。
|
|
52
|
+
- **成员标识与操作样式复用宿主视觉**——跟随宿主 chrome,上游视觉变化时需要跟进复验。
|
|
53
|
+
- **跨宿主绘制测量假设同钟**——本地诊断假设共享时钟;远程宿主的测量需要对齐时钟。
|
|
54
|
+
- **模型回答成功不能排除存储故障**——持久化失败以诊断形式呈现。
|
|
55
|
+
|
|
56
|
+
## 实现原理
|
|
57
|
+
|
|
58
|
+
<details>
|
|
59
|
+
<summary>内部结构(点击展开)</summary>
|
|
60
|
+
|
|
61
|
+
**架构。** 宿主半部分是 `RoomService`——一个 Typert Remote 服务(以 `room` 提供),掌管升级、名册管理、人类 @ 入口、通知闸门、任务板与运行取消;派发记录与首个任务由 `DispatchEngine` 执行,耐久目标由 `PlanService` 负责(每个房间一条串行写者)。房间的全部状态就是会话的 `room/*` 自定义事件日志——纯日志事件:持久化与重载回放免费获得,模型永远看不到,未挂载本插件的宿主也能安全回放该会话。每次读取把日志经纯函数回放折出状态,每次写入追加并落盘。冷读取(`isRoom`/`getState`)经持久化检视回答,不唤醒 agent;对冷房间的写入先按日志记录的 preset 冷恢复 agent。`agent/pre-step` 守卫防止过期的客户端或其他输入面在外部协调者背后唤醒 DSH 模型:原生轮次必须携带明确的 room 来源派发,用户输入改走房间入口路由,无法无损转发时直接拒绝。
|
|
62
|
+
|
|
63
|
+
**事件词汇 seam。** 插件在 apply 时把 `room/*` 类型注册进会话持久化的事件目录。注册必须落在工具链的模块实例里——profile 安装的插件否则会解析出第二份目录副本,重启后读路径会拒读 room 日志——因此 specifier 在运行时拼出并解析,顶层 await 让插件加载器阻塞 boot 直到注册完成。这是等待官方事件注册 API 的临时 seam。
|
|
64
|
+
|
|
65
|
+
**客户端。** 浏览器半经 `ctx.remote.$mount` 挂载生成的 Remote,注册 zh/en 词典,并驱动客户端 `RoomStore`。槽位条目:会话头部「邀请 agent」动作(`conversation.session.header.actions`,order 30)、「成员」`conversation.view` tab(order 20;隐藏发生在注册层——隐藏的 tab 是注销而非空体)、`conversation.composer` 接管(priority -10:只认领缓存判定为 Room 的会话,对挂起的审批交互让位;dock 胶囊与统计行由它自行渲染,因为它们的官方座位随被藏起的回退树一起消失),以及五个 `conversation.chat.node` 渲染器(`room-speech` / `room-run` / `room-event` / `room-relay` / `room-task-line`)。
|
|
66
|
+
|
|
67
|
+
**工具行拆分(M4')。** core 不在 profile 根注册任何面向模型的工具:`room_invite` / `room_task` / `room_message` 的工厂留在 `./tool` 且不带 origin 标签;伴生包 `@khorsheed/dsh-room-tool` 把工具行挂进 agent preset 组合(按会话授予)并打上自己的 origin 标签。`room_invite` 与 `room_message` 会把调用所在会话升级为 Room;`room_task` 与胶囊 UI 走同一组宿主函数写共享任务板。外部成员经认证家族桥(`receiveMemberCommand`)使用 `room_read` / `room_invite` / `room_message` / `room_plan`——房间与调用者身份由宿主持有,绝不出现在工具参数里。
|
|
68
|
+
|
|
69
|
+
**家族耦合。** 与 local-agent 家族唯一的耦合是探测式门面——`ctx.get('localAgent')` 加方法存在性鸭子类型判断,类型仅作 type-only 导入、编译期漂移检查。门面缺席时 CLI 成员降级(邀请返回结构化 `local-agent-unavailable`,派发落 `failed` 运行记录),绝不影响 boot。通知闸门的 `receiveMemberMessage` 由家族桥鸭子调用,跨无类型包边界做运行时校验。
|
|
70
|
+
|
|
71
|
+
**模型体验。** 当前目标随每个成员提示词的名册段顶部下发;刻意不做黑板折叠——成员提示词从不消费房间的运行日志(speech/dispatch 事件只为 UI 投影与回放落日志)。面向模型的工具随会话 preset 授予到达,由伴生包打标。
|
|
72
|
+
|
|
73
|
+
**身份三角。** cordis 行 id `room`(`cordis.patch.yml`)= `clientBundle('@khorsheed/dsh-room')`(`tsdown.config.ts`)= `src/invariant.ts` 的 `PACKAGE_NAME`。导出:`.` 宿主服务、`/client`(插件 `apply`/`inject` 与 `RoomRemote` 类型)、`/tool` 工具工厂、`/types`、`/typert`、`/remote`、`/invariant`。
|
|
74
|
+
|
|
75
|
+
</details>
|
|
76
|
+
|
|
77
|
+
## 开发
|
|
43
78
|
|
|
44
|
-
|
|
79
|
+
隶属 [dsh-plugins](https://github.com/Khorsheed/dsh-plugins) monorepo(`packages/room`)。问题与贡献请移步该仓库。
|
|
45
80
|
|
|
46
|
-
##
|
|
81
|
+
## 变更记录
|
|
47
82
|
|
|
48
|
-
|
|
83
|
+
见 [CHANGELOG.md](CHANGELOG.md)。
|