@thurstonsand/pi-agent-switchboard 0.1.0 → 0.2.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/index.js +40 -8
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// packages/pi/src/index.ts
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
|
|
1
5
|
// packages/shared/src/index.ts
|
|
2
6
|
import { execFileSync } from "node:child_process";
|
|
3
7
|
import { readFileSync } from "node:fs";
|
|
@@ -103,13 +107,43 @@ var store = globalThis;
|
|
|
103
107
|
function claim() {
|
|
104
108
|
const env = process.env;
|
|
105
109
|
if (env.SWB_MANAGED === "1" && env.SWB_DB && env.SWB_TMUX_SESSION) {
|
|
106
|
-
store[KEY] = {
|
|
110
|
+
store[KEY] = {
|
|
111
|
+
launch: Object.freeze({ db: env.SWB_DB, tmuxSession: env.SWB_TMUX_SESSION, bin: env.SWB_BIN ?? "" }),
|
|
112
|
+
attention: new Set,
|
|
113
|
+
...env.SWB_BIN ? {} : { failure: "started by an swb older than this recorder; upgrade swb" }
|
|
114
|
+
};
|
|
107
115
|
}
|
|
108
116
|
delete env.SWB_MANAGED;
|
|
109
117
|
delete env.SWB_DB;
|
|
110
118
|
delete env.SWB_TMUX_SESSION;
|
|
119
|
+
delete env.SWB_BIN;
|
|
111
120
|
return store[KEY];
|
|
112
121
|
}
|
|
122
|
+
var run = promisify(execFile);
|
|
123
|
+
function host(bin) {
|
|
124
|
+
const swb = async (...args) => {
|
|
125
|
+
try {
|
|
126
|
+
return (await run(bin, args, { timeout: 15000 })).stdout;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const { stderr, message } = error;
|
|
129
|
+
throw new Error(stderr?.trim() || message);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
name: "swb",
|
|
134
|
+
async launch(input) {
|
|
135
|
+
await swb("launch", "--cwd", input.cwd, "--session-id", input.sessionId, "--model", input.model);
|
|
136
|
+
return { success: true };
|
|
137
|
+
},
|
|
138
|
+
async listSessions() {
|
|
139
|
+
const sessions = JSON.parse(await swb("ls", "--json"));
|
|
140
|
+
return sessions.filter((s) => s.open).map((s) => ({ sessionId: s.id, cwd: s.cwd, title: s.title ?? s.id }));
|
|
141
|
+
},
|
|
142
|
+
async wake(sessionId) {
|
|
143
|
+
await swb("wake", sessionId);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
113
147
|
function liveHost(row) {
|
|
114
148
|
if (row && row.boot_id === bootId() && pidAlive(row.pid))
|
|
115
149
|
return row.tmux_session;
|
|
@@ -127,6 +161,8 @@ function src_default(pi) {
|
|
|
127
161
|
return;
|
|
128
162
|
const proc = claimed;
|
|
129
163
|
let ui;
|
|
164
|
+
if (proc.launch.bin)
|
|
165
|
+
pi.events.on("pi-sessions:hosts:v1", (request) => request.register(host(proc.launch.bin)));
|
|
130
166
|
const showFailure = () => ui?.setStatus("swb", ui.theme.fg("error", `swb: not recording: ${proc.failure}`));
|
|
131
167
|
const connect = () => {
|
|
132
168
|
proc.db ??= new Db(proc.launch.db, { create: false });
|
|
@@ -192,9 +228,7 @@ function src_default(pi) {
|
|
|
192
228
|
db.run("UPDATE sessions SET phase = 'idle', cwd = ?, project_root = ?, branch = ?, transcript = ? WHERE session_id = ?", ctx.cwd, projectRoot(ctx.cwd), branch(ctx.cwd), transcript, id);
|
|
193
229
|
});
|
|
194
230
|
});
|
|
195
|
-
pi.on("
|
|
196
|
-
if (event.message.role !== "user")
|
|
197
|
-
return;
|
|
231
|
+
pi.on("agent_start", (_event, ctx) => {
|
|
198
232
|
writeFor(ctx, (db, id) => {
|
|
199
233
|
const transcript = ctx.sessionManager.getSessionFile();
|
|
200
234
|
if (!transcript)
|
|
@@ -202,12 +236,10 @@ function src_default(pi) {
|
|
|
202
236
|
const now = Date.now();
|
|
203
237
|
db.run(`INSERT INTO sessions (session_id, tool, cwd, project_root, transcript, title, branch, phase, created_at, last_prompt_at)
|
|
204
238
|
VALUES (?, 'pi', ?, ?, ?, ?, ?, 'working', ?, ?)
|
|
205
|
-
ON CONFLICT (session_id) DO UPDATE SET phase = 'working',
|
|
239
|
+
ON CONFLICT (session_id) DO UPDATE SET phase = 'working',
|
|
240
|
+
last_prompt_at = CASE WHEN sessions.phase = 'idle' THEN excluded.last_prompt_at ELSE sessions.last_prompt_at END`, id, ctx.cwd, projectRoot(ctx.cwd), transcript, ctx.sessionManager.getSessionName() ?? null, branch(ctx.cwd), now, now);
|
|
206
241
|
});
|
|
207
242
|
});
|
|
208
|
-
pi.on("agent_start", (_event, ctx) => {
|
|
209
|
-
writeFor(ctx, (db, id) => db.run("UPDATE sessions SET phase = 'working' WHERE session_id = ?", id));
|
|
210
|
-
});
|
|
211
243
|
const attention = (open) => (data) => {
|
|
212
244
|
const attentionId = data.attentionId;
|
|
213
245
|
if (typeof attentionId !== "string" || !current)
|