dsh-session-bridge 0.2.0 → 0.3.0
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/README.md +52 -7
- package/README.zh.md +35 -5
- package/dsh.plugin.json +2 -1
- package/lib/index.js +477 -41
- package/package.json +1 -1
- package/src/core.ts +215 -13
- package/src/monitor.ts +126 -1
- package/src/tools.ts +153 -16
package/README.md
CHANGED
|
@@ -20,13 +20,23 @@ action does.
|
|
|
20
20
|
- **Send messages to any session.** `session_bridge_send` appends a turn
|
|
21
21
|
(`mode=queue`) or injects steering into the running step (`mode=steer`), and
|
|
22
22
|
can optionally wait for the next reply.
|
|
23
|
-
- **Wait for a reply.** `session_bridge_wait` blocks until
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
- **Wait for a reply or a segment.** `session_bridge_wait` blocks until new
|
|
24
|
+
assistant output appears after a given seq: `waitFor=reply` (default) returns
|
|
25
|
+
as soon as a new **text** reply is readable; `waitFor=segment` returns as
|
|
26
|
+
soon as any new **completed output step** appears (an `assistant/message` —
|
|
27
|
+
text, reasoning, or tool-call turn), *without* waiting for the whole turn, so
|
|
28
|
+
you can observe output paragraph by paragraph as it is produced. With
|
|
29
|
+
`requireTurnEnd` it additionally waits for the turn to settle.
|
|
30
|
+
Timeout / abort return the partial result rather than throwing.
|
|
27
31
|
- **Read any session.** `session_bridge_read` folds a session's event log into
|
|
28
32
|
readable rows — live or offline (from persistence) — with `sinceSeq` paging,
|
|
29
33
|
role filtering, and a `limit` (default 20, max 100).
|
|
34
|
+
- **Read output paragraph by paragraph.** `session_bridge_segments` returns the
|
|
35
|
+
session's **completed output segments** — every finished assistant step (one
|
|
36
|
+
`assistant/message`: its text, reasoning, and requested tool calls) as its own
|
|
37
|
+
row, paged forward via `sinceSeq`, returning the next cursor. It works live or
|
|
38
|
+
offline and does **not** wait for the whole turn, so you can follow a long
|
|
39
|
+
agentic run step by step (chain-of-thought included when the model streams it).
|
|
30
40
|
- **Resume offline sessions.** `session_bridge_resume` brings a persisted
|
|
31
41
|
session back online (idempotent); it can also override provider / model.
|
|
32
42
|
- **Find sessions.** `session_bridge_find` matches by title, id, workspace, or
|
|
@@ -63,6 +73,40 @@ task is wrapped up rather than nudged forever. Logs go to
|
|
|
63
73
|
|
|
64
74
|
Control it with `session_bridge_monitor_start` / `_stop` / `_list`.
|
|
65
75
|
|
|
76
|
+
### Chain-of-thought monitoring & rules
|
|
77
|
+
|
|
78
|
+
The bridge can watch another session's **chain-of-thought** (reasoning) in real
|
|
79
|
+
time — not just its final reply — and act on it:
|
|
80
|
+
|
|
81
|
+
- **Observe it live.** `session_bridge_status` returns three chain-of-thought
|
|
82
|
+
fields on a running session: `lastReasoning` (the most recent finalized
|
|
83
|
+
reasoning block), `liveReasoning` (the in-flight reasoning streamed for the
|
|
84
|
+
current handled turn, from `assistant/chunk` `reasoning-delta` events), and
|
|
85
|
+
`reasoningTail` (a compact, char-bounded merged preview). Use the
|
|
86
|
+
`reasoning` param (`none | last | live | tail`) to pick which fields come
|
|
87
|
+
back; `tail` is the default and costs the least.
|
|
88
|
+
- **Read paragraph by paragraph.** `session_bridge_segments` returns each completed output
|
|
89
|
+
step (one `assistant/message` — text, reasoning, or tool-call turn) as its own segment,
|
|
90
|
+
paged forward via `sinceSeq`, without waiting for the whole turn.
|
|
91
|
+
- **Or read it per message.** `session_bridge_read` with `includeReasoning`
|
|
92
|
+
returns the finalized reasoning of each assistant message.
|
|
93
|
+
- **Enforce rules.** `session_bridge_monitor_start` accepts `coRules` — an
|
|
94
|
+
array of { match: contains|not-contains, field: reasoning|text|both,
|
|
95
|
+
value: string, action: steer|cancel, message?: string } and `cotMinHits`.
|
|
96
|
+
Each poll the watchdog matches the rule's condition against the live
|
|
97
|
+
reasoning/text and, once it stays matched for `cotMinHits` consecutive polls
|
|
98
|
+
(default 1), fires the action: `steer` injects a guiding user message,
|
|
99
|
+
`cancel` terminates the session. Example — "stop the session the moment its
|
|
100
|
+
reasoning no longer contains I'm" becomes:
|
|
101
|
+
|
|
102
|
+
coRules: [{ "match": "not-contains", "field": "reasoning", "value": "I'm", "action": "cancel" }]
|
|
103
|
+
|
|
104
|
+
Caveats: a `not-contains` rule on `reasoning` deliberately **does not fire**
|
|
105
|
+
when the target session produces no reasoning at all (e.g. a non-reasoning
|
|
106
|
+
model or reasoningEffort off), so you don't cancel sessions that simply
|
|
107
|
+
don't stream a chain-of-thought. Repeated fires are throttled by a cooldown,
|
|
108
|
+
and each evaluation/trigger is written to the monitor log.
|
|
109
|
+
|
|
66
110
|
## Requirements
|
|
67
111
|
|
|
68
112
|
- [Node.js](https://nodejs.org) ≥ 20
|
|
@@ -186,13 +230,14 @@ registration and junction; not re-assembled on restart).
|
|
|
186
230
|
|---|---|
|
|
187
231
|
| `session_bridge_create` | Create a main session (current or another workspace via `workspaceId` / `cwd`); optional first prompt + `waitForReply`. |
|
|
188
232
|
| `session_bridge_send` | Send a message (`mode=queue`/`steer`); optional wait-for-reply. |
|
|
189
|
-
| `session_bridge_wait` | Wait for
|
|
233
|
+
| `session_bridge_wait` | Wait for new output after `sinceSeq`: `waitFor=reply` (text) or `waitFor=segment` (any completed step, no full-turn wait); optional `requireTurnEnd`. |
|
|
190
234
|
| `session_bridge_read` | Read messages — live or offline; `sinceSeq` paging, `role` filter, `limit`. |
|
|
235
|
+
| `session_bridge_segments` | Read completed output segments (each finished assistant step) incrementally by paragraph — live or offline. |
|
|
191
236
|
| `session_bridge_resume` | Bring a persisted session back online (idempotent). |
|
|
192
237
|
| `session_bridge_find` | Find sessions by title / id / workspace / directory across workspaces. |
|
|
193
|
-
| `session_bridge_status` | Read a session's live progress (running, open turn, stall detection, pending work, latest reply). |
|
|
238
|
+
| `session_bridge_status` | Read a session's live progress (running, open turn, stall detection, pending work, latest reply) plus live/finalized chain-of-thought (`reasoning` param). |
|
|
194
239
|
| `session_bridge_cancel` | Stop a running session (abort active turn; clear queued/steering work unless `keepInbox`). |
|
|
195
|
-
| `session_bridge_monitor_start` | Start a background watchdog on a main session (poll, nudge, correct, cancel, wrap up). |
|
|
240
|
+
| `session_bridge_monitor_start` | Start a background watchdog on a main session (poll, nudge, correct, cancel, wrap up); supports chain-of-thought `coRules` (e.g. reasoning not-contains "I'm" → cancel). |
|
|
196
241
|
| `session_bridge_monitor_stop` | Stop a watchdog (keep the session itself running). |
|
|
197
242
|
| `session_bridge_monitor_list` | List active watchdogs and their state. |
|
|
198
243
|
| `session_bridge_archive` | Archive a session (hidden from groupings; history and position preserved). |
|
package/README.zh.md
CHANGED
|
@@ -14,10 +14,17 @@
|
|
|
14
14
|
reasoning effort 默认继承调用会话。
|
|
15
15
|
- **向任意会话发消息。** `session_bridge_send` 追加一轮(`mode=queue`)或向运行中的步骤注入
|
|
16
16
|
steering(`mode=steer`),可选等待下一条回复。
|
|
17
|
-
-
|
|
18
|
-
|
|
17
|
+
- **等待回复或段落。** `session_bridge_wait` 阻塞直至 `sinceSeq` 之后出现新的 assistant 输出:
|
|
18
|
+
`waitFor=reply`(默认)在有新的**文本**回复可读时立即返回;`waitFor=segment` 在任意新**已完成
|
|
19
|
+
输出步骤**出现时立即返回(一个 `assistant/message`——文本、推理或工具调用段),*无需*等整个
|
|
20
|
+
turn 结束,从而可以按段落逐段观察输出。开 `requireTurnEnd` 则同时等待回合收尾。
|
|
21
|
+
超时 / 中止返回部分结果,而非抛错。
|
|
19
22
|
- **读取任意会话。** `session_bridge_read` 把会话事件日志折叠为可读行——live 或离线(持久化)均可;
|
|
20
23
|
支持 `sinceSeq` 分页、role 过滤、`limit`(默认 20,最大 100)。
|
|
24
|
+
- **按段落读取输出。** `session_bridge_segments` 返回会话的**已完成输出段落**——每个已完成的
|
|
25
|
+
assistant 步骤(一个 `assistant/message`:其文本、推理与请求的工具调用)作为一行,用 `sinceSeq`
|
|
26
|
+
增量翻页并返回下一游标。live 或离线均可用,*无需*等整个 turn 结束,因此可以逐步跟踪长 agentic
|
|
27
|
+
任务(模型流式推理时,段落中一并包含思维链)。
|
|
21
28
|
- **恢复离线会话。** `session_bridge_resume` 让持久化会话重新上线(幂等),可覆盖 provider / model。
|
|
22
29
|
- **查找会话。** `session_bridge_find` 跨全部工作区按 标题 / id / workspace / 目录 匹配,返回
|
|
23
30
|
live/running 状态、标题、工作目录;bridge 登记的标题作为别名参与匹配。
|
|
@@ -46,6 +53,28 @@
|
|
|
46
53
|
|
|
47
54
|
用 `session_bridge_monitor_start` / `_stop` / `_list` 控制。
|
|
48
55
|
|
|
56
|
+
### 思维链(CoT)监控与规则
|
|
57
|
+
|
|
58
|
+
会话桥可以**实时监控**另一个会话的思维链(chain-of-thought / reasoning),而不只等它的最终回复:
|
|
59
|
+
|
|
60
|
+
- **实时观察**:`session_bridge_status` 对运行中会话返回三块思维链字段——`lastReasoning`
|
|
61
|
+
(最近一条已定型推理块)、`liveReasoning`(当前正在处理的 turn 的进行中推理,来自
|
|
62
|
+
`assistant/chunk` 的 `reasoning-delta` 流)、`reasoningTail`(紧凑、受字符上限的合并预览)。
|
|
63
|
+
用 `reasoning` 参数(`none | last | live | tail`)选择返回哪些字段,默认 `tail` 最省 token。
|
|
64
|
+
- **按段落读取**:`session_bridge_segments` 把每个已完成输出步骤(一个 `assistant/message`——文本、推理或工具调用段)当作一个段落返回,用 `sinceSeq` 增量翻页,无需等整个 turn。
|
|
65
|
+
- **按消息读取**:`session_bridge_read` 带 `includeReasoning` 可返回每条 assistant 消息的已定型推理。
|
|
66
|
+
- **规则执行**:`session_bridge_monitor_start` 接受 `coRules`(数组,元素为 { match:
|
|
67
|
+
contains|not-contains, field: reasoning|text|both, value: string, action: steer|cancel,
|
|
68
|
+
message?: string })与 `cotMinHits`。每次轮询守护用规则的匹配条件对照实时思维链/文本,
|
|
69
|
+
连续命中 `cotMinHits` 次(默认 1)后触发动作:`steer` 注入引导性用户消息,`cancel` 终止会话。
|
|
70
|
+
示例——"思维链一旦不再包含 I'm 就停止该会话":
|
|
71
|
+
|
|
72
|
+
coRules: [{ "match": "not-contains", "field": "reasoning", "value": "I'm", "action": "cancel" }]
|
|
73
|
+
|
|
74
|
+
注意:作用在 `reasoning` 上的 `not-contains` 规则在目标会话**完全不产生推理**时故意不触发
|
|
75
|
+
(如非推理模型或 reasoningEffort off),避免误 cancel 根本不流式思维链的会话。重复触发有冷却
|
|
76
|
+
节流,每次评估/触发都会写入监控日志。
|
|
77
|
+
|
|
49
78
|
## 环境要求
|
|
50
79
|
|
|
51
80
|
- [Node.js](https://nodejs.org) ≥ 20
|
|
@@ -151,13 +180,14 @@ dev_inject_plugin D:\code\dsh-session-bridge
|
|
|
151
180
|
|---|---|
|
|
152
181
|
| `session_bridge_create` | 创建主会话(当前或其它工作区,经 `workspaceId` / `cwd`);可选首条 prompt + `waitForReply`。 |
|
|
153
182
|
| `session_bridge_send` | 发消息(`mode=queue`/`steer`);可选等待回复。 |
|
|
154
|
-
| `session_bridge_wait` | 等待 `sinceSeq`
|
|
183
|
+
| `session_bridge_wait` | 等待 `sinceSeq` 之后新输出:`waitFor=reply`(文本)或 `waitFor=segment`(任一已完成步骤即返回,无需等整个 turn);可选 `requireTurnEnd`。 |
|
|
155
184
|
| `session_bridge_read` | 读取消息 —— live 或离线;`sinceSeq` 分页、`role` 过滤、`limit`。 |
|
|
185
|
+
| `session_bridge_segments` | 增量读取已完成输出段落(每个已完成的 assistant 步骤)—— live 或离线。 |
|
|
156
186
|
| `session_bridge_resume` | 让持久化会话重新上线(幂等)。 |
|
|
157
187
|
| `session_bridge_find` | 跨工作区按 标题 / id / workspace / 目录 查找会话。 |
|
|
158
|
-
| `session_bridge_status` | 读取会话实时进度(running、openTurn
|
|
188
|
+
| `session_bridge_status` | 读取会话实时进度(running、openTurn、卡住检测、待处理、最新回复)及实时/已定型思维链(`reasoning` 参数)。 |
|
|
159
189
|
| `session_bridge_cancel` | 停止运行中的会话(中止活动 turn;`keepInbox` 保留排队/steering 输入)。 |
|
|
160
|
-
| `session_bridge_monitor_start` |
|
|
190
|
+
| `session_bridge_monitor_start` | 对一个主会话启动后台守护(轮询、催办、纠偏、终止、收尾);支持思维链 `coRules`(如 reasoning not-contains "I'm" → cancel)。 |
|
|
161
191
|
| `session_bridge_monitor_stop` | 停止守护(会话本身不终止)。 |
|
|
162
192
|
| `session_bridge_monitor_list` | 列出活动守护及其状态。 |
|
|
163
193
|
| `session_bridge_archive` | 归档会话(从分组隐藏;历史与位置保留)。 |
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-session-bridge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"description": "会话桥:创建主会话 / 向任意会话发消息 / 等待回复 / 读取消息 / 按名或 id 查找会话(支持跨工作区);另含监控/调度主任务与归档会话。",
|
|
6
6
|
"engines": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"session_bridge_send",
|
|
13
13
|
"session_bridge_resume",
|
|
14
14
|
"session_bridge_wait",
|
|
15
|
+
"session_bridge_segments",
|
|
15
16
|
"session_bridge_read",
|
|
16
17
|
"session_bridge_find",
|
|
17
18
|
"session_bridge_status",
|