tuna-agent 0.1.100 → 0.1.102
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/daemon/index.js +46 -14
- package/package.json +1 -1
package/dist/daemon/index.js
CHANGED
|
@@ -461,8 +461,17 @@ ${skillContent.slice(0, 15000)}`;
|
|
|
461
461
|
// Check per-agent concurrency before resuming
|
|
462
462
|
const resumeAgentId = savedState.agentId || '__default__';
|
|
463
463
|
if (activeAgentTasks.has(resumeAgentId)) {
|
|
464
|
-
|
|
465
|
-
|
|
464
|
+
const busyTask = activeAgentTasks.get(resumeAgentId);
|
|
465
|
+
console.warn(`[Daemon] Cannot resume task ${taskId} — agent ${resumeAgentId} is busy with task ${busyTask}`);
|
|
466
|
+
// Notify user and revert task status so it doesn't get stuck at "executing"
|
|
467
|
+
ws.sendPMMessage(taskId, {
|
|
468
|
+
sender: 'pm',
|
|
469
|
+
content: 'Agent is currently busy with another task. Please try again shortly.',
|
|
470
|
+
});
|
|
471
|
+
ws.sendTaskDone(taskId, {
|
|
472
|
+
result: 'Agent busy — message not processed',
|
|
473
|
+
durationMs: 0,
|
|
474
|
+
});
|
|
466
475
|
break;
|
|
467
476
|
}
|
|
468
477
|
if (savedState.mode === 'agent_team') {
|
|
@@ -871,21 +880,44 @@ ${skillContent.slice(0, 15000)}`;
|
|
|
871
880
|
continue; // retry this round without --resume
|
|
872
881
|
}
|
|
873
882
|
// Send finalized message for the last turn's remaining text
|
|
883
|
+
// Skip if content is same as task result (avoid duplicate in chat + session)
|
|
884
|
+
const simplifiedResult = simplifyMarkdown(result.result);
|
|
885
|
+
const normalizeForCompare = (s) => s.replace(/[#*_`~\-|>]/g, '').replace(/\s+/g, ' ').trim().toLowerCase();
|
|
886
|
+
const isSameAsResult = (text) => {
|
|
887
|
+
const a = normalizeForCompare(text), b = normalizeForCompare(simplifiedResult);
|
|
888
|
+
if (!a || !b)
|
|
889
|
+
return false;
|
|
890
|
+
if (a === b)
|
|
891
|
+
return true;
|
|
892
|
+
if (a.length > 20 && b.length > 20 && (a.includes(b) || b.includes(a)))
|
|
893
|
+
return true;
|
|
894
|
+
return false;
|
|
895
|
+
};
|
|
874
896
|
if (turnAccumulatedText.trim()) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
897
|
+
const simplified = simplifyMarkdown(turnAccumulatedText);
|
|
898
|
+
if (!isSameAsResult(simplified)) {
|
|
899
|
+
wsClient.sendPMMessage(taskId, {
|
|
900
|
+
sender: 'pm',
|
|
901
|
+
content: simplified,
|
|
902
|
+
startedAt: firstChunkIso || undefined,
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
console.log(`[Daemon] ⏭️ Skipping resume final message (duplicate of task result, ${simplified.length} chars)`);
|
|
907
|
+
}
|
|
880
908
|
}
|
|
881
909
|
else if (resultText.length > 0 && messageCount === 0) {
|
|
882
|
-
// No stream events but CLI returned a result
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
910
|
+
// No stream events but CLI returned a result — skip if same as task result
|
|
911
|
+
if (!isSameAsResult(resultText)) {
|
|
912
|
+
console.log(`[Daemon] No stream events but got result (${resultText.length} chars) — sending as message`);
|
|
913
|
+
wsClient.sendPMMessage(taskId, {
|
|
914
|
+
sender: 'pm',
|
|
915
|
+
content: simplifyMarkdown(resultText),
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
else {
|
|
919
|
+
console.log(`[Daemon] ⏭️ Skipping no-stream result message (duplicate of task result, ${resultText.length} chars)`);
|
|
920
|
+
}
|
|
889
921
|
}
|
|
890
922
|
lastResumeOutput = turnAccumulatedText.trim() || resultText || lastResumeOutput;
|
|
891
923
|
if (result.isError) {
|