dsh-agent-lines 0.3.8 → 0.3.9
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.en.md +7 -0
- package/CHANGELOG.md +7 -0
- package/README.en.md +30 -2
- package/README.md +30 -2
- package/bin/dsh-agent-lines.js +12 -1
- package/docs/PROTOCOL.en.md +2 -0
- package/docs/PROTOCOL.md +2 -0
- package/docs/en/index.html +3 -3
- package/docs/index.html +3 -3
- package/docs/market-index.json +2 -2
- package/examples/market-index.json +2 -2
- package/lib/store.js +32 -0
- package/lib/tools.js +24 -0
- package/package.json +1 -1
package/CHANGELOG.en.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文](CHANGELOG.md)
|
|
4
4
|
|
|
5
|
+
## 0.3.9 (2026-11-09)
|
|
6
|
+
|
|
7
|
+
- Added read-only line_observe: a manager feed of cross-line messages without prompts or state changes.
|
|
8
|
+
- Added CLI observe --json.
|
|
9
|
+
- README now documents version-by-version business scenarios; fixed line_handoff version (0.3.7).
|
|
10
|
+
- No schema change; line_send semantics unchanged.
|
|
11
|
+
|
|
5
12
|
## 0.3.8 (2026-11-09)
|
|
6
13
|
|
|
7
14
|
- line_status / line_list expose activity: turns/steps/decodeTokens/level/lastActivityAt.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
[English](CHANGELOG.en.md) | 中文
|
|
4
4
|
|
|
5
|
+
## 0.3.9 (2026-11-09)
|
|
6
|
+
|
|
7
|
+
- 新增只读 line_observe:管理线查看跨线消息 feed,不注入 prompt、不改消息状态。
|
|
8
|
+
- CLI 新增 observe --json。
|
|
9
|
+
- README 补“版本能力与业务场景”,修正 line_handoff 的版本标注(0.3.7)。
|
|
10
|
+
- 无 schema 变化,line_send 语义不变。
|
|
11
|
+
|
|
5
12
|
## 0.3.8 (2026-11-09)
|
|
6
13
|
|
|
7
14
|
- line_status / line_list 增加 activity:turns/steps/decodeTokens/level/lastActivityAt。
|
package/README.en.md
CHANGED
|
@@ -23,6 +23,32 @@ Use it when:
|
|
|
23
23
|
- You want one lead agent to decompose work, create the team, track progress, collect results, and report back.
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
## What each version adds (business scenarios)
|
|
27
|
+
|
|
28
|
+
### 0.3.6: replace a role when context is full
|
|
29
|
+
|
|
30
|
+
Scenario: a writer line has worked long enough that its context is saturated and quality drops.
|
|
31
|
+
Use: the manager calls line_create({ label: "writer", replace: true, force: true, reason: "context full" }).
|
|
32
|
+
Effect: the same label moves to a clean Session; the old Session is retired but kept; queued/claimed messages migrate; delivered/acked are never re-delivered; no manual routing.
|
|
33
|
+
|
|
34
|
+
### 0.3.7: hand off before replacing
|
|
35
|
+
|
|
36
|
+
Scenario: the new writer does not know what the old line finished, what is next, or which traps to avoid.
|
|
37
|
+
Use: line_handoff({ line: "writer", format: "md" }).
|
|
38
|
+
Effect: a structured snapshot (progress, backlog, recent messages, lifecycle) without a model call; the new line reads it first.
|
|
39
|
+
|
|
40
|
+
### 0.3.8: know when to replace
|
|
41
|
+
|
|
42
|
+
Scenario: the manager wants to see which line is close to saturation or has gone quiet.
|
|
43
|
+
Use: line_status / line_list expose activity.level, turns, steps, lastActivityAt.
|
|
44
|
+
Effect: a low/medium/high activity proxy, not a fake "78% context used"; exact context usage waits for DSH.
|
|
45
|
+
|
|
46
|
+
### 0.3.9: the manager can see cross-line traffic
|
|
47
|
+
|
|
48
|
+
Scenario: lines message each other directly; the manager needs visibility without every message becoming a manager turn.
|
|
49
|
+
Use: line_observe({ line: "writer", limit: 20 }) or CLI observe --json.
|
|
50
|
+
Effect: a read-only feed with from/to/state/summary; no prompt injection and no state change; line_send semantics unchanged.
|
|
51
|
+
|
|
26
52
|
## Install
|
|
27
53
|
|
|
28
54
|
One-command install (recommended; no need to find a profile):
|
|
@@ -36,7 +62,7 @@ The script picks the DSH Web profile, installs the plugin, and verifies agent-li
|
|
|
36
62
|
|
|
37
63
|
Offline or when npm is unavailable, use the local tarball:
|
|
38
64
|
|
|
39
|
-
bash install.sh ./dsh-agent-lines-0.3.
|
|
65
|
+
bash install.sh ./dsh-agent-lines-0.3.9.tgz
|
|
40
66
|
|
|
41
67
|
After install and restart, it works without a config. When you want a fixed manager/worker setup, paste the "Manager config" block below into the file printed by the installer.
|
|
42
68
|
|
|
@@ -139,6 +165,7 @@ Tools:
|
|
|
139
165
|
| `line_list` | List lines, status, unread counts, current line and role |
|
|
140
166
|
| `line_create` | Manager only: create a line; same label is idempotent; replace:true swaps the label to a fresh Session |
|
|
141
167
|
| `line_handoff` | Manager only: structured handoff snapshot (JSON/Markdown), no model call |
|
|
168
|
+
| `line_observe` | Manager only: read-only cross-line feed; no prompt injection, no state change |
|
|
142
169
|
| `line_retire` | Manager only: soft-retire; reject new sends, keep Session and history |
|
|
143
170
|
| `line_rebind` | Manager only: atomically switch a line to a new live Session, optionally migrating backlog |
|
|
144
171
|
| `line_rename` | Manager only: rename the sidebar title and persist it in lines.db |
|
|
@@ -155,7 +182,7 @@ Line tools other than `line_status` and `line_claim_manager` are registered only
|
|
|
155
182
|
|
|
156
183
|
A line does not inherit the old Session context. Recommended flow:
|
|
157
184
|
|
|
158
|
-
1. Have the old line write a handoff file (line_handoff is available from 0.3.
|
|
185
|
+
1. Have the old line write a handoff file (line_handoff is available from 0.3.7);
|
|
159
186
|
2. The manager calls `line_create({ label, replace: true, force: true, reason: "context full" })`;
|
|
160
187
|
3. The plugin creates a clean Session, atomically swaps the same label, and marks the old Session retired but keeps it;
|
|
161
188
|
4. queued/claimed messages migrate to the new line; delivered/acked stay on the old Session and are never re-delivered.
|
|
@@ -171,6 +198,7 @@ dsh-agent-lines list
|
|
|
171
198
|
dsh-agent-lines send --from frontend-line --to backend-line --text "hi"
|
|
172
199
|
dsh-agent-lines inbox --line backend-line
|
|
173
200
|
dsh-agent-lines ack --line backend-line --id msg_...
|
|
201
|
+
dsh-agent-lines --json observe --line writer --limit 20
|
|
174
202
|
dsh-agent-lines claim --agent agent-demo --line manager --session "$DSH_SESSION_ID"
|
|
175
203
|
dsh-agent-lines doctor
|
|
176
204
|
```
|
package/README.md
CHANGED
|
@@ -23,6 +23,32 @@ DSH 的 super agent 平替插件。
|
|
|
23
23
|
- 你希望一个负责人 agent 自己拆任务、建团队、追进度、收结果,最后向你汇报。
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
## 版本能力与业务场景
|
|
27
|
+
|
|
28
|
+
### 0.3.6:上下文满了,角色可以换人
|
|
29
|
+
|
|
30
|
+
场景:写手线连续工作很久,上下文配额耗尽;继续写容易出现前后矛盾。
|
|
31
|
+
用法:管理线调用 line_create({ label: "writer", replace: true, force: true, reason: "context full" })。
|
|
32
|
+
效果:同一个 label 切到干净 Session,旧 Session 只 retired、不删除;queued/claimed 消息迁移,delivered/acked 不重投;管理线不需要手工改路由。
|
|
33
|
+
|
|
34
|
+
### 0.3.7:换人之前先交接
|
|
35
|
+
|
|
36
|
+
场景:新写手不知道旧线做到哪、下一步是什么、哪些坑不能踩。
|
|
37
|
+
用法:line_handoff({ line: "writer", format: "md" })。
|
|
38
|
+
效果:生成结构化交接单(进度、积压、最近消息、生命周期),不调用模型;新线先读交接单再继续。
|
|
39
|
+
|
|
40
|
+
### 0.3.8:什么时候该换线
|
|
41
|
+
|
|
42
|
+
场景:管理线想知道哪条线快满了、哪条线最近没动静。
|
|
43
|
+
用法:line_status / line_list 看 activity.level、turns、steps、lastActivityAt。
|
|
44
|
+
效果:给出低/中/高活跃度,不伪造“上下文使用率 78%”;真实窗口等 DSH 上游提供。
|
|
45
|
+
|
|
46
|
+
### 0.3.9:管理线看得到跨线消息
|
|
47
|
+
|
|
48
|
+
场景:成员线之间直接同步,管理线需要知道发生了什么,但不希望每条消息都打断自己。
|
|
49
|
+
用法:line_observe({ line: "writer", limit: 20 }) 或 CLI observe --json。
|
|
50
|
+
效果:只读 feed,显示 from/to/state/摘要;不注入 prompt、不改消息状态;line_send 语义不变。
|
|
51
|
+
|
|
26
52
|
## 安装
|
|
27
53
|
|
|
28
54
|
一条命令安装(推荐,不需要自己找 profile):
|
|
@@ -36,7 +62,7 @@ DSH 的 super agent 平替插件。
|
|
|
36
62
|
|
|
37
63
|
离线或 npm 不可用时,用本地 tarball:
|
|
38
64
|
|
|
39
|
-
bash install.sh ./dsh-agent-lines-0.3.
|
|
65
|
+
bash install.sh ./dsh-agent-lines-0.3.9.tgz
|
|
40
66
|
|
|
41
67
|
安装并重启后,不写配置也可以直接使用;需要固定管理线/worker 时,再把下面“管理线配置”粘贴到脚本打印的配置文件。
|
|
42
68
|
|
|
@@ -144,6 +170,7 @@ level 是活跃度代理(low/medium/high),不是上下文使用率百分
|
|
|
144
170
|
| `line_list` | 列出线、状态、未读数、当前线和 role |
|
|
145
171
|
| `line_create` | 仅管理线:创建新线;同 label 幂等;传 replace:true 可给同 label 换新 Session |
|
|
146
172
|
| `line_handoff` | 仅管理线:生成结构化交接单(JSON/Markdown),不调模型 |
|
|
173
|
+
| `line_observe` | 仅管理线:只读跨线消息 feed;不注入 prompt、不改状态 |
|
|
147
174
|
| `line_retire` | 仅管理线:软下线;拒绝新发送,保留 Session/历史 |
|
|
148
175
|
| `line_rebind` | 仅管理线:把线原子切到新的 live Session,可迁移积压 |
|
|
149
176
|
| `line_rename` | 仅管理线:改侧栏标题,持久化到 lines.db |
|
|
@@ -160,7 +187,7 @@ level 是活跃度代理(low/medium/high),不是上下文使用率百分
|
|
|
160
187
|
|
|
161
188
|
线不会自动继承旧 Session 的上下文。推荐流程:
|
|
162
189
|
|
|
163
|
-
1. 让旧线写交接单(0.3.
|
|
190
|
+
1. 让旧线写交接单(0.3.7 起可用 `line_handoff`);
|
|
164
191
|
2. 管理线调用 `line_create({ label, replace: true, force: true, reason: "context full" })`;
|
|
165
192
|
3. 插件创建干净 Session、同 label 原子切换,旧 Session 标记 retired 但保留;
|
|
166
193
|
4. queued/claimed 消息迁移到新线;delivered/acked 留在旧 Session,不重投。
|
|
@@ -176,6 +203,7 @@ dsh-agent-lines list
|
|
|
176
203
|
dsh-agent-lines send --from frontend-line --to backend-line --text "hi"
|
|
177
204
|
dsh-agent-lines inbox --line backend-line
|
|
178
205
|
dsh-agent-lines ack --line backend-line --id msg_...
|
|
206
|
+
dsh-agent-lines --json observe --line writer --limit 20
|
|
179
207
|
dsh-agent-lines claim --agent agent-demo --line manager --session "$DSH_SESSION_ID"
|
|
180
208
|
dsh-agent-lines doctor
|
|
181
209
|
```
|
package/bin/dsh-agent-lines.js
CHANGED
|
@@ -9,6 +9,7 @@ import { LineError, lineId } from '../lib/protocol.js'
|
|
|
9
9
|
|
|
10
10
|
function usage() {
|
|
11
11
|
console.error(`Usage:
|
|
12
|
+
dsh-agent-lines [--db <path>] [--json] observe [--line <line>] [--since <epochMs>] [--limit N] [--agent <id>]
|
|
12
13
|
dsh-agent-lines [--db <path>] [--json] list
|
|
13
14
|
dsh-agent-lines [--db <path>] [--json] send --from <line> --to <line|agent#line> --text <text> [--agent <id>] [--key <key>] [--reply-to <id>]
|
|
14
15
|
dsh-agent-lines [--db <path>] [--json] inbox --line <line> [--agent <id>] [--limit N] [--all]
|
|
@@ -62,6 +63,16 @@ function main() {
|
|
|
62
63
|
}
|
|
63
64
|
const store = new LineStore(opts.db)
|
|
64
65
|
try {
|
|
66
|
+
if (command === 'observe') {
|
|
67
|
+
const result = store.observe({
|
|
68
|
+
agentId: String(opts.agent ?? 'agent-deepseek'),
|
|
69
|
+
line: opts.line === undefined ? null : String(opts.line),
|
|
70
|
+
since: Number(opts.since ?? 0),
|
|
71
|
+
limit: Number(opts.limit ?? 100),
|
|
72
|
+
})
|
|
73
|
+
print({ db: store.dbPath, ...result }, opts.json)
|
|
74
|
+
return 0
|
|
75
|
+
}
|
|
65
76
|
if (command === 'list') {
|
|
66
77
|
print({ db: store.dbPath, lines: store.listLines(), counts: store.counts() }, opts.json)
|
|
67
78
|
return 0
|
|
@@ -152,4 +163,4 @@ function main() {
|
|
|
152
163
|
}
|
|
153
164
|
}
|
|
154
165
|
|
|
155
|
-
process.exitCode = main()
|
|
166
|
+
process.exitCode = main()
|
package/docs/PROTOCOL.en.md
CHANGED
|
@@ -103,6 +103,7 @@ The new line is an ordinary DSH Session in the same DSH process; no OS process,
|
|
|
103
103
|
line_retire({ line, reason? })
|
|
104
104
|
line_rebind({ line, sessionId, migrate?: "queued" | "none", reason? })
|
|
105
105
|
line_create({ label, replace: true, force?, migrate?, title?, reason? })
|
|
106
|
+
line_observe({ line?, since?, limit? })
|
|
106
107
|
line_handoff({ line, format?: "md" | "json", limit?: number })
|
|
107
108
|
line_rename({ line, title })
|
|
108
109
|
|
|
@@ -112,6 +113,7 @@ The new line is an ordinary DSH Session in the same DSH process; no OS process,
|
|
|
112
113
|
- migrate=none: returns LINE_BACKLOG_NOT_EMPTY if the backlog is non-empty.
|
|
113
114
|
- replace: creates a fresh Session for the same label and rebinds; an active line requires force + reason.
|
|
114
115
|
- line_events records title/retire/rebind audit; titles survive restarts.
|
|
116
|
+
- line_observe is a manager-only read-only cross-line feed; it does not inject prompts or change state.
|
|
115
117
|
|
|
116
118
|
## Echo and reply depth
|
|
117
119
|
|
package/docs/PROTOCOL.md
CHANGED
|
@@ -95,6 +95,7 @@ line_move_workspace({ line, workspace }) 把已有线 Session 挂到已有工作
|
|
|
95
95
|
line_retire({ line, reason? })
|
|
96
96
|
line_rebind({ line, sessionId, migrate?: "queued" | "none", reason? })
|
|
97
97
|
line_create({ label, replace: true, force?, migrate?, title?, reason? })
|
|
98
|
+
line_observe({ line?, since?, limit? })
|
|
98
99
|
line_handoff({ line, format?: "md" | "json", limit?: number })
|
|
99
100
|
line_rename({ line, title })
|
|
100
101
|
|
|
@@ -104,6 +105,7 @@ line_move_workspace({ line, workspace }) 把已有线 Session 挂到已有工作
|
|
|
104
105
|
- migrate=none:backlog 非空时返回 LINE_BACKLOG_NOT_EMPTY。
|
|
105
106
|
- replace:同 label 创建新 Session 并 rebind;active 线需 force + reason。
|
|
106
107
|
- line_events 记录 title/retire/rebind 审计;title 持久化,重启保留。
|
|
108
|
+
- line_observe 仅管理线、只读跨线 feed;不注入 prompt、不改消息状态。
|
|
107
109
|
|
|
108
110
|
## 回声与回复深度
|
|
109
111
|
|
package/docs/en/index.html
CHANGED
|
@@ -43,7 +43,7 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
|
|
|
43
43
|
<div class="wrap">
|
|
44
44
|
<header>
|
|
45
45
|
<a class="brand" href="../"><span class="mark"></span>dsh-agent-lines</a>
|
|
46
|
-
<nav><a href="../">中文</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.
|
|
46
|
+
<nav><a href="../">中文</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.9">Release</a></nav>
|
|
47
47
|
</header>
|
|
48
48
|
<main>
|
|
49
49
|
<section class="hero" style="border:0;padding-bottom:22px">
|
|
@@ -54,7 +54,7 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
|
|
|
54
54
|
<div class="install">curl -fsSL https://raw.githubusercontent.com/Lencen/dsh-agent-lines/main/install.sh -o install.sh && bash install.sh</div>
|
|
55
55
|
<div class="actions">
|
|
56
56
|
<a class="btn primary" href="https://github.com/Lencen/dsh-agent-lines">GitHub repository</a>
|
|
57
|
-
<a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.
|
|
57
|
+
<a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.9">Download 0.3.9</a>
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
<div class="shot">
|
|
@@ -92,7 +92,7 @@ research (调研), architecture (架构), uiux (UIUX), dev (开发), test (测
|
|
|
92
92
|
After the team is ready, wait for my first task. Do not start by yourself.</pre>
|
|
93
93
|
<p style="color:var(--muted);font-size:14px">Restart DSH Web after install or update. Technical details, protocol, and limits: <a href="https://github.com/Lencen/dsh-agent-lines">README / architecture</a>. Community plugin, not an official DeepSeek product.</p>
|
|
94
94
|
</section>
|
|
95
|
-
<footer>dsh-agent-lines 0.3.
|
|
95
|
+
<footer>dsh-agent-lines 0.3.9 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
|
|
96
96
|
</main>
|
|
97
97
|
</div>
|
|
98
98
|
</body>
|
package/docs/index.html
CHANGED
|
@@ -43,7 +43,7 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
|
|
|
43
43
|
<div class="wrap">
|
|
44
44
|
<header>
|
|
45
45
|
<a class="brand" href="./"><span class="mark"></span>dsh-agent-lines</a>
|
|
46
|
-
<nav><a href="en/index.html">English</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.
|
|
46
|
+
<nav><a href="en/index.html">English</a><a href="https://github.com/Lencen/dsh-agent-lines">GitHub</a><a href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.9">Release</a></nav>
|
|
47
47
|
</header>
|
|
48
48
|
<main>
|
|
49
49
|
<section class="hero" style="border:0;padding-bottom:22px">
|
|
@@ -54,7 +54,7 @@ footer{padding:34px 0 48px;color:var(--muted);font-size:12px}
|
|
|
54
54
|
<div class="install">curl -fsSL https://raw.githubusercontent.com/Lencen/dsh-agent-lines/main/install.sh -o install.sh && bash install.sh</div>
|
|
55
55
|
<div class="actions">
|
|
56
56
|
<a class="btn primary" href="https://github.com/Lencen/dsh-agent-lines">GitHub 仓库</a>
|
|
57
|
-
<a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.
|
|
57
|
+
<a class="btn" href="https://github.com/Lencen/dsh-agent-lines/releases/tag/v0.3.9">下载 0.3.9</a>
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
<div class="shot">
|
|
@@ -92,7 +92,7 @@ research(调研)、architecture(架构)、uiux(UIUX)、dev(开发
|
|
|
92
92
|
团队建好后先待命,不要自动开工,等我发第一个任务。</pre>
|
|
93
93
|
<p style="color:var(--muted);font-size:14px">安装或更新后需要重启 DSH Web。技术细节、协议和限制见 <a href="https://github.com/Lencen/dsh-agent-lines">README / 架构文档</a>。社区插件,不是 DeepSeek 官方产品。</p>
|
|
94
94
|
</section>
|
|
95
|
-
<footer>dsh-agent-lines 0.3.
|
|
95
|
+
<footer>dsh-agent-lines 0.3.9 · Apache-2.0 · Community plugin for DeepSeek Harness. Not an official DeepSeek product.</footer>
|
|
96
96
|
</main>
|
|
97
97
|
</div>
|
|
98
98
|
</body>
|
package/docs/market-index.json
CHANGED
package/lib/store.js
CHANGED
|
@@ -542,6 +542,38 @@ export class LineStore {
|
|
|
542
542
|
return this.#stmt('SELECT * FROM line_events WHERE line_id = ? AND action = ? ORDER BY created_at DESC LIMIT 1').get(id, action)
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
+
/** Read-only cross-line feed for the manager; no state changes. */
|
|
546
|
+
observe({ agentId, line = null, since = 0, limit = 100 } = {}) {
|
|
547
|
+
const n = Math.min(200, Math.max(1, Number(limit) || 100))
|
|
548
|
+
const from = Math.max(0, Number(since) || 0)
|
|
549
|
+
const params = [agentId, agentId]
|
|
550
|
+
let sql = `SELECT id, from_agent, from_line, to_agent, to_line, body, state, reply_to, root_message_id,
|
|
551
|
+
hop, no_reply, created_at, delivered_at, acked_at
|
|
552
|
+
FROM messages WHERE (from_agent = ? OR to_agent = ?) AND from_line != to_line AND created_at > ?`
|
|
553
|
+
params.push(from)
|
|
554
|
+
if (line !== null && String(line).trim() !== '') {
|
|
555
|
+
sql += ' AND (from_line = ? OR to_line = ?)'
|
|
556
|
+
params.push(String(line), String(line))
|
|
557
|
+
}
|
|
558
|
+
sql += ' ORDER BY created_at DESC LIMIT ?'
|
|
559
|
+
params.push(n)
|
|
560
|
+
const rows = this.#stmt(sql).all(...params)
|
|
561
|
+
return {
|
|
562
|
+
agentId, line: line === null ? null : String(line), since: from, count: rows.length,
|
|
563
|
+
messages: rows.map(row => ({
|
|
564
|
+
id: row.id,
|
|
565
|
+
from: row.from_agent + '#' + row.from_line,
|
|
566
|
+
to: row.to_agent + '#' + row.to_line,
|
|
567
|
+
state: row.state,
|
|
568
|
+
noReply: Number(row.no_reply) === 1,
|
|
569
|
+
replyTo: row.reply_to,
|
|
570
|
+
hop: row.hop,
|
|
571
|
+
createdAt: row.created_at,
|
|
572
|
+
summary: String(row.body || '').replace(/\s+/g, ' ').slice(0, 240),
|
|
573
|
+
})),
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
545
577
|
/** Structured handoff snapshot: counts + recent messages + lifecycle events. */
|
|
546
578
|
handoff({ agentId, line, limit = 20, now = Date.now() }) {
|
|
547
579
|
const row = this.getLine(agentId, line, now)
|
package/lib/tools.js
CHANGED
|
@@ -398,6 +398,30 @@ export function registerToolsForAgent(agent, def, { config, store, lineDefs, cre
|
|
|
398
398
|
},
|
|
399
399
|
}))
|
|
400
400
|
|
|
401
|
+
disposers.push(agent.ctx.tools.register({
|
|
402
|
+
name: 'line_observe',
|
|
403
|
+
description: 'Manager-only read-only feed of recent cross-line messages (from/to, state, noReply, summary). Does not inject prompts or change any message state. Use it to watch team traffic without turning every message into a manager turn.',
|
|
404
|
+
parameters: {
|
|
405
|
+
type: 'object', additionalProperties: false,
|
|
406
|
+
properties: {
|
|
407
|
+
line: { type: 'string', description: 'Optional line filter (matches from or to)' },
|
|
408
|
+
since: { type: 'number', description: 'Only messages created after this epoch ms' },
|
|
409
|
+
limit: { type: 'number', description: 'Maximum messages, 1-200 (default 100)' },
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
output: OUTPUT,
|
|
413
|
+
execute: async (args, exec) => {
|
|
414
|
+
const caller = currentLine(exec, lineDefs)
|
|
415
|
+
if (caller.label !== config.createFrom) throw new LineError('LINE_CREATE_FORBIDDEN', `Only ${config.createFrom} may observe lines`, { caller: caller.label })
|
|
416
|
+
return store.observe({
|
|
417
|
+
agentId: config.agentId,
|
|
418
|
+
line: args.line === undefined ? null : String(args.line),
|
|
419
|
+
since: Number(args.since) || 0,
|
|
420
|
+
limit: limitValue(args.limit, 100, 200),
|
|
421
|
+
})
|
|
422
|
+
},
|
|
423
|
+
}))
|
|
424
|
+
|
|
401
425
|
disposers.push(agent.ctx.tools.register({
|
|
402
426
|
name: 'line_handoff',
|
|
403
427
|
description: 'Generate a structured handoff snapshot for a line: current metadata, backlog counts, recent messages, lifecycle events. Does not call a model; write the returned markdown to a file before retire/replace/rebind.',
|