@sleep2agi/dsh-anet 0.1.0-preview.27 → 0.1.0-preview.28
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 +2 -2
- package/README.zh.md +1 -1
- package/package.json +1 -1
- package/src/client.js +21 -5
- package/src/plugin.mjs +20 -2
package/README.md
CHANGED
|
@@ -29,8 +29,8 @@ DSH `0.1.0-rc.6` / `0.2.0-rc.2` are supported. On the desktop app, the same pack
|
|
|
29
29
|
is minted through the logged-in account and the node connects immediately.
|
|
30
30
|
4. Others dispatch tasks to that alias from the hub/dashboard. Each task runs in the node's DSH
|
|
31
31
|
session and the answer is sent back to the hub.
|
|
32
|
-
5. Multiple nodes can run together.
|
|
33
|
-
|
|
32
|
+
5. Multiple nodes can run together. On a node card you can switch **project** (a new session is created
|
|
33
|
+
for that project) and switch **session** at any time; **Delete** stops the node.
|
|
34
34
|
|
|
35
35
|
Config lives in `~/.anet/dsh/` (`nodes.json`, `account.json`, both 0600).
|
|
36
36
|
|
package/README.zh.md
CHANGED
|
@@ -28,7 +28,7 @@ dsh plugin --profile web add @sleep2agi/dsh-anet
|
|
|
28
28
|
3. 创建节点:节点名称(alias)、项目目录、Session(新建或选已有)。token 由当前登录账号
|
|
29
29
|
自动签发,节点立即上线。
|
|
30
30
|
4. 其他人在 hub/看板给该 alias 派任务;任务在节点的 DSH session 里执行,结果自动回 hub。
|
|
31
|
-
5.
|
|
31
|
+
5. 可同时运行多个节点;节点卡片里可随时切换 **项目**(会为该节点新建 session)和 **Session**,**删除** 即下线。
|
|
32
32
|
|
|
33
33
|
配置在 `~/.anet/dsh/`(`nodes.json`、`account.json`,均 0600)。
|
|
34
34
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleep2agi/dsh-anet",
|
|
3
|
-
"version": "0.1.0-preview.
|
|
3
|
+
"version": "0.1.0-preview.28",
|
|
4
4
|
"description": "DSH (DeepSeek Harness) plugin: expose one or more DSH sessions as Agent Network (anet.sh / CommHub) nodes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/plugin.mjs",
|
package/src/client.js
CHANGED
|
@@ -26,7 +26,7 @@ window.__ModuleLoader__.load({
|
|
|
26
26
|
loading: "正在加载…", offline: "本地服务不可用(127.0.0.1:9460)", failed: "操作失败",
|
|
27
27
|
note: "配置保存在 ~/.anet/dsh/nodes.json(0600)",
|
|
28
28
|
running: "已连接", starting: "连接中", stopped: "未连接", error: "异常",
|
|
29
|
-
network: "Network", projectLabel: "项目", noNetwork: "默认网络",
|
|
29
|
+
network: "Network", projectLabel: "项目", noNetwork: "默认网络", unnamedSession: "未命名会话",
|
|
30
30
|
};
|
|
31
31
|
const en = {
|
|
32
32
|
title: "ANet", subtitle: "Turn a project/session into an Agent Network node",
|
|
@@ -43,7 +43,7 @@ window.__ModuleLoader__.load({
|
|
|
43
43
|
loading: "Loading…", offline: "Local service unavailable (127.0.0.1:9460)", failed: "Failed",
|
|
44
44
|
note: "Stored in ~/.anet/dsh/nodes.json (0600)",
|
|
45
45
|
running: "Connected", starting: "Connecting", stopped: "Disconnected", error: "Error",
|
|
46
|
-
network: "Network", projectLabel: "Project", noNetwork: "default network",
|
|
46
|
+
network: "Network", projectLabel: "Project", noNetwork: "default network", unnamedSession: "Untitled session",
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
const T = {
|
|
@@ -72,6 +72,22 @@ window.__ModuleLoader__.load({
|
|
|
72
72
|
const sectionHint = { margin: "4px 0 12px", fontSize: 12, color: T.muted, lineHeight: 1.5 };
|
|
73
73
|
const grid2 = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 };
|
|
74
74
|
|
|
75
|
+
function baseName(path) {
|
|
76
|
+
if (!path) return "";
|
|
77
|
+
const parts = String(path).split("/").filter(Boolean);
|
|
78
|
+
return parts.length ? parts[parts.length - 1] : path;
|
|
79
|
+
}
|
|
80
|
+
function sessionWhen(ms) {
|
|
81
|
+
if (!ms) return "";
|
|
82
|
+
const date = new Date(ms);
|
|
83
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
84
|
+
return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
85
|
+
}
|
|
86
|
+
function sessionLabel(t, session) {
|
|
87
|
+
const title = session.title || t("unnamedSession");
|
|
88
|
+
return `${title} · ${sessionWhen(session.createdAt)} · ${baseName(session.cwd)}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
75
91
|
function Field(props) {
|
|
76
92
|
return h("div", { style: props.style ?? null },
|
|
77
93
|
h("label", { style: labelStyle, htmlFor: props.id }, props.label),
|
|
@@ -130,8 +146,8 @@ window.__ModuleLoader__.load({
|
|
|
130
146
|
style: { ...inputStyle, height: 30, padding: "0 8px", fontSize: 12, flex: 1, minWidth: 0 },
|
|
131
147
|
},
|
|
132
148
|
(sessions ?? []).some((session) => session.id === node.sessionId) ? null : h("option", { value: node.sessionId }, node.sessionId),
|
|
133
|
-
(sessions ?? []).map((session) => h("option", { key: session.id, value: session.id },
|
|
134
|
-
|
|
149
|
+
(sessions ?? []).map((session) => h("option", { key: session.id, value: session.id, title: session.id },
|
|
150
|
+
sessionLabel(t, session))),
|
|
135
151
|
),
|
|
136
152
|
),
|
|
137
153
|
node.lastError ? h("div", { style: { fontSize: 11.5, color: T.err, marginTop: 6 } }, node.lastError) : null,
|
|
@@ -404,7 +420,7 @@ window.__ModuleLoader__.load({
|
|
|
404
420
|
onChange: (event) => setSessionChoice(event.target.value),
|
|
405
421
|
},
|
|
406
422
|
h("option", { value: "__new__" }, t("newSession")),
|
|
407
|
-
sessions.map((item) => h("option", { key: item.id, value: item.id
|
|
423
|
+
sessions.map((item) => h("option", { key: item.id, value: item.id, title: item.id }, sessionLabel(t, item))),
|
|
408
424
|
),
|
|
409
425
|
h("p", { style: hintStyle }, t("sessionHint")),
|
|
410
426
|
),
|
package/src/plugin.mjs
CHANGED
|
@@ -21,7 +21,7 @@ export { summarizeTurn } from "./turn.mjs";
|
|
|
21
21
|
export const name = "anet";
|
|
22
22
|
export const inject = ["agents", "agentDefaultModel", "sessions", "tools"];
|
|
23
23
|
|
|
24
|
-
const VERSION = "dsh-anet@0.1.0-preview.
|
|
24
|
+
const VERSION = "dsh-anet@0.1.0-preview.28";
|
|
25
25
|
|
|
26
26
|
function agentSetup(ctx) {
|
|
27
27
|
const selection = ctx.agentDefaultModel.currentSelection();
|
|
@@ -196,6 +196,22 @@ export function apply(ctx, config) {
|
|
|
196
196
|
return { projects, defaultProject: projects[0]?.path ?? process.cwd() };
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
async function sessionTitle(persistence, id) {
|
|
200
|
+
try {
|
|
201
|
+
const { events } = await persistence.inspect(id);
|
|
202
|
+
const titled = events.find((event) => event.type === "session/title");
|
|
203
|
+
const title = titled?.data?.title ?? titled?.data?.text;
|
|
204
|
+
if (typeof title === "string" && title.trim()) return title.trim();
|
|
205
|
+
const first = events.find((event) => event.type === "user/message");
|
|
206
|
+
const content = first?.data?.message?.content ?? first?.data?.content;
|
|
207
|
+
if (Array.isArray(content)) {
|
|
208
|
+
const text = content.filter((block) => block?.type === "text").map((block) => block.text).join(" ").trim();
|
|
209
|
+
if (text) return text.slice(0, 48);
|
|
210
|
+
}
|
|
211
|
+
} catch { /* unreadable session */ }
|
|
212
|
+
return "";
|
|
213
|
+
}
|
|
214
|
+
|
|
199
215
|
async function listSessions() {
|
|
200
216
|
const persistence = ctx.get("sessionPersistence");
|
|
201
217
|
const sessions = [];
|
|
@@ -207,7 +223,9 @@ export function apply(ctx, config) {
|
|
|
207
223
|
} catch { /* no persisted sessions */ }
|
|
208
224
|
}
|
|
209
225
|
sessions.sort((a, b) => (b.createdAt ?? 0) - (a.createdAt ?? 0));
|
|
210
|
-
|
|
226
|
+
const recent = sessions.slice(0, 40);
|
|
227
|
+
for (const session of recent) session.title = await sessionTitle(persistence, session.id);
|
|
228
|
+
return { sessions: [...recent, ...sessions.slice(40, 200)] };
|
|
211
229
|
}
|
|
212
230
|
|
|
213
231
|
async function sessionById(id) {
|