tuna-agent 0.1.81 → 0.1.83
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.
|
@@ -185,6 +185,22 @@ export class ClaudeCodeAdapter {
|
|
|
185
185
|
let firstChunkIso = '';
|
|
186
186
|
let turnAccumulatedText = '';
|
|
187
187
|
let messageCount = 0; // Track message_start events to detect new turns
|
|
188
|
+
let lastSentContent = ''; // Dedup: skip sending same/similar message twice
|
|
189
|
+
// Normalize text for similarity comparison (strip markdown, collapse whitespace)
|
|
190
|
+
const normalize = (s) => s.replace(/[#*_`~\-|>]/g, '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
191
|
+
const isSimilar = (a, b) => {
|
|
192
|
+
if (!a || !b)
|
|
193
|
+
return false;
|
|
194
|
+
const na = normalize(a), nb = normalize(b);
|
|
195
|
+
if (na === nb)
|
|
196
|
+
return true;
|
|
197
|
+
// Check if one contains the other (common with slight variations)
|
|
198
|
+
if (na.length > 20 && nb.length > 20) {
|
|
199
|
+
if (na.includes(nb) || nb.includes(na))
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
};
|
|
188
204
|
console.log(`[ClaudeCode] Agent Team round ${round + 1}: ${userMessage.substring(0, 80)}${currentInputFiles?.length ? ` (+${currentInputFiles.length} images)` : ''}`);
|
|
189
205
|
const defaultWorkspace = path.join(os.homedir(), 'tuna-workspace');
|
|
190
206
|
const cwd = task.repoPath || defaultWorkspace;
|
|
@@ -231,11 +247,18 @@ export class ClaudeCodeAdapter {
|
|
|
231
247
|
if (messageCount > 1 && turnAccumulatedText.trim()) {
|
|
232
248
|
console.log(`[ClaudeCode] ✂️ Splitting bubble — finalizing ${turnAccumulatedText.length} chars from previous turn`);
|
|
233
249
|
ws.sendPMStreamEnd(task.id, streamMsgId);
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
250
|
+
const simplified = simplifyMarkdown(turnAccumulatedText);
|
|
251
|
+
if (!isSimilar(simplified, lastSentContent)) {
|
|
252
|
+
ws.sendPMMessage(task.id, {
|
|
253
|
+
sender: 'pm',
|
|
254
|
+
content: simplified,
|
|
255
|
+
startedAt: firstChunkIso || undefined,
|
|
256
|
+
});
|
|
257
|
+
lastSentContent = simplified;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
console.log(`[ClaudeCode] ⏭️ Skipping duplicate message (${simplified.length} chars)`);
|
|
261
|
+
}
|
|
239
262
|
turnAccumulatedText = '';
|
|
240
263
|
firstChunkIso = '';
|
|
241
264
|
streamMsgId = `team-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -327,13 +350,20 @@ export class ClaudeCodeAdapter {
|
|
|
327
350
|
if (lastTaskOutput) {
|
|
328
351
|
console.log(`[Reflection] Captured ${lastTaskOutput.length} chars of task output for reflection`);
|
|
329
352
|
}
|
|
330
|
-
// Send finalized message for the last turn's remaining text
|
|
353
|
+
// Send finalized message for the last turn's remaining text (skip if duplicate)
|
|
331
354
|
if (turnAccumulatedText.trim()) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
355
|
+
const simplified = simplifyMarkdown(turnAccumulatedText);
|
|
356
|
+
if (!isSimilar(simplified, lastSentContent)) {
|
|
357
|
+
ws.sendPMMessage(task.id, {
|
|
358
|
+
sender: 'pm',
|
|
359
|
+
content: simplified,
|
|
360
|
+
startedAt: firstChunkIso || undefined,
|
|
361
|
+
});
|
|
362
|
+
lastSentContent = simplified;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
console.log(`[ClaudeCode] ⏭️ Skipping similar final message (${simplified.length} chars)`);
|
|
366
|
+
}
|
|
337
367
|
}
|
|
338
368
|
// Last round → close
|
|
339
369
|
if (round === MAX_ROUNDS - 1)
|
package/dist/cli/index.js
CHANGED
|
File without changes
|
|
File without changes
|