tuna-agent 0.1.104 → 0.1.106
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.
|
@@ -350,12 +350,13 @@ export class ClaudeCodeAdapter {
|
|
|
350
350
|
// Send finalized message for the last turn's remaining text (skip if duplicate)
|
|
351
351
|
// Fallback: if no streaming deltas were captured (e.g. agent_team mode may emit
|
|
352
352
|
// complete assistant messages instead of stream_event deltas), use result.result
|
|
353
|
+
// Always send pm_message for DB persistence — pm_stream is fire-and-forget
|
|
354
|
+
// (not saved to DB), so this is the only way to persist the response.
|
|
355
|
+
// Still skip if duplicate of last SENT message (multi-turn dedup).
|
|
353
356
|
const finalText = turnAccumulatedText.trim() || result.result;
|
|
354
357
|
if (finalText) {
|
|
355
358
|
const simplified = simplifyMarkdown(finalText);
|
|
356
|
-
|
|
357
|
-
// Skip if similar to last sent content OR to task result (avoid duplicate in chat + session)
|
|
358
|
-
if (!isSimilar(simplified, lastSentContent) && !isSimilar(simplified, simplifiedResult)) {
|
|
359
|
+
if (!isSimilar(simplified, lastSentContent)) {
|
|
359
360
|
ws.sendPMMessage(task.id, {
|
|
360
361
|
sender: 'pm',
|
|
361
362
|
content: simplified,
|
|
@@ -364,7 +365,7 @@ export class ClaudeCodeAdapter {
|
|
|
364
365
|
lastSentContent = simplified;
|
|
365
366
|
}
|
|
366
367
|
else {
|
|
367
|
-
console.log(`[ClaudeCode] ⏭️ Skipping final message (duplicate of
|
|
368
|
+
console.log(`[ClaudeCode] ⏭️ Skipping final message (duplicate of last sent, ${simplified.length} chars)`);
|
|
368
369
|
}
|
|
369
370
|
}
|
|
370
371
|
// Last round → close
|
package/dist/daemon/index.js
CHANGED
|
@@ -267,6 +267,22 @@ export async function startDaemon(config) {
|
|
|
267
267
|
}
|
|
268
268
|
break;
|
|
269
269
|
}
|
|
270
|
+
case 'task_interrupted': {
|
|
271
|
+
const taskId = msg.taskId;
|
|
272
|
+
console.log(`[Daemon] Task interrupted: ${taskId}`);
|
|
273
|
+
// Kill the running process but preserve PM state so next message can resume the session
|
|
274
|
+
const interruptAbort = taskAbortControllers.get(taskId);
|
|
275
|
+
if (interruptAbort) {
|
|
276
|
+
interruptAbort.abort();
|
|
277
|
+
console.log(`[Daemon] Aborted running task ${taskId} (state preserved for resume)`);
|
|
278
|
+
}
|
|
279
|
+
const interruptResolver = pendingInputResolvers.get(taskId);
|
|
280
|
+
if (interruptResolver) {
|
|
281
|
+
interruptResolver({ text: '__TASK_CANCELLED__' });
|
|
282
|
+
pendingInputResolvers.delete(taskId);
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
270
286
|
case 'command': {
|
|
271
287
|
const command = msg.command;
|
|
272
288
|
if (command === 'rescan_agent_skills') {
|
|
@@ -906,31 +922,22 @@ ${skillContent.slice(0, 15000)}`;
|
|
|
906
922
|
return true;
|
|
907
923
|
return false;
|
|
908
924
|
};
|
|
925
|
+
// Always send pm_message for DB persistence — pm_stream is fire-and-forget
|
|
926
|
+
// (not saved to DB), so this is the only way to persist the response.
|
|
909
927
|
if (turnAccumulatedText.trim()) {
|
|
910
928
|
const simplified = simplifyMarkdown(turnAccumulatedText);
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
});
|
|
917
|
-
}
|
|
918
|
-
else {
|
|
919
|
-
console.log(`[Daemon] ⏭️ Skipping resume final message (duplicate of task result, ${simplified.length} chars)`);
|
|
920
|
-
}
|
|
929
|
+
wsClient.sendPMMessage(taskId, {
|
|
930
|
+
sender: 'pm',
|
|
931
|
+
content: simplified,
|
|
932
|
+
startedAt: firstChunkIso || undefined,
|
|
933
|
+
});
|
|
921
934
|
}
|
|
922
|
-
else if (resultText.length > 0
|
|
923
|
-
// No stream events but CLI returned a result
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
content: simplifyMarkdown(resultText),
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
else {
|
|
932
|
-
console.log(`[Daemon] ⏭️ Skipping no-stream result message (duplicate of task result, ${resultText.length} chars)`);
|
|
933
|
-
}
|
|
935
|
+
else if (resultText.length > 0) {
|
|
936
|
+
// No stream events but CLI returned a result
|
|
937
|
+
wsClient.sendPMMessage(taskId, {
|
|
938
|
+
sender: 'pm',
|
|
939
|
+
content: simplifyMarkdown(resultText),
|
|
940
|
+
});
|
|
934
941
|
}
|
|
935
942
|
lastResumeOutput = turnAccumulatedText.trim() || resultText || lastResumeOutput;
|
|
936
943
|
if (result.isError) {
|