@shipers-dev/multi 0.44.0 → 0.46.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 +257 -43
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33352,12 +33352,24 @@ ${c.newText || ""}`.slice(0, 4000);
|
|
|
33352
33352
|
break;
|
|
33353
33353
|
}
|
|
33354
33354
|
case "plan": {
|
|
33355
|
-
const
|
|
33355
|
+
const rawEntries = u.entries || [];
|
|
33356
|
+
if (!rawEntries.length)
|
|
33357
|
+
break;
|
|
33358
|
+
if (o.onPlanUpdate) {
|
|
33359
|
+
const entries2 = rawEntries.map((e) => ({
|
|
33360
|
+
status: String(e?.status ?? "pending"),
|
|
33361
|
+
content: String(e?.content ?? "")
|
|
33362
|
+
}));
|
|
33363
|
+
await o.onPlanUpdate(entries2);
|
|
33364
|
+
} else {
|
|
33365
|
+
const text = rawEntries.map((e, i) => `${i + 1}. [${e.status || "pending"}] ${e.content}`).join(`
|
|
33356
33366
|
`);
|
|
33357
|
-
if (entries2)
|
|
33358
33367
|
await o.onEvent({ event_type: "assistant_text", payload: { text: `**Plan**
|
|
33359
33368
|
|
|
33360
|
-
${
|
|
33369
|
+
${text}
|
|
33370
|
+
|
|
33371
|
+
` } });
|
|
33372
|
+
}
|
|
33361
33373
|
break;
|
|
33362
33374
|
}
|
|
33363
33375
|
case "current_mode_update": {
|
|
@@ -33521,7 +33533,7 @@ async function runAcpx(opts) {
|
|
|
33521
33533
|
dlog(`[acpx stdout] ${line.slice(0, 500)}`);
|
|
33522
33534
|
const events = parseAcpLine(line, (r) => {
|
|
33523
33535
|
stopReason = r;
|
|
33524
|
-
});
|
|
33536
|
+
}, opts);
|
|
33525
33537
|
for (const ev of events)
|
|
33526
33538
|
await opts.onEvent(ev);
|
|
33527
33539
|
}
|
|
@@ -33530,7 +33542,7 @@ async function runAcpx(opts) {
|
|
|
33530
33542
|
if (buf.trim()) {
|
|
33531
33543
|
const events = parseAcpLine(buf.trim(), (r) => {
|
|
33532
33544
|
stopReason = r;
|
|
33533
|
-
});
|
|
33545
|
+
}, opts);
|
|
33534
33546
|
for (const ev of events)
|
|
33535
33547
|
await opts.onEvent(ev);
|
|
33536
33548
|
}
|
|
@@ -33540,7 +33552,7 @@ async function runAcpx(opts) {
|
|
|
33540
33552
|
}
|
|
33541
33553
|
return { stopReason };
|
|
33542
33554
|
}
|
|
33543
|
-
function parseAcpLine(line, setStop) {
|
|
33555
|
+
function parseAcpLine(line, setStop, opts) {
|
|
33544
33556
|
let msg;
|
|
33545
33557
|
try {
|
|
33546
33558
|
msg = JSON.parse(line);
|
|
@@ -33549,7 +33561,7 @@ function parseAcpLine(line, setStop) {
|
|
|
33549
33561
|
}
|
|
33550
33562
|
const out = [];
|
|
33551
33563
|
if (msg.method === "session/update" && msg.params?.update?.sessionUpdate) {
|
|
33552
|
-
return handleSessionUpdate(msg.params);
|
|
33564
|
+
return handleSessionUpdate(msg.params, opts);
|
|
33553
33565
|
}
|
|
33554
33566
|
if (msg.id && msg.result && typeof msg.result === "object" && "stopReason" in msg.result) {
|
|
33555
33567
|
setStop(msg.result.stopReason);
|
|
@@ -33562,7 +33574,7 @@ function parseAcpLine(line, setStop) {
|
|
|
33562
33574
|
}
|
|
33563
33575
|
return out;
|
|
33564
33576
|
}
|
|
33565
|
-
function handleSessionUpdate(params) {
|
|
33577
|
+
function handleSessionUpdate(params, opts) {
|
|
33566
33578
|
const u = params.update || {};
|
|
33567
33579
|
const kind = u.sessionUpdate;
|
|
33568
33580
|
const out = [];
|
|
@@ -33602,12 +33614,24 @@ ${c.newText || ""}`.slice(0, 4000);
|
|
|
33602
33614
|
break;
|
|
33603
33615
|
}
|
|
33604
33616
|
case "plan": {
|
|
33605
|
-
const
|
|
33617
|
+
const rawEntries = u.entries || [];
|
|
33618
|
+
if (!rawEntries.length)
|
|
33619
|
+
break;
|
|
33620
|
+
if (opts.onPlanUpdate) {
|
|
33621
|
+
const entries2 = rawEntries.map((e) => ({
|
|
33622
|
+
status: String(e?.status ?? "pending"),
|
|
33623
|
+
content: String(e?.content ?? "")
|
|
33624
|
+
}));
|
|
33625
|
+
Promise.resolve(opts.onPlanUpdate(entries2));
|
|
33626
|
+
} else {
|
|
33627
|
+
const text = rawEntries.map((e, i) => `${i + 1}. [${e.status || "pending"}] ${e.content}`).join(`
|
|
33606
33628
|
`);
|
|
33607
|
-
if (entries2)
|
|
33608
33629
|
out.push({ event_type: "assistant_text", payload: { text: `**Plan**
|
|
33609
33630
|
|
|
33610
|
-
${
|
|
33631
|
+
${text}
|
|
33632
|
+
|
|
33633
|
+
` } });
|
|
33634
|
+
}
|
|
33611
33635
|
break;
|
|
33612
33636
|
}
|
|
33613
33637
|
}
|
|
@@ -33990,7 +34014,7 @@ var init_plans = __esm(() => {
|
|
|
33990
34014
|
});
|
|
33991
34015
|
|
|
33992
34016
|
// ../lib/chat.ts
|
|
33993
|
-
var ChatScopeSchema, ChatMetaSchema, ChatAuthorKindSchema, ChatAuthorSchema, ChatAttachmentSchema, ChatMessageKindSchema, ChatToolKindSchema, ChatMessageSchema, CHAT_DOC, CreateChatBodySchema, UpdateChatBodySchema;
|
|
34017
|
+
var ChatScopeSchema, ChatMetaSchema, ChatAuthorKindSchema, ChatAuthorSchema, ChatAttachmentSchema, ChatMessageKindSchema, ChatToolKindSchema, ChatPlanEntryStatusSchema, ChatPlanEntrySchema, ChatMessageSchema, CHAT_DOC, CreateChatBodySchema, UpdateChatBodySchema;
|
|
33994
34018
|
var init_chat = __esm(() => {
|
|
33995
34019
|
init_zod();
|
|
33996
34020
|
ChatScopeSchema = exports_external.enum(["project", "workspace"]);
|
|
@@ -34018,8 +34042,13 @@ var init_chat = __esm(() => {
|
|
|
34018
34042
|
size: exports_external.number().optional(),
|
|
34019
34043
|
url: exports_external.string().optional()
|
|
34020
34044
|
});
|
|
34021
|
-
ChatMessageKindSchema = exports_external.enum(["text", "tool_call", "tool_result"]);
|
|
34045
|
+
ChatMessageKindSchema = exports_external.enum(["text", "tool_call", "tool_result", "plan"]);
|
|
34022
34046
|
ChatToolKindSchema = exports_external.enum(["edit", "read", "write", "bash", "search", "other"]);
|
|
34047
|
+
ChatPlanEntryStatusSchema = exports_external.enum(["pending", "in_progress", "completed"]);
|
|
34048
|
+
ChatPlanEntrySchema = exports_external.object({
|
|
34049
|
+
status: ChatPlanEntryStatusSchema.default("pending"),
|
|
34050
|
+
content: exports_external.string()
|
|
34051
|
+
});
|
|
34023
34052
|
ChatMessageSchema = exports_external.object({
|
|
34024
34053
|
id: exports_external.string(),
|
|
34025
34054
|
author: ChatAuthorSchema,
|
|
@@ -34034,7 +34063,10 @@ var init_chat = __esm(() => {
|
|
|
34034
34063
|
status: exports_external.enum(["pending", "in_progress", "completed", "failed"]).optional(),
|
|
34035
34064
|
input: exports_external.unknown().optional(),
|
|
34036
34065
|
tool_call_id: exports_external.string().optional(),
|
|
34037
|
-
content: exports_external.string().optional()
|
|
34066
|
+
content: exports_external.string().optional(),
|
|
34067
|
+
plan_entries: exports_external.array(ChatPlanEntrySchema).optional(),
|
|
34068
|
+
dispatched_at: exports_external.number().optional(),
|
|
34069
|
+
delivered_to_acp_at: exports_external.number().optional()
|
|
34038
34070
|
});
|
|
34039
34071
|
CHAT_DOC = {
|
|
34040
34072
|
MESSAGES_LIST: "messages",
|
|
@@ -35845,6 +35877,8 @@ function appendMessage(doc2, msg) {
|
|
|
35845
35877
|
map20.set("tool_call_id", msg.tool_call_id);
|
|
35846
35878
|
if (msg.content !== undefined)
|
|
35847
35879
|
map20.set("content", msg.content);
|
|
35880
|
+
if (msg.plan_entries !== undefined)
|
|
35881
|
+
map20.set("plan_entries", msg.plan_entries);
|
|
35848
35882
|
const mentions = map20.setContainer("mentions", new LoroList);
|
|
35849
35883
|
for (const x of msg.mentions ?? [])
|
|
35850
35884
|
mentions.push(x);
|
|
@@ -35876,6 +35910,19 @@ function finalizeMessage(doc2, mapId) {
|
|
|
35876
35910
|
return;
|
|
35877
35911
|
map20.set("partial", false);
|
|
35878
35912
|
}
|
|
35913
|
+
function setMessageField(doc2, msgId, key, value3) {
|
|
35914
|
+
const list = doc2.getMovableList(CHAT_DOC.MESSAGES_LIST);
|
|
35915
|
+
for (let i = 0;i < list.length; i++) {
|
|
35916
|
+
const child = list.get(i);
|
|
35917
|
+
if (!child || typeof child.get !== "function")
|
|
35918
|
+
continue;
|
|
35919
|
+
if (child.get("id") === msgId) {
|
|
35920
|
+
child.set(key, value3);
|
|
35921
|
+
return true;
|
|
35922
|
+
}
|
|
35923
|
+
}
|
|
35924
|
+
return false;
|
|
35925
|
+
}
|
|
35879
35926
|
function listMessages(doc2) {
|
|
35880
35927
|
const list = doc2.getMovableList(CHAT_DOC.MESSAGES_LIST);
|
|
35881
35928
|
return list.toJSON();
|
|
@@ -35909,6 +35956,7 @@ class ChatPeer {
|
|
|
35909
35956
|
dirtySinceWrite = 0;
|
|
35910
35957
|
seenIds = new Set;
|
|
35911
35958
|
closed = false;
|
|
35959
|
+
firstFrameSinceConnect = true;
|
|
35912
35960
|
reconnectTimer = null;
|
|
35913
35961
|
constructor(opts) {
|
|
35914
35962
|
this.opts = opts;
|
|
@@ -35979,10 +36027,37 @@ class ChatPeer {
|
|
|
35979
36027
|
this.flush();
|
|
35980
36028
|
return containerId;
|
|
35981
36029
|
}
|
|
36030
|
+
upsertPlan(authorAgentId, authorName, entries2, containerId) {
|
|
36031
|
+
if (containerId) {
|
|
36032
|
+
patchMessage(this.doc, containerId, { plan_entries: entries2 });
|
|
36033
|
+
this.flush();
|
|
36034
|
+
return containerId;
|
|
36035
|
+
}
|
|
36036
|
+
const msg = {
|
|
36037
|
+
id: crypto.randomUUID(),
|
|
36038
|
+
author: { kind: "agent", id: authorAgentId, name: authorName },
|
|
36039
|
+
kind: "plan",
|
|
36040
|
+
text: "",
|
|
36041
|
+
ts: Math.floor(Date.now() / 1000),
|
|
36042
|
+
mentions: [],
|
|
36043
|
+
attachments: [],
|
|
36044
|
+
partial: false,
|
|
36045
|
+
plan_entries: entries2
|
|
36046
|
+
};
|
|
36047
|
+
const cid = appendMessage(this.doc, msg);
|
|
36048
|
+
this.seenIds.add(msg.id);
|
|
36049
|
+
this.flush();
|
|
36050
|
+
return cid;
|
|
36051
|
+
}
|
|
35982
36052
|
patchMessage(containerId, patch9) {
|
|
35983
36053
|
patchMessage(this.doc, containerId, patch9);
|
|
35984
36054
|
this.flush();
|
|
35985
36055
|
}
|
|
36056
|
+
markDelivered(msgId) {
|
|
36057
|
+
if (setMessageField(this.doc, msgId, "delivered_to_acp_at", Math.floor(Date.now() / 1000))) {
|
|
36058
|
+
this.flush();
|
|
36059
|
+
}
|
|
36060
|
+
}
|
|
35986
36061
|
getDoc() {
|
|
35987
36062
|
return this.doc;
|
|
35988
36063
|
}
|
|
@@ -36031,7 +36106,11 @@ class ChatPeer {
|
|
|
36031
36106
|
return;
|
|
36032
36107
|
}
|
|
36033
36108
|
ws.binaryType = "arraybuffer";
|
|
36034
|
-
ws.addEventListener("open", () =>
|
|
36109
|
+
ws.addEventListener("open", () => {
|
|
36110
|
+
this.opts.log(`[chat ${this.chatId}] ws open`);
|
|
36111
|
+
this.firstFrameSinceConnect = true;
|
|
36112
|
+
this.sendJson({ type: "daemon_subscribed" });
|
|
36113
|
+
});
|
|
36035
36114
|
ws.addEventListener("message", (ev) => this.onFrame(ev.data));
|
|
36036
36115
|
ws.addEventListener("close", () => {
|
|
36037
36116
|
this.opts.log(`[chat ${this.chatId}] ws close`);
|
|
@@ -36062,6 +36141,17 @@ class ChatPeer {
|
|
|
36062
36141
|
this.ws.send(frame);
|
|
36063
36142
|
} catch {}
|
|
36064
36143
|
}
|
|
36144
|
+
sendJson(obj) {
|
|
36145
|
+
if (!this.ws || this.ws.readyState !== 1)
|
|
36146
|
+
return;
|
|
36147
|
+
const body = new TextEncoder().encode(JSON.stringify(obj));
|
|
36148
|
+
const frame = new Uint8Array(1 + body.byteLength);
|
|
36149
|
+
frame[0] = FRAME_JSON;
|
|
36150
|
+
frame.set(body, 1);
|
|
36151
|
+
try {
|
|
36152
|
+
this.ws.send(frame);
|
|
36153
|
+
} catch {}
|
|
36154
|
+
}
|
|
36065
36155
|
onFrame(raw) {
|
|
36066
36156
|
const buf = raw instanceof ArrayBuffer ? new Uint8Array(raw) : raw instanceof Uint8Array ? raw : null;
|
|
36067
36157
|
if (!buf || buf.byteLength < 1)
|
|
@@ -36074,10 +36164,14 @@ class ChatPeer {
|
|
|
36074
36164
|
} catch {
|
|
36075
36165
|
return;
|
|
36076
36166
|
}
|
|
36167
|
+
const isFirstFrame = this.firstFrameSinceConnect;
|
|
36168
|
+
this.firstFrameSinceConnect = false;
|
|
36077
36169
|
for (const m of listMessages(this.doc)) {
|
|
36078
36170
|
if (before2.has(m.id))
|
|
36079
36171
|
continue;
|
|
36080
36172
|
this.seenIds.add(m.id);
|
|
36173
|
+
if (isFirstFrame)
|
|
36174
|
+
continue;
|
|
36081
36175
|
if (m.author?.kind === "user" && !m.partial && this.opts.onUserMessage) {
|
|
36082
36176
|
const cb = this.opts.onUserMessage;
|
|
36083
36177
|
Promise.resolve().then(() => cb(m, this)).catch((e) => this.opts.log(`[chat ${this.chatId}] onUserMessage error: ${e.message}`));
|
|
@@ -36128,6 +36222,7 @@ ${opts.prompt}`;
|
|
|
36128
36222
|
prompt,
|
|
36129
36223
|
cwd: opts.cwd,
|
|
36130
36224
|
sessionName: `chat-${opts.chatId}`,
|
|
36225
|
+
onPlanUpdate: opts.onPlanUpdate,
|
|
36131
36226
|
onEvent: (ev) => {
|
|
36132
36227
|
if (ev.event_type === "assistant_text") {
|
|
36133
36228
|
const text = ev.payload?.text;
|
|
@@ -36180,6 +36275,7 @@ ${opts.prompt}`;
|
|
|
36180
36275
|
onSession: (sid) => {
|
|
36181
36276
|
chatSessions.set(opts.chatId, sid);
|
|
36182
36277
|
},
|
|
36278
|
+
onPlanUpdate: opts.onPlanUpdate,
|
|
36183
36279
|
onEvent: (ev) => {
|
|
36184
36280
|
if (ev.event_type === "assistant_text") {
|
|
36185
36281
|
const text = ev.payload?.text;
|
|
@@ -36545,11 +36641,7 @@ var init_chat_plan_actions = __esm(() => {
|
|
|
36545
36641
|
});
|
|
36546
36642
|
|
|
36547
36643
|
// src/_impl/chat-supervisor.ts
|
|
36548
|
-
|
|
36549
|
-
__export(exports_chat_supervisor, {
|
|
36550
|
-
runChatTurn: () => runChatTurn
|
|
36551
|
-
});
|
|
36552
|
-
async function runChatTurn(opts) {
|
|
36644
|
+
async function runChatTurnWithPeer(peer, opts) {
|
|
36553
36645
|
const { apiUrl, authToken: authToken2, workspaceId, chatId, messageId, log: log4 } = opts;
|
|
36554
36646
|
const headers = { authorization: `Bearer ${authToken2}` };
|
|
36555
36647
|
const metaR = await fetch(`${apiUrl}/api/workspaces/${workspaceId}/chats/${chatId}`, { headers });
|
|
@@ -36558,25 +36650,12 @@ async function runChatTurn(opts) {
|
|
|
36558
36650
|
return;
|
|
36559
36651
|
}
|
|
36560
36652
|
const chat2 = await metaR.json();
|
|
36561
|
-
const
|
|
36562
|
-
|
|
36563
|
-
|
|
36564
|
-
|
|
36565
|
-
chatId,
|
|
36566
|
-
primaryAgentId: chat2.primary_agent_id,
|
|
36567
|
-
log: log4
|
|
36568
|
-
});
|
|
36569
|
-
peer.start();
|
|
36570
|
-
try {
|
|
36571
|
-
const msg = await peer.awaitMessage(messageId, 7000);
|
|
36572
|
-
if (!msg) {
|
|
36573
|
-
log4(`[chat ${chatId}] message ${messageId} not visible after sync; aborting`);
|
|
36574
|
-
return;
|
|
36575
|
-
}
|
|
36576
|
-
await processUserMessage(chat2, msg, peer, { apiUrl, authToken: authToken2, workspaceId, log: log4 });
|
|
36577
|
-
} finally {
|
|
36578
|
-
peer.close();
|
|
36653
|
+
const msg = await peer.awaitMessage(messageId, 7000);
|
|
36654
|
+
if (!msg) {
|
|
36655
|
+
log4(`[chat ${chatId}] message ${messageId} not visible after sync; aborting`);
|
|
36656
|
+
return;
|
|
36579
36657
|
}
|
|
36658
|
+
await processUserMessage(chat2, msg, peer, { apiUrl, authToken: authToken2, workspaceId, log: log4 });
|
|
36580
36659
|
}
|
|
36581
36660
|
async function fetchAgents(apiUrl, workspaceId, authToken2) {
|
|
36582
36661
|
const headers = { authorization: `Bearer ${authToken2}` };
|
|
@@ -36647,6 +36726,7 @@ async function processUserMessage(chat2, userMsg, peer, ctx) {
|
|
|
36647
36726
|
let lastFlush = Date.now();
|
|
36648
36727
|
let agentReplyText = "";
|
|
36649
36728
|
const toolMsgByCallId = new Map;
|
|
36729
|
+
let planContainerId = null;
|
|
36650
36730
|
const flushText = (force = false) => {
|
|
36651
36731
|
const now = Date.now();
|
|
36652
36732
|
if (!buffered || textContainerId == null)
|
|
@@ -36713,6 +36793,7 @@ async function processUserMessage(chat2, userMsg, peer, ctx) {
|
|
|
36713
36793
|
return "other";
|
|
36714
36794
|
};
|
|
36715
36795
|
const preamble = buildChatPreamble({ projectId: chat2.project_id, agents: allAgents });
|
|
36796
|
+
peer.markDelivered(userMsg.id);
|
|
36716
36797
|
await new Promise((resolve2) => {
|
|
36717
36798
|
handleChatTurn({
|
|
36718
36799
|
chatId: chat2.id,
|
|
@@ -36782,6 +36863,10 @@ async function processUserMessage(chat2, userMsg, peer, ctx) {
|
|
|
36782
36863
|
if (cid)
|
|
36783
36864
|
peer.patchMessage(cid, { partial: false, status: "completed" });
|
|
36784
36865
|
},
|
|
36866
|
+
onPlanUpdate: (entries2) => {
|
|
36867
|
+
closeText();
|
|
36868
|
+
planContainerId = peer.upsertPlan(agentAuthorId, agentDisplayName, entries2, planContainerId);
|
|
36869
|
+
},
|
|
36785
36870
|
onDone: (stopReason) => {
|
|
36786
36871
|
closeText();
|
|
36787
36872
|
for (const cid of toolMsgByCallId.values()) {
|
|
@@ -36934,6 +37019,131 @@ var init_chat_supervisor = __esm(() => {
|
|
|
36934
37019
|
init_lib();
|
|
36935
37020
|
});
|
|
36936
37021
|
|
|
37022
|
+
// src/_impl/chat-session-registry.ts
|
|
37023
|
+
var exports_chat_session_registry = {};
|
|
37024
|
+
__export(exports_chat_session_registry, {
|
|
37025
|
+
chatSessionRegistry: () => chatSessionRegistry
|
|
37026
|
+
});
|
|
37027
|
+
function key(wsId, chatId) {
|
|
37028
|
+
return `${wsId}:${chatId}`;
|
|
37029
|
+
}
|
|
37030
|
+
function clearIdle(s) {
|
|
37031
|
+
if (s.idleTimer) {
|
|
37032
|
+
clearTimeout(s.idleTimer);
|
|
37033
|
+
s.idleTimer = null;
|
|
37034
|
+
}
|
|
37035
|
+
}
|
|
37036
|
+
function scheduleIdle(k, s, log4) {
|
|
37037
|
+
clearIdle(s);
|
|
37038
|
+
s.idleTimer = setTimeout(() => {
|
|
37039
|
+
if (s.inFlight) {
|
|
37040
|
+
scheduleIdle(k, s, log4);
|
|
37041
|
+
return;
|
|
37042
|
+
}
|
|
37043
|
+
log4(`[chat ${k}] idle evict`);
|
|
37044
|
+
try {
|
|
37045
|
+
s.peer.close();
|
|
37046
|
+
} catch {}
|
|
37047
|
+
sessions.delete(k);
|
|
37048
|
+
}, idleTtlMs);
|
|
37049
|
+
}
|
|
37050
|
+
function ensureSession(wsId, chatId, ctx) {
|
|
37051
|
+
const k = key(wsId, chatId);
|
|
37052
|
+
const existing = sessions.get(k);
|
|
37053
|
+
if (existing) {
|
|
37054
|
+
clearIdle(existing);
|
|
37055
|
+
return existing;
|
|
37056
|
+
}
|
|
37057
|
+
const peer = new ChatPeer({
|
|
37058
|
+
apiUrl: ctx.apiUrl,
|
|
37059
|
+
authToken: ctx.authToken,
|
|
37060
|
+
workspaceId: wsId,
|
|
37061
|
+
chatId,
|
|
37062
|
+
primaryAgentId: null,
|
|
37063
|
+
log: ctx.log,
|
|
37064
|
+
onUserMessage: (msg) => {
|
|
37065
|
+
chatSessionRegistry.ensureAndProcess(wsId, chatId, msg.id, ctx);
|
|
37066
|
+
}
|
|
37067
|
+
});
|
|
37068
|
+
peer.start();
|
|
37069
|
+
const now = Date.now();
|
|
37070
|
+
const s = {
|
|
37071
|
+
peer,
|
|
37072
|
+
ctx,
|
|
37073
|
+
chatId,
|
|
37074
|
+
startedAt: now,
|
|
37075
|
+
lastTurnAt: 0,
|
|
37076
|
+
inFlight: null,
|
|
37077
|
+
pending: [],
|
|
37078
|
+
processed: new Set,
|
|
37079
|
+
idleTimer: null
|
|
37080
|
+
};
|
|
37081
|
+
sessions.set(k, s);
|
|
37082
|
+
ctx.log(`[chat ${k}] session opened`);
|
|
37083
|
+
return s;
|
|
37084
|
+
}
|
|
37085
|
+
async function runTurn(s, k, messageId, ctx, chatId) {
|
|
37086
|
+
try {
|
|
37087
|
+
await runChatTurnWithPeer(s.peer, {
|
|
37088
|
+
apiUrl: ctx.apiUrl,
|
|
37089
|
+
authToken: ctx.authToken,
|
|
37090
|
+
workspaceId: ctx.workspaceId,
|
|
37091
|
+
deviceId: ctx.deviceId,
|
|
37092
|
+
chatId,
|
|
37093
|
+
messageId,
|
|
37094
|
+
log: ctx.log
|
|
37095
|
+
});
|
|
37096
|
+
} catch (e) {
|
|
37097
|
+
ctx.log(`[chat ${k}] turn ${messageId} error: ${e.message}`);
|
|
37098
|
+
} finally {
|
|
37099
|
+
s.lastTurnAt = Date.now();
|
|
37100
|
+
const next4 = s.pending.shift();
|
|
37101
|
+
if (next4) {
|
|
37102
|
+
s.inFlight = runTurn(s, k, next4, ctx, chatId);
|
|
37103
|
+
} else {
|
|
37104
|
+
s.inFlight = null;
|
|
37105
|
+
scheduleIdle(k, s, ctx.log);
|
|
37106
|
+
}
|
|
37107
|
+
}
|
|
37108
|
+
}
|
|
37109
|
+
var DEFAULT_IDLE_TTL_MS, sessions, idleTtlMs, chatSessionRegistry;
|
|
37110
|
+
var init_chat_session_registry = __esm(() => {
|
|
37111
|
+
init_chat_peer();
|
|
37112
|
+
init_chat_supervisor();
|
|
37113
|
+
DEFAULT_IDLE_TTL_MS = 10 * 60 * 1000;
|
|
37114
|
+
sessions = new Map;
|
|
37115
|
+
idleTtlMs = DEFAULT_IDLE_TTL_MS;
|
|
37116
|
+
chatSessionRegistry = {
|
|
37117
|
+
setIdleTtl(ms) {
|
|
37118
|
+
idleTtlMs = ms;
|
|
37119
|
+
},
|
|
37120
|
+
async ensureAndProcess(wsId, chatId, messageId, ctx) {
|
|
37121
|
+
const s = ensureSession(wsId, chatId, ctx);
|
|
37122
|
+
const k = key(wsId, chatId);
|
|
37123
|
+
if (s.processed.has(messageId))
|
|
37124
|
+
return;
|
|
37125
|
+
s.processed.add(messageId);
|
|
37126
|
+
if (s.inFlight) {
|
|
37127
|
+
s.pending.push(messageId);
|
|
37128
|
+
return;
|
|
37129
|
+
}
|
|
37130
|
+
s.inFlight = runTurn(s, k, messageId, ctx, chatId);
|
|
37131
|
+
},
|
|
37132
|
+
async closeAll() {
|
|
37133
|
+
for (const [k, s] of sessions) {
|
|
37134
|
+
clearIdle(s);
|
|
37135
|
+
try {
|
|
37136
|
+
s.peer.close();
|
|
37137
|
+
} catch {}
|
|
37138
|
+
sessions.delete(k);
|
|
37139
|
+
}
|
|
37140
|
+
},
|
|
37141
|
+
size() {
|
|
37142
|
+
return sessions.size;
|
|
37143
|
+
}
|
|
37144
|
+
};
|
|
37145
|
+
});
|
|
37146
|
+
|
|
36937
37147
|
// src/_impl/supervisor-tick.ts
|
|
36938
37148
|
var exports_supervisor_tick = {};
|
|
36939
37149
|
__export(exports_supervisor_tick, {
|
|
@@ -37553,7 +37763,7 @@ import { parseArgs } from "util";
|
|
|
37553
37763
|
// package.json
|
|
37554
37764
|
var package_default = {
|
|
37555
37765
|
name: "@shipers-dev/multi",
|
|
37556
|
-
version: "0.
|
|
37766
|
+
version: "0.46.0",
|
|
37557
37767
|
type: "module",
|
|
37558
37768
|
bin: {
|
|
37559
37769
|
"multi-agent": "./dist/index.js"
|
|
@@ -38996,14 +39206,12 @@ var daemonProgram = ({ cfg, apiUrl }) => exports_Effect.gen(function* () {
|
|
|
38996
39206
|
if (!cfg.workspaceId || !cfg.authToken || !cfg.deviceId) {
|
|
38997
39207
|
return Response.json({ error: "daemon not configured" }, { status: 503 });
|
|
38998
39208
|
}
|
|
38999
|
-
const {
|
|
39000
|
-
|
|
39209
|
+
const { chatSessionRegistry: chatSessionRegistry2 } = await Promise.resolve().then(() => (init_chat_session_registry(), exports_chat_session_registry));
|
|
39210
|
+
chatSessionRegistry2.ensureAndProcess(cfg.workspaceId, body.chat_id, body.message_id, {
|
|
39001
39211
|
apiUrl,
|
|
39002
39212
|
authToken: cfg.authToken,
|
|
39003
39213
|
workspaceId: cfg.workspaceId,
|
|
39004
39214
|
deviceId: cfg.deviceId,
|
|
39005
|
-
chatId: body.chat_id,
|
|
39006
|
-
messageId: body.message_id,
|
|
39007
39215
|
log: log3
|
|
39008
39216
|
}).catch((e) => log3(`[chat ${body.chat_id}] runChatTurn error: ${e.message}`));
|
|
39009
39217
|
return Response.json({ accepted: true }, { status: 202 });
|
|
@@ -39191,6 +39399,12 @@ var daemonProgram = ({ cfg, apiUrl }) => exports_Effect.gen(function* () {
|
|
|
39191
39399
|
try {
|
|
39192
39400
|
tunnel?.child?.kill();
|
|
39193
39401
|
} catch {}
|
|
39402
|
+
yield* exports_Effect.promise(async () => {
|
|
39403
|
+
try {
|
|
39404
|
+
const { chatSessionRegistry: chatSessionRegistry2 } = await Promise.resolve().then(() => (init_chat_session_registry(), exports_chat_session_registry));
|
|
39405
|
+
await chatSessionRegistry2.closeAll();
|
|
39406
|
+
} catch {}
|
|
39407
|
+
});
|
|
39194
39408
|
yield* announceTunnel(apiUrl, cfg.workspaceId, cfg.deviceId, null).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
39195
39409
|
const inFlight = [];
|
|
39196
39410
|
for (const e of running3.values())
|