dsh-session-bridge 0.2.1 → 0.3.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/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 a new text assistant
24
- reply appears after a given seq; with `requireTurnEnd` it also waits for the
25
- turn to settle. Timeout / abort return the partial result rather than
26
- throwing.
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 a new text assistant reply after `sinceSeq`; optional `requireTurnEnd`. |
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
- - **等待回复。** `session_bridge_wait` 阻塞直至 `sinceSeq` 之后出现新的带文本 assistant 回复;
18
- `requireTurnEnd` 则同时等待回合收尾。超时 / 中止返回部分结果,而非抛错。
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` 之后新的带文本 assistant 回复;可选 `requireTurnEnd`。 |
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,10 +1,10 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-session-bridge",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "main": "./lib/index.js",
5
5
  "description": "会话桥:创建主会话 / 向任意会话发消息 / 等待回复 / 读取消息 / 按名或 id 查找会话(支持跨工作区);另含监控/调度主任务与归档会话。",
6
6
  "engines": {
7
- "dsh": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0"
7
+ "dsh": "^0.1.0-rc.6 || ^0.1.1-0 || ^0.1.2-0 || ^0.1.5-0"
8
8
  },
9
9
  "contributes": {
10
10
  "tools": [
@@ -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",