@shipers-dev/multi 0.65.0 → 0.66.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.js +183 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34493,6 +34493,27 @@ var init_chat = __esm(() => {
|
|
|
34493
34493
|
primary_agent_id: exports_external.string().nullable().optional()
|
|
34494
34494
|
});
|
|
34495
34495
|
});
|
|
34496
|
+
// ../lib/device-link.ts
|
|
34497
|
+
function encodeFrame(frame) {
|
|
34498
|
+
const body = new TextEncoder().encode(JSON.stringify(frame));
|
|
34499
|
+
const out = new Uint8Array(1 + body.byteLength);
|
|
34500
|
+
out[0] = FRAME_JSON;
|
|
34501
|
+
out.set(body, 1);
|
|
34502
|
+
return out;
|
|
34503
|
+
}
|
|
34504
|
+
function decodeFrame(buf) {
|
|
34505
|
+
if (buf.byteLength < 1)
|
|
34506
|
+
return null;
|
|
34507
|
+
if (buf[0] !== FRAME_JSON)
|
|
34508
|
+
return null;
|
|
34509
|
+
try {
|
|
34510
|
+
return JSON.parse(new TextDecoder().decode(buf.subarray(1)));
|
|
34511
|
+
} catch {
|
|
34512
|
+
return null;
|
|
34513
|
+
}
|
|
34514
|
+
}
|
|
34515
|
+
var FRAME_JSON = 0;
|
|
34516
|
+
|
|
34496
34517
|
// ../lib/index.ts
|
|
34497
34518
|
var init_lib = __esm(() => {
|
|
34498
34519
|
init_streams();
|
|
@@ -36935,7 +36956,7 @@ class ChatPeer {
|
|
|
36935
36956
|
return;
|
|
36936
36957
|
const body = new TextEncoder().encode(JSON.stringify(obj));
|
|
36937
36958
|
const frame = new Uint8Array(1 + body.byteLength);
|
|
36938
|
-
frame[0] =
|
|
36959
|
+
frame[0] = FRAME_JSON2;
|
|
36939
36960
|
frame.set(body, 1);
|
|
36940
36961
|
try {
|
|
36941
36962
|
this.ws.send(frame);
|
|
@@ -36978,7 +36999,7 @@ class ChatPeer {
|
|
|
36978
36999
|
this.persist();
|
|
36979
37000
|
return;
|
|
36980
37001
|
}
|
|
36981
|
-
if (tag3 ===
|
|
37002
|
+
if (tag3 === FRAME_JSON2) {
|
|
36982
37003
|
try {
|
|
36983
37004
|
const txt = new TextDecoder().decode(buf.subarray(1));
|
|
36984
37005
|
const msg = JSON.parse(txt);
|
|
@@ -36988,7 +37009,7 @@ class ChatPeer {
|
|
|
36988
37009
|
}
|
|
36989
37010
|
}
|
|
36990
37011
|
}
|
|
36991
|
-
var
|
|
37012
|
+
var FRAME_JSON2 = 0, FRAME_LORO = 1;
|
|
36992
37013
|
var init_chat_peer = __esm(() => {
|
|
36993
37014
|
init_paths();
|
|
36994
37015
|
init_chat_doc();
|
|
@@ -38853,7 +38874,7 @@ import { parseArgs } from "util";
|
|
|
38853
38874
|
// package.json
|
|
38854
38875
|
var package_default = {
|
|
38855
38876
|
name: "@shipers-dev/multi",
|
|
38856
|
-
version: "0.
|
|
38877
|
+
version: "0.66.0",
|
|
38857
38878
|
type: "module",
|
|
38858
38879
|
bin: {
|
|
38859
38880
|
"multi-agent": "./dist/index.js"
|
|
@@ -39934,10 +39955,101 @@ import { homedir as homedir4 } from "os";
|
|
|
39934
39955
|
import { join as join16 } from "path";
|
|
39935
39956
|
init_adapter_pidfile();
|
|
39936
39957
|
init_errors();
|
|
39958
|
+
|
|
39959
|
+
// src/_impl/device-link-client.ts
|
|
39960
|
+
function startDeviceLinkClient(opts) {
|
|
39961
|
+
let ws = null;
|
|
39962
|
+
let stopped = false;
|
|
39963
|
+
let attempt = 0;
|
|
39964
|
+
let reconnectTimer = null;
|
|
39965
|
+
const connect = () => {
|
|
39966
|
+
if (stopped)
|
|
39967
|
+
return;
|
|
39968
|
+
let socket;
|
|
39969
|
+
try {
|
|
39970
|
+
socket = new WebSocket(opts.url);
|
|
39971
|
+
} catch (e) {
|
|
39972
|
+
opts.log(`[device-link] ws construct error: ${e.message}`);
|
|
39973
|
+
scheduleReconnect();
|
|
39974
|
+
return;
|
|
39975
|
+
}
|
|
39976
|
+
socket.binaryType = "arraybuffer";
|
|
39977
|
+
socket.addEventListener("open", () => {
|
|
39978
|
+
attempt = 0;
|
|
39979
|
+
ws = socket;
|
|
39980
|
+
opts.log("[device-link] connected");
|
|
39981
|
+
try {
|
|
39982
|
+
socket.send(encodeFrame({ kind: "hello", cli_version: opts.cliVersion, device_id: opts.deviceId }));
|
|
39983
|
+
} catch {}
|
|
39984
|
+
});
|
|
39985
|
+
socket.addEventListener("message", (ev) => {
|
|
39986
|
+
const data = ev.data;
|
|
39987
|
+
if (!(data instanceof ArrayBuffer))
|
|
39988
|
+
return;
|
|
39989
|
+
const frame = decodeFrame(new Uint8Array(data));
|
|
39990
|
+
if (!frame)
|
|
39991
|
+
return;
|
|
39992
|
+
try {
|
|
39993
|
+
const ret = opts.onFrame(frame);
|
|
39994
|
+
if (ret && typeof ret.catch === "function") {
|
|
39995
|
+
ret.catch((e) => {
|
|
39996
|
+
opts.log(`[device-link] onFrame rejected: ${e?.message ?? String(e)}`);
|
|
39997
|
+
});
|
|
39998
|
+
}
|
|
39999
|
+
} catch (e) {
|
|
40000
|
+
opts.log(`[device-link] onFrame threw: ${e.message}`);
|
|
40001
|
+
}
|
|
40002
|
+
});
|
|
40003
|
+
const handleEnd = (reason) => {
|
|
40004
|
+
if (ws === socket)
|
|
40005
|
+
ws = null;
|
|
40006
|
+
opts.log(`[device-link] disconnected (${reason})`);
|
|
40007
|
+
scheduleReconnect();
|
|
40008
|
+
};
|
|
40009
|
+
socket.addEventListener("close", (ev) => handleEnd(`code=${ev.code}`));
|
|
40010
|
+
socket.addEventListener("error", () => handleEnd("error"));
|
|
40011
|
+
};
|
|
40012
|
+
const scheduleReconnect = () => {
|
|
40013
|
+
if (stopped || reconnectTimer !== null)
|
|
40014
|
+
return;
|
|
40015
|
+
attempt++;
|
|
40016
|
+
const base = Math.min(60000, 1000 * Math.pow(2, Math.min(6, attempt - 1)));
|
|
40017
|
+
const jitter = base * (0.75 + Math.random() * 0.5);
|
|
40018
|
+
reconnectTimer = setTimeout(() => {
|
|
40019
|
+
reconnectTimer = null;
|
|
40020
|
+
connect();
|
|
40021
|
+
}, jitter);
|
|
40022
|
+
};
|
|
40023
|
+
connect();
|
|
40024
|
+
return {
|
|
40025
|
+
isConnected: () => ws !== null && ws.readyState === WebSocket.OPEN,
|
|
40026
|
+
send: (frame) => {
|
|
40027
|
+
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
40028
|
+
return false;
|
|
40029
|
+
try {
|
|
40030
|
+
ws.send(encodeFrame(frame));
|
|
40031
|
+
return true;
|
|
40032
|
+
} catch {
|
|
40033
|
+
return false;
|
|
40034
|
+
}
|
|
40035
|
+
},
|
|
40036
|
+
stop: () => {
|
|
40037
|
+
stopped = true;
|
|
40038
|
+
if (reconnectTimer !== null) {
|
|
40039
|
+
clearTimeout(reconnectTimer);
|
|
40040
|
+
reconnectTimer = null;
|
|
40041
|
+
}
|
|
40042
|
+
try {
|
|
40043
|
+
ws?.close(1000, "stopping");
|
|
40044
|
+
} catch {}
|
|
40045
|
+
ws = null;
|
|
40046
|
+
}
|
|
40047
|
+
};
|
|
40048
|
+
}
|
|
39937
40049
|
// package.json
|
|
39938
40050
|
var package_default2 = {
|
|
39939
40051
|
name: "@shipers-dev/multi",
|
|
39940
|
-
version: "0.
|
|
40052
|
+
version: "0.66.0",
|
|
39941
40053
|
type: "module",
|
|
39942
40054
|
bin: {
|
|
39943
40055
|
"multi-agent": "./dist/index.js"
|
|
@@ -40931,6 +41043,69 @@ var daemonProgram = ({ cfg, apiUrl }) => exports_Effect.gen(function* () {
|
|
|
40931
41043
|
cli_version: CLI_VERSION
|
|
40932
41044
|
}, null, 2));
|
|
40933
41045
|
} catch {}
|
|
41046
|
+
let deviceLink = null;
|
|
41047
|
+
if (!localMode && cfg.workspaceId && cfg.deviceId && cfg.dispatchSecret) {
|
|
41048
|
+
const linkUrl = `${apiUrl.replace(/^http/, "ws")}/api/daemon/link?device_id=${encodeURIComponent(cfg.deviceId)}&token=${encodeURIComponent(cfg.dispatchSecret)}`;
|
|
41049
|
+
const onFrame = async (frame) => {
|
|
41050
|
+
switch (frame.kind) {
|
|
41051
|
+
case "chat_turn": {
|
|
41052
|
+
try {
|
|
41053
|
+
const { chatSessionRegistry: chatSessionRegistry2 } = await Promise.resolve().then(() => (init_chat_session_registry(), exports_chat_session_registry));
|
|
41054
|
+
await chatSessionRegistry2.ensureAndProcess(frame.workspace_id, frame.chat_id, frame.message_id, { apiUrl, authToken: cfg.authToken, workspaceId: frame.workspace_id, deviceId: cfg.deviceId, log: log3 });
|
|
41055
|
+
deviceLink?.send({ id: frame.id, kind: "ack", for: frame.id, ok: true });
|
|
41056
|
+
} catch (e) {
|
|
41057
|
+
deviceLink?.send({ id: frame.id, kind: "ack", for: frame.id, ok: false, error: e.message });
|
|
41058
|
+
}
|
|
41059
|
+
return;
|
|
41060
|
+
}
|
|
41061
|
+
case "supervisor_tick": {
|
|
41062
|
+
try {
|
|
41063
|
+
const { runSupervisorTick: runSupervisorTick2 } = await Promise.resolve().then(() => (init_supervisor_tick(), exports_supervisor_tick));
|
|
41064
|
+
await runSupervisorTick2({
|
|
41065
|
+
apiUrl,
|
|
41066
|
+
tickId: frame.tick_id,
|
|
41067
|
+
projectId: frame.project_id,
|
|
41068
|
+
system: frame.system,
|
|
41069
|
+
user: frame.user,
|
|
41070
|
+
callbackUrl: frame.callback_url,
|
|
41071
|
+
callbackToken: frame.callback_token,
|
|
41072
|
+
log: log3
|
|
41073
|
+
});
|
|
41074
|
+
deviceLink?.send({ id: frame.id, kind: "ack", for: frame.id, ok: true });
|
|
41075
|
+
} catch (e) {
|
|
41076
|
+
deviceLink?.send({ id: frame.id, kind: "ack", for: frame.id, ok: false, error: e.message });
|
|
41077
|
+
}
|
|
41078
|
+
return;
|
|
41079
|
+
}
|
|
41080
|
+
case "stop": {
|
|
41081
|
+
const entries2 = Array.from(running3.values()).filter((e) => e.issueId === frame.issue_id);
|
|
41082
|
+
for (const entry of entries2) {
|
|
41083
|
+
entry.stopped = true;
|
|
41084
|
+
entry.stopReason = "user requested";
|
|
41085
|
+
try {
|
|
41086
|
+
entry.child?.kill("SIGTERM");
|
|
41087
|
+
} catch {}
|
|
41088
|
+
setTimeout(() => {
|
|
41089
|
+
try {
|
|
41090
|
+
entry.child?.kill("SIGKILL");
|
|
41091
|
+
} catch {}
|
|
41092
|
+
}, 1500);
|
|
41093
|
+
}
|
|
41094
|
+
deviceLink?.send({ id: frame.id, kind: "ack", for: frame.id, ok: true });
|
|
41095
|
+
return;
|
|
41096
|
+
}
|
|
41097
|
+
default:
|
|
41098
|
+
return;
|
|
41099
|
+
}
|
|
41100
|
+
};
|
|
41101
|
+
deviceLink = startDeviceLinkClient({
|
|
41102
|
+
url: linkUrl,
|
|
41103
|
+
cliVersion: CLI_VERSION,
|
|
41104
|
+
deviceId: cfg.deviceId,
|
|
41105
|
+
onFrame,
|
|
41106
|
+
log: log3
|
|
41107
|
+
});
|
|
41108
|
+
}
|
|
40934
41109
|
let tunnel;
|
|
40935
41110
|
if (localMode) {
|
|
40936
41111
|
tunnel = { child: null, url: `http://127.0.0.1:${port}` };
|
|
@@ -41043,6 +41218,9 @@ var daemonProgram = ({ cfg, apiUrl }) => exports_Effect.gen(function* () {
|
|
|
41043
41218
|
try {
|
|
41044
41219
|
tunnel?.child?.kill();
|
|
41045
41220
|
} catch {}
|
|
41221
|
+
try {
|
|
41222
|
+
deviceLink?.stop();
|
|
41223
|
+
} catch {}
|
|
41046
41224
|
yield* exports_Effect.promise(async () => {
|
|
41047
41225
|
try {
|
|
41048
41226
|
const { chatSessionRegistry: chatSessionRegistry2 } = await Promise.resolve().then(() => (init_chat_session_registry(), exports_chat_session_registry));
|