clay-server 2.27.0-beta.1 → 2.27.0-beta.10
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/lib/project-debate.js +25 -12
- package/lib/project.js +2 -0
- package/lib/public/app.js +12 -5
- package/lib/public/modules/debate.js +21 -4
- package/lib/sdk-bridge.js +4 -3
- package/lib/server.js +23 -19
- package/package.json +1 -1
package/lib/project-debate.js
CHANGED
|
@@ -299,6 +299,10 @@ function attachDebate(ctx) {
|
|
|
299
299
|
}),
|
|
300
300
|
};
|
|
301
301
|
ctx.sendToSession(session.localId, briefReadyMsg);
|
|
302
|
+
// Also send to setup session if client switched there (quickStart flow)
|
|
303
|
+
if (debate.setupSessionId && debate.setupSessionId !== session.localId) {
|
|
304
|
+
ctx.sendToSession(debate.setupSessionId, briefReadyMsg);
|
|
305
|
+
}
|
|
302
306
|
} else {
|
|
303
307
|
console.log("[debate] Brief picked up, transitioning to live. Topic:", debate.topic);
|
|
304
308
|
// Transition to live (standard flow via modal/skill)
|
|
@@ -530,6 +534,8 @@ function attachDebate(ctx) {
|
|
|
530
534
|
ctx.sm.switchSession(setupSession.localId, null, ctx.hydrateImageRefs);
|
|
531
535
|
debate.setupSessionId = setupSession.localId;
|
|
532
536
|
debate.setupStartedAt = setupSession.loop.startedAt;
|
|
537
|
+
// Share debate state with setup session so confirm_brief works from either
|
|
538
|
+
setupSession._debate = debate;
|
|
533
539
|
|
|
534
540
|
// Build DM conversation context for the moderator
|
|
535
541
|
var dmContext = msg.dmContext || "";
|
|
@@ -715,6 +721,13 @@ function attachDebate(ctx) {
|
|
|
715
721
|
ctx.send({ type: "mention_processing", mateId: mateId, active: active });
|
|
716
722
|
}
|
|
717
723
|
|
|
724
|
+
// Persist a debate message to session history and send to clients
|
|
725
|
+
function debateSendAndRecord(session, msg) {
|
|
726
|
+
session.history.push(msg);
|
|
727
|
+
ctx.sm.appendToSessionFile(session, msg);
|
|
728
|
+
ctx.sendToSession(session.localId, msg);
|
|
729
|
+
}
|
|
730
|
+
|
|
718
731
|
// --- Live debate ---
|
|
719
732
|
|
|
720
733
|
function startDebateLive(session) {
|
|
@@ -765,7 +778,7 @@ function attachDebate(ctx) {
|
|
|
765
778
|
|
|
766
779
|
// Signal moderator's first turn
|
|
767
780
|
debateMateProcessing(debate.moderatorId, true);
|
|
768
|
-
|
|
781
|
+
debateSendAndRecord(debateSession, {
|
|
769
782
|
type: "debate_turn",
|
|
770
783
|
mateId: debate.moderatorId,
|
|
771
784
|
mateName: moderatorProfile.name,
|
|
@@ -792,7 +805,7 @@ function attachDebate(ctx) {
|
|
|
792
805
|
},
|
|
793
806
|
onDelta: function (delta) {
|
|
794
807
|
if (debateSession._debate && debateSession._debate.phase !== "ended") {
|
|
795
|
-
|
|
808
|
+
debateSendAndRecord(debateSession, { type: "debate_stream", mateId: debate.moderatorId, mateName: moderatorProfile.name, delta: delta });
|
|
796
809
|
}
|
|
797
810
|
},
|
|
798
811
|
onDone: function (fullText) {
|
|
@@ -900,7 +913,7 @@ function attachDebate(ctx) {
|
|
|
900
913
|
|
|
901
914
|
// Notify clients of new turn
|
|
902
915
|
debateMateProcessing(mateId, true);
|
|
903
|
-
|
|
916
|
+
debateSendAndRecord(session, {
|
|
904
917
|
type: "debate_turn",
|
|
905
918
|
mateId: mateId,
|
|
906
919
|
mateName: profile.name,
|
|
@@ -920,7 +933,7 @@ function attachDebate(ctx) {
|
|
|
920
933
|
onDelta: function (delta) {
|
|
921
934
|
if (session._debate && session._debate.phase !== "ended") {
|
|
922
935
|
debate._currentTurnText += delta;
|
|
923
|
-
|
|
936
|
+
debateSendAndRecord(session, { type: "debate_stream", mateId: mateId, mateName: profile.name, delta: delta });
|
|
924
937
|
}
|
|
925
938
|
},
|
|
926
939
|
onDone: function (fullText) {
|
|
@@ -1065,7 +1078,7 @@ function attachDebate(ctx) {
|
|
|
1065
1078
|
|
|
1066
1079
|
// Notify clients of moderator turn
|
|
1067
1080
|
debateMateProcessing(debate.moderatorId, true);
|
|
1068
|
-
|
|
1081
|
+
debateSendAndRecord(session, {
|
|
1069
1082
|
type: "debate_turn",
|
|
1070
1083
|
mateId: debate.moderatorId,
|
|
1071
1084
|
mateName: moderatorProfile.name,
|
|
@@ -1095,7 +1108,7 @@ function attachDebate(ctx) {
|
|
|
1095
1108
|
},
|
|
1096
1109
|
onDelta: function (delta) {
|
|
1097
1110
|
if (session._debate && session._debate.phase !== "ended") {
|
|
1098
|
-
|
|
1111
|
+
debateSendAndRecord(session, { type: "debate_stream", mateId: debate.moderatorId, mateName: moderatorProfile.name, delta: delta });
|
|
1099
1112
|
}
|
|
1100
1113
|
},
|
|
1101
1114
|
onDone: function (fullText) {
|
|
@@ -1162,7 +1175,7 @@ function attachDebate(ctx) {
|
|
|
1162
1175
|
debate.turnInProgress = true;
|
|
1163
1176
|
var moderatorProfile = ctx.getMateProfile(debate.mateCtx, debate.moderatorId);
|
|
1164
1177
|
|
|
1165
|
-
|
|
1178
|
+
debateSendAndRecord(session, {
|
|
1166
1179
|
type: "debate_turn",
|
|
1167
1180
|
mateId: debate.moderatorId,
|
|
1168
1181
|
mateName: moderatorProfile.name,
|
|
@@ -1201,7 +1214,7 @@ function attachDebate(ctx) {
|
|
|
1201
1214
|
debate.turnInProgress = true;
|
|
1202
1215
|
var moderatorProfile = ctx.getMateProfile(debate.mateCtx, debate.moderatorId);
|
|
1203
1216
|
|
|
1204
|
-
|
|
1217
|
+
debateSendAndRecord(session, {
|
|
1205
1218
|
type: "debate_turn",
|
|
1206
1219
|
mateId: debate.moderatorId,
|
|
1207
1220
|
mateName: moderatorProfile.name,
|
|
@@ -1232,7 +1245,7 @@ function attachDebate(ctx) {
|
|
|
1232
1245
|
},
|
|
1233
1246
|
onDelta: function (delta) {
|
|
1234
1247
|
if (session._debate && session._debate.phase !== "ended") {
|
|
1235
|
-
|
|
1248
|
+
debateSendAndRecord(session, { type: "debate_stream", mateId: debate.moderatorId, mateName: moderatorProfile.name, delta: delta });
|
|
1236
1249
|
}
|
|
1237
1250
|
},
|
|
1238
1251
|
onDone: function (fullText) {
|
|
@@ -1281,7 +1294,7 @@ function attachDebate(ctx) {
|
|
|
1281
1294
|
var moderatorProfile = ctx.getMateProfile(debate.mateCtx, debate.moderatorId);
|
|
1282
1295
|
|
|
1283
1296
|
debateMateProcessing(debate.moderatorId, true);
|
|
1284
|
-
|
|
1297
|
+
debateSendAndRecord(session, {
|
|
1285
1298
|
type: "debate_turn",
|
|
1286
1299
|
mateId: debate.moderatorId,
|
|
1287
1300
|
mateName: moderatorProfile.name,
|
|
@@ -1471,7 +1484,7 @@ function attachDebate(ctx) {
|
|
|
1471
1484
|
|
|
1472
1485
|
debate.turnInProgress = true;
|
|
1473
1486
|
debateMateProcessing(debate.moderatorId, true);
|
|
1474
|
-
|
|
1487
|
+
debateSendAndRecord(session, {
|
|
1475
1488
|
type: "debate_turn",
|
|
1476
1489
|
mateId: debate.moderatorId,
|
|
1477
1490
|
mateName: moderatorProfile.name,
|
|
@@ -1519,7 +1532,7 @@ function attachDebate(ctx) {
|
|
|
1519
1532
|
},
|
|
1520
1533
|
onDelta: function (delta) {
|
|
1521
1534
|
if (session._debate && session._debate.phase !== "ended") {
|
|
1522
|
-
|
|
1535
|
+
debateSendAndRecord(session, { type: "debate_stream", mateId: debate.moderatorId, mateName: moderatorProfile.name, delta: delta });
|
|
1523
1536
|
}
|
|
1524
1537
|
},
|
|
1525
1538
|
onDone: function (fullText) {
|
package/lib/project.js
CHANGED
|
@@ -886,6 +886,7 @@ function createProjectContext(opts) {
|
|
|
886
886
|
matesModule: matesModule,
|
|
887
887
|
getSessionForWs: getSessionForWs,
|
|
888
888
|
getLinuxUserForSession: getLinuxUserForSession,
|
|
889
|
+
getOsUserInfoForWs: getOsUserInfoForWs,
|
|
889
890
|
hydrateImageRefs: hydrateImageRefs,
|
|
890
891
|
saveImageFile: saveImageFile,
|
|
891
892
|
imagesDir: imagesDir,
|
|
@@ -893,6 +894,7 @@ function createProjectContext(opts) {
|
|
|
893
894
|
_loop: _loop,
|
|
894
895
|
browserState: { _browserTabList: _browserTabList, _extensionWs: _extensionWs, pendingExtensionRequests: pendingExtensionRequests },
|
|
895
896
|
sendExtensionCommandAny: sendExtensionCommandAny,
|
|
897
|
+
requestTabContext: requestTabContext,
|
|
896
898
|
scheduleMessage: scheduleMessage,
|
|
897
899
|
cancelScheduledMessage: cancelScheduledMessage,
|
|
898
900
|
loadContextSources: loadContextSources,
|
package/lib/public/app.js
CHANGED
|
@@ -5518,11 +5518,7 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
5518
5518
|
|
|
5519
5519
|
case "debate_turn_done":
|
|
5520
5520
|
if (msg.round) updateDebateRound(msg.round);
|
|
5521
|
-
|
|
5522
|
-
renderDebateTurnDone(msg);
|
|
5523
|
-
} else {
|
|
5524
|
-
handleDebateTurnDone(msg);
|
|
5525
|
-
}
|
|
5521
|
+
handleDebateTurnDone(msg);
|
|
5526
5522
|
break;
|
|
5527
5523
|
|
|
5528
5524
|
case "debate_hand_raised":
|
|
@@ -7531,6 +7527,17 @@ import { initDebate, handleDebatePreparing, handleDebateStarted, handleDebateRes
|
|
|
7531
7527
|
document.getElementById("debate-bottom-stop").addEventListener("click", function () {
|
|
7532
7528
|
if (ws && ws.readyState === 1) {
|
|
7533
7529
|
ws.send(JSON.stringify({ type: "debate_stop" }));
|
|
7530
|
+
var stopBtn = document.getElementById("debate-bottom-stop");
|
|
7531
|
+
if (stopBtn) {
|
|
7532
|
+
stopBtn.disabled = true;
|
|
7533
|
+
stopBtn.innerHTML = iconHtml("loader") + " Stopping...";
|
|
7534
|
+
refreshIcons();
|
|
7535
|
+
}
|
|
7536
|
+
var waitingEl = document.getElementById("debate-bottom-waiting");
|
|
7537
|
+
if (waitingEl) {
|
|
7538
|
+
waitingEl.textContent = "Stopping after current turn...";
|
|
7539
|
+
waitingEl.classList.remove("hidden");
|
|
7540
|
+
}
|
|
7534
7541
|
}
|
|
7535
7542
|
});
|
|
7536
7543
|
}
|
|
@@ -1225,16 +1225,33 @@ function renderDebateBriefCard(msg, resolved) {
|
|
|
1225
1225
|
topicHtml += '<div class="debate-brief-context">' + escapeHtml(msg.context) + '</div>';
|
|
1226
1226
|
}
|
|
1227
1227
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1228
|
+
// Resolve mate avatars from matesList
|
|
1229
|
+
var mates = ctx.matesList ? ctx.matesList() : [];
|
|
1230
|
+
var mateMap = {};
|
|
1231
|
+
for (var mi = 0; mi < mates.length; mi++) {
|
|
1232
|
+
mateMap[mates[mi].id] = mates[mi];
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
var modMate = msg.moderatorId ? mateMap[msg.moderatorId] : null;
|
|
1236
|
+
var modAvatarSrc = modMate ? mateAvatarUrl(modMate, 24) : "";
|
|
1237
|
+
topicHtml += '<div class="debate-brief-moderator" style="display:flex;align-items:center;gap:8px;">' +
|
|
1238
|
+
iconHtml("mic") + ' <strong>Moderator:</strong> ';
|
|
1239
|
+
if (modAvatarSrc) {
|
|
1240
|
+
topicHtml += '<img src="' + escapeHtml(modAvatarSrc) + '" width="24" height="24" style="border-radius:50%;flex-shrink:0;">';
|
|
1241
|
+
}
|
|
1242
|
+
topicHtml += escapeHtml(msg.moderatorName || "Unknown") + '</div>';
|
|
1231
1243
|
|
|
1232
1244
|
topicHtml += '<div class="debate-brief-panelists-label">' + iconHtml("users") + ' <strong>Panelists:</strong></div>';
|
|
1233
1245
|
topicHtml += '<div class="debate-brief-panelists">';
|
|
1234
1246
|
if (msg.panelists) {
|
|
1235
1247
|
for (var i = 0; i < msg.panelists.length; i++) {
|
|
1236
1248
|
var p = msg.panelists[i];
|
|
1237
|
-
|
|
1249
|
+
var mate = p.mateId ? mateMap[p.mateId] : null;
|
|
1250
|
+
var avatarSrc = mate ? mateAvatarUrl(mate, 24) : "";
|
|
1251
|
+
topicHtml += '<div class="debate-brief-panelist" style="display:flex;align-items:center;gap:8px;">';
|
|
1252
|
+
if (avatarSrc) {
|
|
1253
|
+
topicHtml += '<img src="' + escapeHtml(avatarSrc) + '" width="24" height="24" style="border-radius:50%;flex-shrink:0;">';
|
|
1254
|
+
}
|
|
1238
1255
|
topicHtml += '<span class="debate-brief-panelist-name">' + escapeHtml(p.name || "Unknown") + '</span>';
|
|
1239
1256
|
if (p.role) {
|
|
1240
1257
|
topicHtml += '<span class="debate-brief-panelist-role">' + escapeHtml(p.role) + '</span>';
|
package/lib/sdk-bridge.js
CHANGED
|
@@ -2375,9 +2375,9 @@ function createSDKBridge(opts) {
|
|
|
2375
2375
|
includePartialMessages: true,
|
|
2376
2376
|
abortController: abortController,
|
|
2377
2377
|
canUseTool: opts.canUseTool || function (toolName, input) {
|
|
2378
|
-
var
|
|
2379
|
-
if (
|
|
2380
|
-
return Promise.resolve(
|
|
2378
|
+
var whitelisted = checkToolWhitelist(toolName, input);
|
|
2379
|
+
if (whitelisted) {
|
|
2380
|
+
return Promise.resolve(whitelisted);
|
|
2381
2381
|
}
|
|
2382
2382
|
return Promise.resolve({
|
|
2383
2383
|
behavior: "deny",
|
|
@@ -2386,6 +2386,7 @@ function createSDKBridge(opts) {
|
|
|
2386
2386
|
},
|
|
2387
2387
|
};
|
|
2388
2388
|
if (opts.model) mentionQueryOptions.model = opts.model;
|
|
2389
|
+
if (opts.includeMcpServers && mcpServers) mentionQueryOptions.mcpServers = mcpServers;
|
|
2389
2390
|
query = sdk.query({
|
|
2390
2391
|
prompt: mq,
|
|
2391
2392
|
options: mentionQueryOptions,
|
package/lib/server.js
CHANGED
|
@@ -15,6 +15,7 @@ var { CONFIG_DIR } = require("./config");
|
|
|
15
15
|
var { provisionLinuxUser } = require("./os-users");
|
|
16
16
|
|
|
17
17
|
var https = require("https");
|
|
18
|
+
var pkg = require("../package.json");
|
|
18
19
|
|
|
19
20
|
var publicDir = path.join(__dirname, "public");
|
|
20
21
|
var bundledThemesDir = path.join(__dirname, "themes");
|
|
@@ -1124,31 +1125,34 @@ function createServer(opts) {
|
|
|
1124
1125
|
return;
|
|
1125
1126
|
}
|
|
1126
1127
|
|
|
1127
|
-
// Health check endpoint
|
|
1128
|
+
// Health check endpoint
|
|
1129
|
+
// Unauthenticated: minimal liveness info only
|
|
1130
|
+
// Authenticated: full system details (memory, pid, version, sessions)
|
|
1128
1131
|
if (req.method === "GET" && fullUrl === "/api/health") {
|
|
1129
|
-
var mem = process.memoryUsage();
|
|
1130
|
-
var activeSessions = 0;
|
|
1131
|
-
projects.forEach(function (ctx) {
|
|
1132
|
-
if (ctx && ctx.clients) {
|
|
1133
|
-
activeSessions += ctx.clients.size || 0;
|
|
1134
|
-
}
|
|
1135
|
-
});
|
|
1136
|
-
var pkg = require("../package.json");
|
|
1137
1132
|
var health = {
|
|
1138
1133
|
status: "ok",
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1134
|
+
timestamp: new Date().toISOString(),
|
|
1135
|
+
};
|
|
1136
|
+
if (isRequestAuthed(req)) {
|
|
1137
|
+
var mem = process.memoryUsage();
|
|
1138
|
+
var activeSessions = 0;
|
|
1139
|
+
projects.forEach(function (ctx) {
|
|
1140
|
+
if (ctx && ctx.clients) {
|
|
1141
|
+
activeSessions += ctx.clients.size || 0;
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
health.uptime = process.uptime();
|
|
1145
|
+
health.version = pkg.version;
|
|
1146
|
+
health.node = process.version;
|
|
1147
|
+
health.sessions = activeSessions;
|
|
1148
|
+
health.projects = projects.size;
|
|
1149
|
+
health.memory = {
|
|
1145
1150
|
rss: mem.rss,
|
|
1146
1151
|
heapUsed: mem.heapUsed,
|
|
1147
1152
|
heapTotal: mem.heapTotal,
|
|
1148
|
-
}
|
|
1149
|
-
pid
|
|
1150
|
-
|
|
1151
|
-
};
|
|
1153
|
+
};
|
|
1154
|
+
health.pid = process.pid;
|
|
1155
|
+
}
|
|
1152
1156
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1153
1157
|
res.end(JSON.stringify(health));
|
|
1154
1158
|
return;
|
package/package.json
CHANGED