lyu-extension-workflow 0.0.0-stage → 0.1.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/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +482 -0
- package/dist/index.js.map +1 -0
- package/frontend/dist/index.html +196 -0
- package/package.json +31 -4
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Extension for lyu-code
|
|
3
|
+
*
|
|
4
|
+
* /workflow — 打开本地前端页面,可视化编排多 agent 工作流
|
|
5
|
+
*
|
|
6
|
+
* 架构:
|
|
7
|
+
* - 命令启动本地 HTTP 服务(默认 18789)+ WebSocket
|
|
8
|
+
* - serve frontend/dist/ 下的静态文件(用户自行提供)
|
|
9
|
+
* - WebSocket 通道让前端和 Pi 通信
|
|
10
|
+
* - 前端发指令(addNode, connect, run, stop, ...)
|
|
11
|
+
* - 扩展执行操作,回传状态和结果
|
|
12
|
+
*
|
|
13
|
+
* 用法:
|
|
14
|
+
* /workflow — 打开编辑器
|
|
15
|
+
* /workflow stop — 关闭服务
|
|
16
|
+
*/
|
|
17
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
18
|
+
export default function (pi: ExtensionAPI): void;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,YAAY,EAGb,MAAM,iCAAiC,CAAC;AAkbzC,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAoDxC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Extension for lyu-code
|
|
3
|
+
*
|
|
4
|
+
* /workflow — 打开本地前端页面,可视化编排多 agent 工作流
|
|
5
|
+
*
|
|
6
|
+
* 架构:
|
|
7
|
+
* - 命令启动本地 HTTP 服务(默认 18789)+ WebSocket
|
|
8
|
+
* - serve frontend/dist/ 下的静态文件(用户自行提供)
|
|
9
|
+
* - WebSocket 通道让前端和 Pi 通信
|
|
10
|
+
* - 前端发指令(addNode, connect, run, stop, ...)
|
|
11
|
+
* - 扩展执行操作,回传状态和结果
|
|
12
|
+
*
|
|
13
|
+
* 用法:
|
|
14
|
+
* /workflow — 打开编辑器
|
|
15
|
+
* /workflow stop — 关闭服务
|
|
16
|
+
*/
|
|
17
|
+
import * as http from "node:http";
|
|
18
|
+
import * as fs from "node:fs";
|
|
19
|
+
import * as path from "node:path";
|
|
20
|
+
import { URL } from "node:url";
|
|
21
|
+
const DEFAULT_PORT = 18789;
|
|
22
|
+
// ─── 简易 WebSocket (RFC 6455, 最小实现) ──────────────────────────
|
|
23
|
+
function wsAcceptKey(key) {
|
|
24
|
+
const crypto = require("node:crypto");
|
|
25
|
+
return crypto.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-5AB5DC828B12").digest("base64");
|
|
26
|
+
}
|
|
27
|
+
// ─── 全局状态 ──────────────────────────────────────────────────────
|
|
28
|
+
let server = null;
|
|
29
|
+
let port = DEFAULT_PORT;
|
|
30
|
+
let piRef = null;
|
|
31
|
+
const workflows = new Map();
|
|
32
|
+
const runStates = new Map();
|
|
33
|
+
const wsClients = [];
|
|
34
|
+
// ─── 广播 ──────────────────────────────────────────────────────────
|
|
35
|
+
function broadcast(type, data) {
|
|
36
|
+
const msg = JSON.stringify({ type, data });
|
|
37
|
+
for (const c of wsClients) {
|
|
38
|
+
try {
|
|
39
|
+
c.send(msg);
|
|
40
|
+
}
|
|
41
|
+
catch { /* ignore */ }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ─── 前端静态文件 ──────────────────────────────────────────────────
|
|
45
|
+
const MIME = {
|
|
46
|
+
".html": "text/html", ".js": "application/javascript", ".mjs": "application/javascript",
|
|
47
|
+
".css": "text/css", ".json": "application/json", ".png": "image/png",
|
|
48
|
+
".jpg": "image/jpeg", ".svg": "image/svg+xml", ".ico": "image/x-icon",
|
|
49
|
+
".woff": "font/woff", ".woff2": "font/woff2",
|
|
50
|
+
};
|
|
51
|
+
function getFrontendDir() {
|
|
52
|
+
const thisDir = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, "$1"));
|
|
53
|
+
return path.join(thisDir, "..", "frontend", "dist");
|
|
54
|
+
}
|
|
55
|
+
function serveStatic(req, res) {
|
|
56
|
+
const frontendDir = getFrontendDir();
|
|
57
|
+
let urlPath = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
58
|
+
// API 路由
|
|
59
|
+
if (urlPath.startsWith("/api/")) {
|
|
60
|
+
handleApi(req, res, urlPath);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// 静态文件
|
|
64
|
+
if (urlPath === "/")
|
|
65
|
+
urlPath = "/index.html";
|
|
66
|
+
const filePath = path.join(frontendDir, urlPath);
|
|
67
|
+
try {
|
|
68
|
+
if (!filePath.startsWith(frontendDir)) {
|
|
69
|
+
res.writeHead(403);
|
|
70
|
+
res.end();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const stat = fs.statSync(filePath);
|
|
74
|
+
if (!stat.isFile())
|
|
75
|
+
throw new Error("not file");
|
|
76
|
+
const ext = path.extname(filePath);
|
|
77
|
+
res.writeHead(200, { "Content-Type": (MIME[ext] || "application/octet-stream") + "; charset=utf-8" });
|
|
78
|
+
res.end(fs.readFileSync(filePath));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// SPA fallback
|
|
82
|
+
try {
|
|
83
|
+
const fallback = path.join(frontendDir, "index.html");
|
|
84
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
85
|
+
res.end(fs.readFileSync(fallback));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
res.writeHead(404);
|
|
89
|
+
res.end("Not found — put frontend files in frontend/dist/");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function handleApi(_req, res, urlPath) {
|
|
94
|
+
const ok = (d) => { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify(d)); };
|
|
95
|
+
if (urlPath === "/api/workflows") {
|
|
96
|
+
ok([...workflows.values()].map(w => ({ id: w.id, name: w.name, nodeCount: w.nodes.length, globalMaxLoops: w.globalMaxLoops })));
|
|
97
|
+
}
|
|
98
|
+
else if (urlPath === "/api/status") {
|
|
99
|
+
ok({ ok: true, workflows: workflows.size, clients: wsClients.length });
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
ok({ error: "not found" });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// ─── WebSocket 消息处理 ────────────────────────────────────────────
|
|
106
|
+
function handleWsMessage(raw) {
|
|
107
|
+
let msg;
|
|
108
|
+
try {
|
|
109
|
+
msg = JSON.parse(raw);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
switch (msg.type) {
|
|
115
|
+
case "workflow:create": {
|
|
116
|
+
const wf = {
|
|
117
|
+
id: msg.data?.id ?? `wf-${Date.now()}`,
|
|
118
|
+
name: msg.data?.name ?? "Untitled Workflow",
|
|
119
|
+
nodes: msg.data?.nodes ?? [],
|
|
120
|
+
edges: msg.data?.edges ?? [],
|
|
121
|
+
globalMaxLoops: msg.data?.globalMaxLoops ?? 10,
|
|
122
|
+
createdAt: Date.now(),
|
|
123
|
+
updatedAt: Date.now(),
|
|
124
|
+
};
|
|
125
|
+
workflows.set(wf.id, wf);
|
|
126
|
+
runStates.set(wf.id, { status: "idle", iteration: 0, results: {} });
|
|
127
|
+
broadcast("workflow:created", wf);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case "workflow:update": {
|
|
131
|
+
const wf = workflows.get(msg.data?.id);
|
|
132
|
+
if (wf) {
|
|
133
|
+
Object.assign(wf, msg.data, { updatedAt: Date.now() });
|
|
134
|
+
broadcast("workflow:updated", wf);
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "workflow:delete": {
|
|
139
|
+
workflows.delete(msg.data?.id);
|
|
140
|
+
runStates.delete(msg.data?.id);
|
|
141
|
+
broadcast("workflow:deleted", { id: msg.data?.id });
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "node:add": {
|
|
145
|
+
const wf = workflows.get(msg.data?.workflowId);
|
|
146
|
+
if (wf) {
|
|
147
|
+
wf.nodes.push(msg.data.node);
|
|
148
|
+
wf.updatedAt = Date.now();
|
|
149
|
+
broadcast("workflow:updated", wf);
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case "node:update": {
|
|
154
|
+
const wf = workflows.get(msg.data?.workflowId);
|
|
155
|
+
if (wf) {
|
|
156
|
+
const i = wf.nodes.findIndex(n => n.id === msg.data.node.id);
|
|
157
|
+
if (i >= 0) {
|
|
158
|
+
wf.nodes[i] = { ...wf.nodes[i], ...msg.data.node };
|
|
159
|
+
wf.updatedAt = Date.now();
|
|
160
|
+
broadcast("workflow:updated", wf);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
case "node:remove": {
|
|
166
|
+
const wf = workflows.get(msg.data?.workflowId);
|
|
167
|
+
if (wf) {
|
|
168
|
+
wf.nodes = wf.nodes.filter(n => n.id !== msg.data.nodeId);
|
|
169
|
+
wf.edges = wf.edges.filter(e => e.source !== msg.data.nodeId && e.target !== msg.data.nodeId);
|
|
170
|
+
wf.updatedAt = Date.now();
|
|
171
|
+
broadcast("workflow:updated", wf);
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case "edge:add": {
|
|
176
|
+
const wf = workflows.get(msg.data?.workflowId);
|
|
177
|
+
if (wf) {
|
|
178
|
+
wf.edges.push(msg.data.edge);
|
|
179
|
+
wf.updatedAt = Date.now();
|
|
180
|
+
broadcast("workflow:updated", wf);
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
case "edge:remove": {
|
|
185
|
+
const wf = workflows.get(msg.data?.workflowId);
|
|
186
|
+
if (wf) {
|
|
187
|
+
wf.edges = wf.edges.filter(e => e.id !== msg.data.edgeId);
|
|
188
|
+
wf.updatedAt = Date.now();
|
|
189
|
+
broadcast("workflow:updated", wf);
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case "workflow:run": {
|
|
194
|
+
const wfId = msg.data?.workflowId;
|
|
195
|
+
const wf = workflows.get(wfId);
|
|
196
|
+
const state = runStates.get(wfId);
|
|
197
|
+
if (!wf || !state || state.status === "running")
|
|
198
|
+
break;
|
|
199
|
+
state.status = "running";
|
|
200
|
+
state.iteration = 0;
|
|
201
|
+
state.results = {};
|
|
202
|
+
for (const n of wf.nodes)
|
|
203
|
+
state.results[n.id] = { status: "pending" };
|
|
204
|
+
broadcast("run:state", { workflowId: wfId, state });
|
|
205
|
+
runWorkflow(wf, state).catch(err => {
|
|
206
|
+
state.status = "error";
|
|
207
|
+
broadcast("run:state", { workflowId: wfId, state, error: String(err) });
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
case "workflow:stop": {
|
|
212
|
+
const state = runStates.get(msg.data?.workflowId);
|
|
213
|
+
if (state) {
|
|
214
|
+
state.status = "idle";
|
|
215
|
+
broadcast("run:state", { workflowId: msg.data?.workflowId, state });
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case "agent:send": {
|
|
220
|
+
if (piRef) {
|
|
221
|
+
piRef.sendUserMessage(msg.data?.message ?? "", { deliverAs: "followUp" });
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// ─── Workflow 执行引擎 ─────────────────────────────────────────────
|
|
228
|
+
async function runWorkflow(wf, state) {
|
|
229
|
+
const sorted = topoSort(wf.nodes, wf.edges);
|
|
230
|
+
for (let iter = 0; iter < wf.globalMaxLoops; iter++) {
|
|
231
|
+
state.iteration = iter + 1;
|
|
232
|
+
broadcast("run:state", { workflowId: wf.id, state });
|
|
233
|
+
for (const node of sorted) {
|
|
234
|
+
const ns = state.results[node.id];
|
|
235
|
+
if (!ns)
|
|
236
|
+
continue;
|
|
237
|
+
ns.status = "running";
|
|
238
|
+
state.currentStep = node.id;
|
|
239
|
+
broadcast("run:state", { workflowId: wf.id, state });
|
|
240
|
+
// 收集上游输出
|
|
241
|
+
const upstream = wf.edges
|
|
242
|
+
.filter(e => e.target === node.id)
|
|
243
|
+
.map(e => state.results[e.source]?.output ?? "")
|
|
244
|
+
.filter(Boolean)
|
|
245
|
+
.join("\n\n");
|
|
246
|
+
// 通过 Pi 驱动 agent
|
|
247
|
+
if (piRef) {
|
|
248
|
+
const prompt = upstream
|
|
249
|
+
? `[上游输入]\n${upstream}\n\n[请处理以上输入并输出结果]`
|
|
250
|
+
: node.config.systemPrompt ?? "请开始工作";
|
|
251
|
+
piRef.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
252
|
+
}
|
|
253
|
+
// 等待一小段时间让 Pi 处理(实际结果由 agent_end 事件回填)
|
|
254
|
+
await new Promise(r => setTimeout(r, 500));
|
|
255
|
+
ns.status = "done";
|
|
256
|
+
ns.iterations = (ns.iterations ?? 0) + 1;
|
|
257
|
+
broadcast("run:state", { workflowId: wf.id, state });
|
|
258
|
+
}
|
|
259
|
+
// 无回边则不循环
|
|
260
|
+
const hasBack = wf.edges.some(e => {
|
|
261
|
+
const si = sorted.findIndex(n => n.id === e.source);
|
|
262
|
+
const ti = sorted.findIndex(n => n.id === e.target);
|
|
263
|
+
return ti <= si;
|
|
264
|
+
});
|
|
265
|
+
if (!hasBack)
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
state.status = "done";
|
|
269
|
+
state.currentStep = undefined;
|
|
270
|
+
broadcast("run:state", { workflowId: wf.id, state });
|
|
271
|
+
}
|
|
272
|
+
function topoSort(nodes, edges) {
|
|
273
|
+
const nodeMap = new Map(nodes.map(n => [n.id, n]));
|
|
274
|
+
const deg = new Map(nodes.map(n => [n.id, 0]));
|
|
275
|
+
const adj = new Map(nodes.map(n => [n.id, []]));
|
|
276
|
+
for (const e of edges) {
|
|
277
|
+
adj.get(e.source)?.push(e.target);
|
|
278
|
+
deg.set(e.target, (deg.get(e.target) ?? 0) + 1);
|
|
279
|
+
}
|
|
280
|
+
const q = [];
|
|
281
|
+
for (const [id, d] of deg)
|
|
282
|
+
if (d === 0)
|
|
283
|
+
q.push(id);
|
|
284
|
+
const result = [];
|
|
285
|
+
while (q.length) {
|
|
286
|
+
const id = q.shift();
|
|
287
|
+
const n = nodeMap.get(id);
|
|
288
|
+
if (n)
|
|
289
|
+
result.push(n);
|
|
290
|
+
for (const next of adj.get(id) ?? []) {
|
|
291
|
+
const d = (deg.get(next) ?? 1) - 1;
|
|
292
|
+
deg.set(next, d);
|
|
293
|
+
if (d === 0)
|
|
294
|
+
q.push(next);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
for (const n of nodes)
|
|
298
|
+
if (!result.find(r => r.id === n.id))
|
|
299
|
+
result.push(n);
|
|
300
|
+
return result;
|
|
301
|
+
}
|
|
302
|
+
// ─── 启停 ──────────────────────────────────────────────────────────
|
|
303
|
+
function startServer() {
|
|
304
|
+
return new Promise((resolve, reject) => {
|
|
305
|
+
server = http.createServer(serveStatic);
|
|
306
|
+
// WebSocket upgrade (简易实现)
|
|
307
|
+
server.on("upgrade", (req, socket, head) => {
|
|
308
|
+
if (!(req.url ?? "/").startsWith("/ws")) {
|
|
309
|
+
socket.destroy();
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const key = req.headers["sec-websocket-key"];
|
|
313
|
+
if (!key) {
|
|
314
|
+
socket.destroy();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
socket.write("HTTP/1.1 101 Switching Protocols\r\n" +
|
|
318
|
+
"Upgrade: websocket\r\n" +
|
|
319
|
+
"Connection: Upgrade\r\n" +
|
|
320
|
+
`Sec-WebSocket-Accept: ${wsAcceptKey(key)}\r\n\r\n`);
|
|
321
|
+
const client = {
|
|
322
|
+
socket,
|
|
323
|
+
send(data) {
|
|
324
|
+
// 简易:发 text frame (opcode 0x1), 无掩码, 不分片
|
|
325
|
+
const buf = Buffer.from(data, "utf-8");
|
|
326
|
+
const len = buf.length;
|
|
327
|
+
const frames = [];
|
|
328
|
+
if (len < 126) {
|
|
329
|
+
frames.push(Buffer.from([0x81, len]));
|
|
330
|
+
}
|
|
331
|
+
else if (len < 65536) {
|
|
332
|
+
const h = Buffer.alloc(4);
|
|
333
|
+
h[0] = 0x81;
|
|
334
|
+
h[1] = 126;
|
|
335
|
+
h.writeUInt16BE(len, 2);
|
|
336
|
+
frames.push(h);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
const h = Buffer.alloc(10);
|
|
340
|
+
h[0] = 0x81;
|
|
341
|
+
h[1] = 127;
|
|
342
|
+
h.writeBigUInt64BE(BigInt(len), 2);
|
|
343
|
+
frames.push(h);
|
|
344
|
+
}
|
|
345
|
+
frames.push(buf);
|
|
346
|
+
socket.write(Buffer.concat(frames));
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
wsClients.push(client);
|
|
350
|
+
// 接收帧(简易:只处理小 text 帧)
|
|
351
|
+
let buf = Buffer.alloc(0);
|
|
352
|
+
socket.on("data", (chunk) => {
|
|
353
|
+
buf = Buffer.concat([buf, chunk]);
|
|
354
|
+
// 解析 text frame
|
|
355
|
+
if (buf.length < 2)
|
|
356
|
+
return;
|
|
357
|
+
const opcode = buf[0] & 0x0f;
|
|
358
|
+
const masked = !!(buf[1] & 0x80);
|
|
359
|
+
let payloadLen = buf[1] & 0x7f;
|
|
360
|
+
let offset = 2;
|
|
361
|
+
if (payloadLen === 126) {
|
|
362
|
+
if (buf.length < 4)
|
|
363
|
+
return;
|
|
364
|
+
payloadLen = buf.readUInt16BE(2);
|
|
365
|
+
offset = 4;
|
|
366
|
+
}
|
|
367
|
+
else if (payloadLen === 127) {
|
|
368
|
+
if (buf.length < 10)
|
|
369
|
+
return;
|
|
370
|
+
payloadLen = Number(buf.readBigUInt64BE(2));
|
|
371
|
+
offset = 10;
|
|
372
|
+
}
|
|
373
|
+
if (masked)
|
|
374
|
+
offset += 4;
|
|
375
|
+
if (buf.length < offset + payloadLen)
|
|
376
|
+
return;
|
|
377
|
+
let payload = buf.subarray(offset, offset + payloadLen);
|
|
378
|
+
if (masked) {
|
|
379
|
+
const mask = buf.subarray(offset - 4, offset);
|
|
380
|
+
payload = Buffer.from(payload.map((b, i) => b ^ mask[i % 4]));
|
|
381
|
+
}
|
|
382
|
+
buf = buf.subarray(offset + payloadLen);
|
|
383
|
+
if (opcode === 0x1) { // text
|
|
384
|
+
handleWsMessage(payload.toString("utf-8"));
|
|
385
|
+
}
|
|
386
|
+
else if (opcode === 0x8) { // close
|
|
387
|
+
const idx = wsClients.indexOf(client);
|
|
388
|
+
if (idx >= 0)
|
|
389
|
+
wsClients.splice(idx, 1);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
socket.on("close", () => {
|
|
393
|
+
const idx = wsClients.indexOf(client);
|
|
394
|
+
if (idx >= 0)
|
|
395
|
+
wsClients.splice(idx, 1);
|
|
396
|
+
});
|
|
397
|
+
// 发送初始状态
|
|
398
|
+
client.send(JSON.stringify({
|
|
399
|
+
type: "connected",
|
|
400
|
+
data: { workflows: [...workflows.values()], port },
|
|
401
|
+
}));
|
|
402
|
+
});
|
|
403
|
+
server.on("error", (err) => {
|
|
404
|
+
if (err.code === "EADDRINUSE") {
|
|
405
|
+
port++;
|
|
406
|
+
server.listen(port, "127.0.0.1");
|
|
407
|
+
}
|
|
408
|
+
else
|
|
409
|
+
reject(err);
|
|
410
|
+
});
|
|
411
|
+
server.on("listening", () => resolve(port));
|
|
412
|
+
server.listen(port, "127.0.0.1");
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
function stopServer() {
|
|
416
|
+
for (const c of wsClients)
|
|
417
|
+
try {
|
|
418
|
+
c.socket.destroy();
|
|
419
|
+
}
|
|
420
|
+
catch { /* ok */ }
|
|
421
|
+
wsClients.length = 0;
|
|
422
|
+
server?.close();
|
|
423
|
+
server = null;
|
|
424
|
+
}
|
|
425
|
+
// ─── 扩展入口 ──────────────────────────────────────────────────────
|
|
426
|
+
export default function (pi) {
|
|
427
|
+
piRef = pi;
|
|
428
|
+
pi.registerCommand("workflow", {
|
|
429
|
+
description: "Open workflow editor — visually compose multi-agent pipelines",
|
|
430
|
+
handler: async (args, _ctx) => {
|
|
431
|
+
if (args.trim() === "stop") {
|
|
432
|
+
stopServer();
|
|
433
|
+
pi.sendMessage({ customType: "workflow", content: "Workflow server stopped", display: true });
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (!server) {
|
|
437
|
+
const actualPort = await startServer();
|
|
438
|
+
const url = `http://127.0.0.1:${actualPort}`;
|
|
439
|
+
// 打开浏览器
|
|
440
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
441
|
+
try {
|
|
442
|
+
require("node:child_process").execSync(`${cmd} "${url}"`, { stdio: "ignore" });
|
|
443
|
+
}
|
|
444
|
+
catch { /* ok */ }
|
|
445
|
+
pi.sendMessage({
|
|
446
|
+
customType: "workflow",
|
|
447
|
+
content: `Workflow editor: ${url}`,
|
|
448
|
+
display: true,
|
|
449
|
+
details: { url, port: actualPort },
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
const url = `http://127.0.0.1:${port}`;
|
|
454
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
455
|
+
try {
|
|
456
|
+
require("node:child_process").execSync(`${cmd} "${url}"`, { stdio: "ignore" });
|
|
457
|
+
}
|
|
458
|
+
catch { /* ok */ }
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
});
|
|
462
|
+
// agent_end 事件回填节点结果
|
|
463
|
+
pi.on("agent_end", (event) => {
|
|
464
|
+
for (const [wfId, state] of runStates) {
|
|
465
|
+
if (state.status !== "running" || !state.currentStep)
|
|
466
|
+
continue;
|
|
467
|
+
const lastMsg = event.messages[event.messages.length - 1];
|
|
468
|
+
if (lastMsg?.role === "assistant") {
|
|
469
|
+
const content = lastMsg.content;
|
|
470
|
+
const text = Array.isArray(content)
|
|
471
|
+
? content.filter((b) => b.type === "text").map((b) => b.text).join("\n")
|
|
472
|
+
: typeof content === "string" ? content : "";
|
|
473
|
+
const ns = state.results[state.currentStep];
|
|
474
|
+
if (ns)
|
|
475
|
+
ns.output = text;
|
|
476
|
+
broadcast("run:nodeResult", { workflowId: wfId, nodeId: state.currentStep, output: text });
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
console.error("[workflow] Extension loaded — /workflow to open editor");
|
|
481
|
+
}
|
|
482
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Lyu-Code Workflow Editor</title>
|
|
7
|
+
<style>
|
|
8
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0a0a0a; color: #e0e0e0; }
|
|
10
|
+
#app { display: flex; flex-direction: column; height: 100vh; }
|
|
11
|
+
|
|
12
|
+
.header { padding: 12px 20px; background: #141414; border-bottom: 1px solid #262626; display: flex; align-items: center; gap: 12px; }
|
|
13
|
+
.header h1 { font-size: 16px; font-weight: 600; }
|
|
14
|
+
.header .status { margin-left: auto; font-size: 12px; color: #888; }
|
|
15
|
+
.header .status.connected { color: #4ade80; }
|
|
16
|
+
|
|
17
|
+
.toolbar { padding: 8px 20px; background: #1a1a1a; border-bottom: 1px solid #262626; display: flex; gap: 8px; }
|
|
18
|
+
.toolbar button { padding: 6px 14px; border: 1px solid #333; border-radius: 6px; background: #222; color: #ccc; cursor: pointer; font-size: 13px; }
|
|
19
|
+
.toolbar button:hover { background: #2a2a2a; border-color: #444; }
|
|
20
|
+
.toolbar button.primary { background: #2563eb; border-color: #2563eb; color: #fff; }
|
|
21
|
+
.toolbar button.primary:hover { background: #1d4ed8; }
|
|
22
|
+
.toolbar button.danger { background: #dc2626; border-color: #dc2626; color: #fff; }
|
|
23
|
+
|
|
24
|
+
.canvas-area { flex: 1; display: flex; align-items: center; justify-content: center; position: relative; }
|
|
25
|
+
.placeholder { text-align: center; color: #555; }
|
|
26
|
+
.placeholder h2 { font-size: 20px; margin-bottom: 8px; color: #888; }
|
|
27
|
+
.placeholder p { font-size: 14px; }
|
|
28
|
+
|
|
29
|
+
.panel { position: absolute; right: 16px; top: 16px; bottom: 16px; width: 300px; background: #141414; border: 1px solid #262626; border-radius: 8px; overflow: hidden; display: none; }
|
|
30
|
+
.panel.open { display: flex; flex-direction: column; }
|
|
31
|
+
.panel-header { padding: 12px 16px; border-bottom: 1px solid #262626; font-size: 14px; font-weight: 600; }
|
|
32
|
+
.panel-body { flex: 1; overflow-y: auto; padding: 12px 16px; }
|
|
33
|
+
.panel-body label { display: block; font-size: 12px; color: #888; margin-bottom: 4px; margin-top: 12px; }
|
|
34
|
+
.panel-body input, .panel-body textarea, .panel-body select {
|
|
35
|
+
width: 100%; padding: 6px 8px; background: #222; border: 1px solid #333; border-radius: 4px; color: #e0e0e0; font-size: 13px;
|
|
36
|
+
}
|
|
37
|
+
.panel-body textarea { min-height: 80px; resize: vertical; }
|
|
38
|
+
</style>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div id="app">
|
|
42
|
+
<div class="header">
|
|
43
|
+
<h1>⚡ Lyu-Code Workflow</h1>
|
|
44
|
+
<span class="status" id="status">Connecting…</span>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div class="toolbar">
|
|
48
|
+
<button class="primary" onclick="createWorkflow()">+ New Workflow</button>
|
|
49
|
+
<button onclick="addAgentNode()">Add Agent</button>
|
|
50
|
+
<button class="primary" onclick="runWorkflow()">▶ Run</button>
|
|
51
|
+
<button onclick="stopWorkflow()">■ Stop</button>
|
|
52
|
+
<button class="danger" onclick="clearWorkflow()">✕ Clear</button>
|
|
53
|
+
<span style="margin-left:auto;font-size:12px;color:#666;">
|
|
54
|
+
Max Loops: <input type="number" id="maxLoops" value="10" min="1" max="100" style="width:60px;padding:2px 4px;background:#222;border:1px solid #333;border-radius:3px;color:#e0e0e0;font-size:12px;">
|
|
55
|
+
</span>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div class="canvas-area">
|
|
59
|
+
<div class="placeholder">
|
|
60
|
+
<h2>🎨 Workflow Canvas</h2>
|
|
61
|
+
<p>Replace this placeholder with your React Flow frontend.<br>
|
|
62
|
+
Put built files in <code>frontend/dist/</code></p>
|
|
63
|
+
<p style="margin-top:16px;font-size:12px;color:#444;">
|
|
64
|
+
WebSocket: <code id="wsUrl">ws://127.0.0.1:18789/ws</code><br>
|
|
65
|
+
API: <code id="apiUrl">http://127.0.0.1:18789/api</code>
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div class="panel" id="nodePanel">
|
|
71
|
+
<div class="panel-header">Node Config</div>
|
|
72
|
+
<div class="panel-body">
|
|
73
|
+
<label>Label</label>
|
|
74
|
+
<input type="text" id="nodeLabel" placeholder="Agent name">
|
|
75
|
+
|
|
76
|
+
<label>System Prompt</label>
|
|
77
|
+
<textarea id="nodePrompt" placeholder="You are a helpful coding agent..."></textarea>
|
|
78
|
+
|
|
79
|
+
<label>Model</label>
|
|
80
|
+
<select id="nodeModel">
|
|
81
|
+
<option value="">default</option>
|
|
82
|
+
<option value="gpt-6-sol">GPT-6 Sol</option>
|
|
83
|
+
<option value="gpt-5.6-luna">GPT-5.6 Luna</option>
|
|
84
|
+
<option value="deepseek-v4-pro">DeepSeek V4 Pro</option>
|
|
85
|
+
</select>
|
|
86
|
+
|
|
87
|
+
<label>Max Loops (this node)</label>
|
|
88
|
+
<input type="number" id="nodeMaxLoops" value="1" min="1" max="100">
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<script>
|
|
94
|
+
// ─── WebSocket 连接 ─────────────────────────────────
|
|
95
|
+
let ws = null;
|
|
96
|
+
let currentWorkflow = null;
|
|
97
|
+
let msgId = 0;
|
|
98
|
+
|
|
99
|
+
function connectWS() {
|
|
100
|
+
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
101
|
+
ws = new WebSocket(`${proto}//${location.host}/ws`);
|
|
102
|
+
|
|
103
|
+
ws.onopen = () => {
|
|
104
|
+
document.getElementById('status').textContent = 'Connected';
|
|
105
|
+
document.getElementById('status').classList.add('connected');
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
ws.onclose = () => {
|
|
109
|
+
document.getElementById('status').textContent = 'Disconnected';
|
|
110
|
+
document.getElementById('status').classList.remove('connected');
|
|
111
|
+
setTimeout(connectWS, 2000);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
ws.onmessage = (e) => {
|
|
115
|
+
const msg = JSON.parse(e.data);
|
|
116
|
+
handleMessage(msg);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function send(type, data = {}) {
|
|
121
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
122
|
+
ws.send(JSON.stringify({ type, data, id: String(++msgId) }));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function handleMessage(msg) {
|
|
126
|
+
switch (msg.type) {
|
|
127
|
+
case 'connected':
|
|
128
|
+
console.log('Connected to workflow server', msg.data);
|
|
129
|
+
break;
|
|
130
|
+
case 'workflow:created':
|
|
131
|
+
currentWorkflow = msg.data;
|
|
132
|
+
console.log('Workflow created:', msg.data.id);
|
|
133
|
+
break;
|
|
134
|
+
case 'workflow:updated':
|
|
135
|
+
currentWorkflow = msg.data;
|
|
136
|
+
break;
|
|
137
|
+
case 'run:state':
|
|
138
|
+
console.log('Run state:', msg.data);
|
|
139
|
+
break;
|
|
140
|
+
case 'run:nodeResult':
|
|
141
|
+
console.log('Node result:', msg.data);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ─── UI 操作 ─────────────────────────────────────────
|
|
147
|
+
function createWorkflow() {
|
|
148
|
+
send('workflow:create', {
|
|
149
|
+
name: 'New Workflow',
|
|
150
|
+
globalMaxLoops: parseInt(document.getElementById('maxLoops').value) || 10,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function addAgentNode() {
|
|
155
|
+
if (!currentWorkflow) { createWorkflow(); setTimeout(addAgentNode, 100); return; }
|
|
156
|
+
const id = 'agent-' + Date.now();
|
|
157
|
+
send('node:add', {
|
|
158
|
+
workflowId: currentWorkflow.id,
|
|
159
|
+
node: {
|
|
160
|
+
id,
|
|
161
|
+
type: 'agent',
|
|
162
|
+
label: 'Agent ' + (currentWorkflow.nodes.length + 1),
|
|
163
|
+
config: { systemPrompt: '', maxLoops: 1 },
|
|
164
|
+
position: { x: 100 + currentWorkflow.nodes.length * 200, y: 200 },
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function runWorkflow() {
|
|
170
|
+
if (!currentWorkflow) return;
|
|
171
|
+
// 先更新 globalMaxLoops
|
|
172
|
+
send('workflow:update', {
|
|
173
|
+
id: currentWorkflow.id,
|
|
174
|
+
globalMaxLoops: parseInt(document.getElementById('maxLoops').value) || 10,
|
|
175
|
+
});
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
send('workflow:run', { workflowId: currentWorkflow.id });
|
|
178
|
+
}, 50);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function stopWorkflow() {
|
|
182
|
+
if (!currentWorkflow) return;
|
|
183
|
+
send('workflow:stop', { workflowId: currentWorkflow.id });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function clearWorkflow() {
|
|
187
|
+
if (!currentWorkflow) return;
|
|
188
|
+
send('workflow:delete', { id: currentWorkflow.id });
|
|
189
|
+
currentWorkflow = null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// ─── 启动 ───────────────────────────────────────────
|
|
193
|
+
connectWS();
|
|
194
|
+
</script>
|
|
195
|
+
</body>
|
|
196
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lyu-extension-workflow",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Workflow extension for lyu-code — visually compose multi-agent pipelines",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc -p tsconfig.json"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"frontend/dist"
|
|
13
|
+
],
|
|
14
|
+
"pi": {
|
|
15
|
+
"extensions": [
|
|
16
|
+
"dist/index.js"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@earendil-works/pi-coding-agent": "^0.87.1",
|
|
21
|
+
"@earendil-works/pi-ai": "^0.87.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.8.0",
|
|
25
|
+
"@types/node": "^22.0.0"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/WeeeeeKdY/lyu-code.git",
|
|
31
|
+
"directory": "packages/extensions/workflow"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/README.md
DELETED