clay-server 2.35.0 → 2.35.1-beta.1
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-mate-interaction.js +40 -22
- package/package.json +1 -1
|
@@ -27,47 +27,65 @@ function attachMateInteraction(ctx) {
|
|
|
27
27
|
// it comes from the debate module initialized after this one.
|
|
28
28
|
|
|
29
29
|
// --- @Mention handler ---
|
|
30
|
-
var MENTION_WINDOW = 20; // turns to check for session continuity
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
var MENTION_WINDOW = 20; // turns to check for session continuity (recency check only)
|
|
31
|
+
var MENTION_CONTEXT_BUDGET = 32 * 1024; // 32KB total budget for prior turns fed into mention context
|
|
32
|
+
var MENTION_CONTEXT_MAX_TURNS = 200; // hard safety cap so we never walk the entire session
|
|
33
|
+
|
|
34
|
+
// Walk session history backwards collecting full turns (no per-turn truncation)
|
|
35
|
+
// until either maxTurns is reached or byteBudget is exhausted. Each turn keeps
|
|
36
|
+
// its full text; we drop older turns first when the budget runs out.
|
|
37
|
+
function getRecentTurns(session, maxTurns, byteBudget) {
|
|
33
38
|
var turns = [];
|
|
39
|
+
var totalBytes = 0;
|
|
34
40
|
var history = session.history;
|
|
35
|
-
// Walk backwards through history, collect user/assistant/mention text turns
|
|
36
41
|
var assistantBuffer = "";
|
|
37
|
-
|
|
42
|
+
|
|
43
|
+
function tryPush(turn) {
|
|
44
|
+
var size = (turn.text || "").length + (turn.role || "").length + 4;
|
|
45
|
+
// Always keep at least one turn so a single long message still gets through.
|
|
46
|
+
if (byteBudget && turns.length > 0 && totalBytes + size > byteBudget) return false;
|
|
47
|
+
turns.push(turn);
|
|
48
|
+
totalBytes += size;
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (var i = history.length - 1; i >= 0 && turns.length < maxTurns; i--) {
|
|
38
53
|
var entry = history[i];
|
|
39
54
|
if (entry.type === "user_message") {
|
|
40
55
|
if (assistantBuffer) {
|
|
41
|
-
|
|
56
|
+
if (!tryPush({ role: "assistant", text: assistantBuffer.trim() })) { assistantBuffer = ""; break; }
|
|
42
57
|
assistantBuffer = "";
|
|
43
58
|
}
|
|
44
|
-
|
|
59
|
+
if (!tryPush({ role: "user", text: entry.text || "" })) break;
|
|
45
60
|
} else if (entry.type === "delta" || entry.type === "text") {
|
|
46
61
|
assistantBuffer = (entry.text || "") + assistantBuffer;
|
|
47
62
|
} else if (entry.type === "mention_response") {
|
|
48
63
|
if (assistantBuffer) {
|
|
49
|
-
|
|
64
|
+
if (!tryPush({ role: "assistant", text: assistantBuffer.trim() })) { assistantBuffer = ""; break; }
|
|
50
65
|
assistantBuffer = "";
|
|
51
66
|
}
|
|
52
|
-
|
|
67
|
+
if (!tryPush({ role: "@" + (entry.mateName || "Mate"), text: entry.text || "", mateId: entry.mateId })) break;
|
|
53
68
|
} else if (entry.type === "mention_user") {
|
|
54
69
|
if (assistantBuffer) {
|
|
55
|
-
|
|
70
|
+
if (!tryPush({ role: "assistant", text: assistantBuffer.trim() })) { assistantBuffer = ""; break; }
|
|
56
71
|
assistantBuffer = "";
|
|
57
72
|
}
|
|
58
|
-
|
|
73
|
+
if (!tryPush({ role: "user", text: "@" + (entry.mateName || "Mate") + " " + (entry.text || ""), mateId: entry.mateId })) break;
|
|
59
74
|
}
|
|
60
75
|
}
|
|
61
|
-
if (assistantBuffer) {
|
|
62
|
-
|
|
76
|
+
if (assistantBuffer && turns.length < maxTurns) {
|
|
77
|
+
tryPush({ role: "assistant", text: assistantBuffer.trim() });
|
|
63
78
|
}
|
|
64
79
|
turns.reverse();
|
|
65
80
|
return turns;
|
|
66
81
|
}
|
|
67
82
|
|
|
68
|
-
// Check if the given mate has a mention response
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
// Check if the given mate has a mention response within the most recent
|
|
84
|
+
// `windowSize` turns. Continuity is recency-based, even when getRecentTurns
|
|
85
|
+
// returns more turns to satisfy the byte budget.
|
|
86
|
+
function hasMateInWindow(recentTurns, mateId, windowSize) {
|
|
87
|
+
var start = windowSize ? Math.max(0, recentTurns.length - windowSize) : 0;
|
|
88
|
+
for (var i = start; i < recentTurns.length; i++) {
|
|
71
89
|
if (recentTurns[i].mateId === mateId && recentTurns[i].role.charAt(0) === "@") {
|
|
72
90
|
return true;
|
|
73
91
|
}
|
|
@@ -83,11 +101,11 @@ function attachMateInteraction(ctx) {
|
|
|
83
101
|
var t = recentTurns[i];
|
|
84
102
|
if (t.mateId === mateId && t.role.charAt(0) === "@") { found = true; break; }
|
|
85
103
|
if (t.role === "user") {
|
|
86
|
-
lines.unshift("[User said after your last reply: " + t.text
|
|
104
|
+
lines.unshift("[User said after your last reply: " + t.text + "]");
|
|
87
105
|
} else if (t.role === "assistant") {
|
|
88
|
-
lines.unshift("[Session agent replied: " + t.text
|
|
106
|
+
lines.unshift("[Session agent replied: " + t.text + "]");
|
|
89
107
|
} else if (t.role.charAt(0) === "@") {
|
|
90
|
-
lines.unshift("[@" + t.role.substring(1) + " replied: " + t.text
|
|
108
|
+
lines.unshift("[@" + t.role.substring(1) + " replied: " + t.text + "]");
|
|
91
109
|
}
|
|
92
110
|
}
|
|
93
111
|
if (!found || lines.length === 0) return "";
|
|
@@ -101,7 +119,7 @@ function attachMateInteraction(ctx) {
|
|
|
101
119
|
for (var i = 0; i < recentTurns.length; i++) {
|
|
102
120
|
var t = recentTurns[i];
|
|
103
121
|
var label = t.role === "user" ? userName : t.role === "assistant" ? "Session Agent" : t.role;
|
|
104
|
-
lines.push(label + ": " + t.text
|
|
122
|
+
lines.push(label + ": " + t.text);
|
|
105
123
|
}
|
|
106
124
|
return lines.join("\n") + "\n\n";
|
|
107
125
|
}
|
|
@@ -512,7 +530,7 @@ function attachMateInteraction(ctx) {
|
|
|
512
530
|
sendToSessionOthers(ws, session.localId, hydrateImageRefs(mentionUserEntry));
|
|
513
531
|
|
|
514
532
|
// Extract recent turns for continuity check
|
|
515
|
-
var recentTurns = getRecentTurns(session,
|
|
533
|
+
var recentTurns = getRecentTurns(session, MENTION_CONTEXT_MAX_TURNS, MENTION_CONTEXT_BUDGET);
|
|
516
534
|
|
|
517
535
|
// Determine user name for context
|
|
518
536
|
var userName = "User";
|
|
@@ -612,7 +630,7 @@ function attachMateInteraction(ctx) {
|
|
|
612
630
|
// Session continuity: check if this mate has a response in the recent window
|
|
613
631
|
var existingSession = session._mentionSessions[msg.mateId];
|
|
614
632
|
// Don't reuse a session that's still generating a digest (would mix digest output into mention stream)
|
|
615
|
-
var canContinue = existingSession && existingSession.isAlive() && !existingSession._digesting && hasMateInWindow(recentTurns, msg.mateId);
|
|
633
|
+
var canContinue = existingSession && existingSession.isAlive() && !existingSession._digesting && hasMateInWindow(recentTurns, msg.mateId, MENTION_WINDOW);
|
|
616
634
|
|
|
617
635
|
if (canContinue) {
|
|
618
636
|
// Continue existing mention session with middle context
|