@csdwd/ai-teams-server 0.3.1 → 0.3.2
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 +56 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import websocket from "@fastify/websocket";
|
|
|
13
13
|
import fastifyStatic from "@fastify/static";
|
|
14
14
|
|
|
15
15
|
// ../../packages/shared/dist/index.js
|
|
16
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timeout"]);
|
|
16
17
|
var ProtocolError = class extends Error {
|
|
17
18
|
constructor(message) {
|
|
18
19
|
super(message);
|
|
@@ -578,6 +579,16 @@ async function hydrateState(db, state, defaultTimeoutSec, maxLogChunksPerTask) {
|
|
|
578
579
|
queue.push(task.id);
|
|
579
580
|
state.taskQueues.set(task.employeeId, queue);
|
|
580
581
|
}
|
|
582
|
+
} else if (task.employeeId && !TERMINAL_STATUSES.has(task.status)) {
|
|
583
|
+
task.status = "queued";
|
|
584
|
+
persistTask(db, task);
|
|
585
|
+
if (task.targetMode === "queue") {
|
|
586
|
+
state.sharedTaskQueue.push(task.id);
|
|
587
|
+
} else {
|
|
588
|
+
const queue = state.mainTaskQueues.get(task.employeeId) ?? [];
|
|
589
|
+
queue.push(task.id);
|
|
590
|
+
state.mainTaskQueues.set(task.employeeId, queue);
|
|
591
|
+
}
|
|
581
592
|
}
|
|
582
593
|
}
|
|
583
594
|
const logRows = await db.all(
|
|
@@ -1222,7 +1233,6 @@ var scheduleListResponseSchema = {
|
|
|
1222
1233
|
// src/dispatch.ts
|
|
1223
1234
|
import { createHmac, randomUUID } from "node:crypto";
|
|
1224
1235
|
import WebSocket from "ws";
|
|
1225
|
-
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled", "timeout"]);
|
|
1226
1236
|
function nowIso() {
|
|
1227
1237
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
1228
1238
|
}
|
|
@@ -1959,11 +1969,52 @@ function createDispatch(ctx) {
|
|
|
1959
1969
|
break;
|
|
1960
1970
|
}
|
|
1961
1971
|
}
|
|
1972
|
+
function startDisconnectRecovery(employeeId) {
|
|
1973
|
+
const employee = state.employees.get(employeeId);
|
|
1974
|
+
if (!employee) return;
|
|
1975
|
+
const taskIds = [];
|
|
1976
|
+
if (employee.mainTaskId) taskIds.push(employee.mainTaskId);
|
|
1977
|
+
if (employee.queueTaskId) taskIds.push(employee.queueTaskId);
|
|
1978
|
+
if (taskIds.length === 0) return;
|
|
1979
|
+
const timer = setTimeout(() => {
|
|
1980
|
+
state.disconnectTimers.delete(employeeId);
|
|
1981
|
+
if (state.agentSockets.has(employeeId)) return;
|
|
1982
|
+
for (const taskId of taskIds) {
|
|
1983
|
+
const task = state.tasks.get(taskId);
|
|
1984
|
+
if (!task || TERMINAL_STATUSES.has(task.status)) continue;
|
|
1985
|
+
clearTaskTimeout(taskId);
|
|
1986
|
+
task.status = "queued";
|
|
1987
|
+
task.employeeId = null;
|
|
1988
|
+
upsertTask(task);
|
|
1989
|
+
log.info({ taskId, employeeId }, "Task re-queued after disconnect grace period");
|
|
1990
|
+
if (task.targetMode === "queue") {
|
|
1991
|
+
enqueueSharedTask(taskId);
|
|
1992
|
+
} else {
|
|
1993
|
+
const queue = state.mainTaskQueues.get(employeeId) ?? [];
|
|
1994
|
+
if (!queue.includes(taskId)) queue.push(taskId);
|
|
1995
|
+
state.mainTaskQueues.set(employeeId, queue);
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
const emp = state.employees.get(employeeId);
|
|
1999
|
+
if (emp) {
|
|
2000
|
+
if (taskIds.includes(emp.mainTaskId ?? "")) setMainTask(employeeId, null, null);
|
|
2001
|
+
if (taskIds.includes(emp.queueTaskId ?? "")) setQueueTask(employeeId, null, null);
|
|
2002
|
+
broadcastToLeaders({ type: "employee.upsert", employee: emp });
|
|
2003
|
+
}
|
|
2004
|
+
for (const taskId of taskIds) {
|
|
2005
|
+
const task = state.tasks.get(taskId);
|
|
2006
|
+
if (task) broadcastToLeaders({ type: "task.upsert", task });
|
|
2007
|
+
}
|
|
2008
|
+
dispatchSharedQueuedTasks();
|
|
2009
|
+
}, ctx.disconnectGraceMs);
|
|
2010
|
+
state.disconnectTimers.set(employeeId, timer);
|
|
2011
|
+
}
|
|
1962
2012
|
return {
|
|
1963
2013
|
dispatchLeaderCommand,
|
|
1964
2014
|
handleAgentMessage,
|
|
1965
2015
|
handleLeaderMessage,
|
|
1966
|
-
cancelTaskById
|
|
2016
|
+
cancelTaskById,
|
|
2017
|
+
startDisconnectRecovery
|
|
1967
2018
|
};
|
|
1968
2019
|
}
|
|
1969
2020
|
|
|
@@ -2157,7 +2208,7 @@ async function createAiTeamsServer(options) {
|
|
|
2157
2208
|
disconnectGraceMs,
|
|
2158
2209
|
encryptor: createEncryptor(process.env.AI_TEAMS_ENCRYPTION_KEY)
|
|
2159
2210
|
};
|
|
2160
|
-
const { dispatchLeaderCommand, handleAgentMessage, handleLeaderMessage, cancelTaskById } = createDispatch(dispatchCtx);
|
|
2211
|
+
const { dispatchLeaderCommand, handleAgentMessage, handleLeaderMessage, cancelTaskById, startDisconnectRecovery } = createDispatch(dispatchCtx);
|
|
2161
2212
|
const scheduleDispatchFn = (message, webhookUrl, cliConfig, priority, requiredLabels) => {
|
|
2162
2213
|
return dispatchLeaderCommand(message, webhookUrl, cliConfig, priority, requiredLabels);
|
|
2163
2214
|
};
|
|
@@ -2786,6 +2837,7 @@ async function createAiTeamsServer(options) {
|
|
|
2786
2837
|
for (const leaderSocket of state.leaderSockets) {
|
|
2787
2838
|
sendJson(leaderSocket, { type: "employee.upsert", employee }, dispatchCtx.encryptor);
|
|
2788
2839
|
}
|
|
2840
|
+
startDisconnectRecovery(employeeId);
|
|
2789
2841
|
}
|
|
2790
2842
|
app.log.info({ employeeId }, "Agent disconnected");
|
|
2791
2843
|
});
|
|
@@ -2891,7 +2943,7 @@ if (isCli) {
|
|
|
2891
2943
|
getArgValue2 = getArgValue, resolveDataDir2 = resolveDataDir, resolvePidFile2 = resolvePidFile, resolveLogDir2 = resolveLogDir, applyCliArgsToEnv2 = applyCliArgsToEnv;
|
|
2892
2944
|
const args = process.argv.slice(2);
|
|
2893
2945
|
if (args.includes("--version") || args.includes("-v")) {
|
|
2894
|
-
console.log("0.3.
|
|
2946
|
+
console.log("0.3.2");
|
|
2895
2947
|
process.exit(0);
|
|
2896
2948
|
}
|
|
2897
2949
|
if (args.includes("--help") || args.includes("-h")) {
|
package/package.json
CHANGED