tuna-agent 0.1.180 → 0.1.181
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 +0 -2
- package/dist/executor/task-runner.js +3 -3
- package/dist/pm/planner.js +16 -8
- package/package.json +1 -1
package/dist/daemon/index.js
CHANGED
|
@@ -794,8 +794,6 @@ ${skillContent.slice(0, 15000)}`;
|
|
|
794
794
|
if (result.status === 'done' && !result.followUpMessage) {
|
|
795
795
|
const totalDuration = result.sessions.reduce((sum, s) => sum + (s.durationMs ?? 0), 0);
|
|
796
796
|
wsClient.sendTaskDone(taskId, { result: plan.summary, durationMs: totalDuration });
|
|
797
|
-
await new Promise(resolve => setTimeout(resolve, 150));
|
|
798
|
-
wsClient.sendPMMessage(taskId, { sender: 'pm', content: `Task completed.` });
|
|
799
797
|
}
|
|
800
798
|
else if (result.followUpMessage) {
|
|
801
799
|
userMessage = result.followUpMessage;
|
|
@@ -333,7 +333,7 @@ export async function executeSubtask(subtask, repoPath, contracts, callbacks, si
|
|
|
333
333
|
const result = await runClaude({
|
|
334
334
|
prompt: subtask.description,
|
|
335
335
|
cwd,
|
|
336
|
-
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep'],
|
|
336
|
+
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep', 'mcp__mem0', 'mcp__tuna-knowledge', 'mcp__tuna-idea', 'mcp__tuna-browser', 'mcp__appeeky'],
|
|
337
337
|
disallowedTools: ['AskUserQuestion'],
|
|
338
338
|
systemPrompt: buildSessionPrompt(subtask, contracts),
|
|
339
339
|
outputFormat: 'stream-json',
|
|
@@ -370,7 +370,7 @@ export async function executeSubtask(subtask, repoPath, contracts, callbacks, si
|
|
|
370
370
|
const resumeResult = await runClaude({
|
|
371
371
|
prompt: `The answer to your question "${question.question}" is: ${answer}\n\nContinue your work with this information.`,
|
|
372
372
|
cwd,
|
|
373
|
-
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep'],
|
|
373
|
+
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep', 'mcp__mem0', 'mcp__tuna-knowledge', 'mcp__tuna-idea', 'mcp__tuna-browser', 'mcp__appeeky'],
|
|
374
374
|
disallowedTools: ['AskUserQuestion'],
|
|
375
375
|
resumeSessionId: info.sessionId,
|
|
376
376
|
outputFormat: 'stream-json',
|
|
@@ -449,7 +449,7 @@ export async function executeSubtask(subtask, repoPath, contracts, callbacks, si
|
|
|
449
449
|
const resumeResult = await runClaude({
|
|
450
450
|
prompt: `The answer to your question "${fallbackQuestion.question}" is: ${answer}\n\nContinue your work with this information.`,
|
|
451
451
|
cwd,
|
|
452
|
-
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep'],
|
|
452
|
+
allowedTools: ['Read', 'Edit', 'Write', 'Bash', 'Glob', 'Grep', 'mcp__mem0', 'mcp__tuna-knowledge', 'mcp__tuna-idea', 'mcp__tuna-browser', 'mcp__appeeky'],
|
|
453
453
|
disallowedTools: ['AskUserQuestion'],
|
|
454
454
|
resumeSessionId: info.sessionId,
|
|
455
455
|
outputFormat: 'stream-json',
|
package/dist/pm/planner.js
CHANGED
|
@@ -144,7 +144,7 @@ export async function planTask(task, onProgress, signal, onTextChunk, inputFiles
|
|
|
144
144
|
const result = await runClaude({
|
|
145
145
|
prompt: userPrompt,
|
|
146
146
|
cwd,
|
|
147
|
-
allowedTools: ['Read', 'Glob', 'Grep'],
|
|
147
|
+
allowedTools: ['Read', 'Glob', 'Grep', 'mcp__mem0', 'mcp__tuna-knowledge', 'mcp__tuna-idea'],
|
|
148
148
|
systemPrompt,
|
|
149
149
|
maxTurns,
|
|
150
150
|
outputFormat: 'stream-json',
|
|
@@ -287,17 +287,20 @@ User message: ${userMessage}`;
|
|
|
287
287
|
let firstDeltaMs = 0;
|
|
288
288
|
let deltaCount = 0;
|
|
289
289
|
const cwd = repoPath || path.join(os.homedir(), 'tuna-workspace');
|
|
290
|
+
let streamedText = '';
|
|
290
291
|
const result = await runClaude({
|
|
291
292
|
prompt: chatPrompt,
|
|
292
293
|
cwd,
|
|
293
294
|
resumeSessionId: pmSessionId || undefined,
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
// Read-only tools + knowledge/memory MCP: follow-ups like "check the skill
|
|
296
|
+
// list" need to actually look at files. No tools + 1 turn made the model
|
|
297
|
+
// attempt a tool call anyway and come back with an EMPTY result (silent task).
|
|
298
|
+
allowedTools: ['Read', 'Glob', 'Grep', 'mcp__mem0', 'mcp__tuna-knowledge', 'mcp__tuna-idea'],
|
|
299
|
+
maxTurns: 8,
|
|
297
300
|
outputFormat: 'stream-json',
|
|
298
301
|
includePartialMessages: true,
|
|
299
302
|
inputFiles,
|
|
300
|
-
onStreamLine:
|
|
303
|
+
onStreamLine: (data) => {
|
|
301
304
|
// Parse stream_event → content_block_delta for real token streaming
|
|
302
305
|
if (data.type === 'stream_event') {
|
|
303
306
|
const event = data.event;
|
|
@@ -305,15 +308,16 @@ User message: ${userMessage}`;
|
|
|
305
308
|
const delta = event.delta;
|
|
306
309
|
if (delta?.type === 'text_delta' && delta.text) {
|
|
307
310
|
deltaCount++;
|
|
311
|
+
streamedText += delta.text;
|
|
308
312
|
if (!firstDeltaMs) {
|
|
309
313
|
firstDeltaMs = Date.now();
|
|
310
314
|
console.log(`[PM] ⏱ first text delta: ${firstDeltaMs - chatStartMs}ms after chat start`);
|
|
311
315
|
}
|
|
312
|
-
onTextChunk(delta.text);
|
|
316
|
+
onTextChunk?.(delta.text);
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
}
|
|
316
|
-
}
|
|
320
|
+
},
|
|
317
321
|
signal,
|
|
318
322
|
});
|
|
319
323
|
const chatDoneMs = Date.now();
|
|
@@ -321,7 +325,11 @@ User message: ${userMessage}`;
|
|
|
321
325
|
if (result.isError) {
|
|
322
326
|
return { response: `Sorry, I encountered an error: ${result.result}`, sessionId: result.sessionId };
|
|
323
327
|
}
|
|
324
|
-
|
|
328
|
+
// A hit turn-cap (or odd stop) can yield an empty `result` even though text was
|
|
329
|
+
// streamed. Never return empty — a silent agent looks dead to the user.
|
|
330
|
+
const rawResult = result.result?.trim()
|
|
331
|
+
|| streamedText.trim()
|
|
332
|
+
|| 'Xin lỗi anh, phiên xử lý tin nhắn vừa rồi bị nghẽn (không có output). Anh nhắn lại giúp nhé.';
|
|
325
333
|
// Try extracting JSON plan
|
|
326
334
|
let jsonStr = null;
|
|
327
335
|
const codeBlockMatch = rawResult.match(/```(?:json)?\s*(\{[\s\S]*?"subtasks"[\s\S]*?\})\s*```/);
|