fix: TodoWrite-Tool über CLI korrekt als Todo-Liste rendern
TodoWrite → todo_write Mapping in Backend und Frontend ergänzt. Todo-Liste wird jetzt aus dem Input-Array gebaut statt aus dem Result, da die CLI nur einen generischen Erfolgstext zurückgibt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2494ca89b8
commit
9c507e4716
2 files changed
+67
-3
No files matched your search
@@ -340,6 +340,7 @@ public partial class AnthropicService
|
|||||||
"WebSearch" => "web_search",
|
"WebSearch" => "web_search",
|
||||||
"WebFetch" => "web_fetch",
|
"WebFetch" => "web_fetch",
|
||||||
"NotebookEdit" => "notebook_edit",
|
"NotebookEdit" => "notebook_edit",
|
||||||
|
"TodoWrite" => "todo_write",
|
||||||
_ => cliName?.StartsWith("mcp__") == true ? cliName.Split("__").LastOrDefault() ?? cliName : cliName
|
_ => cliName?.StartsWith("mcp__") == true ? cliName.Split("__").LastOrDefault() ?? cliName : cliName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-3
@@ -10,6 +10,7 @@ const CLI_TOOL_NAME_MAP = {
|
|||||||
'WebSearch': 'web_search',
|
'WebSearch': 'web_search',
|
||||||
'WebFetch': 'web_fetch',
|
'WebFetch': 'web_fetch',
|
||||||
'NotebookEdit': 'notebook_edit',
|
'NotebookEdit': 'notebook_edit',
|
||||||
|
'TodoWrite': 'todo_write',
|
||||||
'ToolSearch': 'tool_search',
|
'ToolSearch': 'tool_search',
|
||||||
'mcp__gott-remote__remote_execute': 'remote_execute'
|
'mcp__gott-remote__remote_execute': 'remote_execute'
|
||||||
};
|
};
|
||||||
@@ -195,8 +196,13 @@ function renderToolBoxContent(div, rawName, inputJson, result, isError, sources)
|
|||||||
foldTarget = preview;
|
foldTarget = preview;
|
||||||
|
|
||||||
} else if (name === 'todo_write') {
|
} else if (name === 'todo_write') {
|
||||||
// Todo-Liste: kein tool-input, standardmäßig sichtbar, custom parser
|
// Todo-Liste: aus Input bauen (CLI hat nur generisches Result, API formatiert Result)
|
||||||
if (result) {
|
// Priorität: parsedInput.todos (immer vorhanden) > result (nur bei API-Pfad formatiert)
|
||||||
|
if (parsedInput && parsedInput.todos && Array.isArray(parsedInput.todos)) {
|
||||||
|
const todoList = buildTodoListFromInput(parsedInput.todos, isError);
|
||||||
|
div.appendChild(todoList);
|
||||||
|
foldTarget = todoList;
|
||||||
|
} else if (result) {
|
||||||
const todoList = buildTodoList(result, isError);
|
const todoList = buildTodoList(result, isError);
|
||||||
div.appendChild(todoList);
|
div.appendChild(todoList);
|
||||||
foldTarget = todoList;
|
foldTarget = todoList;
|
||||||
@@ -325,6 +331,52 @@ function buildTodoList(result, isError) {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Baut Todo-Liste direkt aus dem Input-Array (für CLI-Pfad, wo Result nur generischer Text ist). */
|
||||||
|
function buildTodoListFromInput(todos, isError) {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.className = 'todo-list' + (isError ? ' tool-error' : '');
|
||||||
|
|
||||||
|
for (var i = 0; i < todos.length; i++) {
|
||||||
|
const todo = todos[i];
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'todo-item';
|
||||||
|
|
||||||
|
const status = todo.status || 'pending';
|
||||||
|
const icon = status === 'completed' ? '✅' : status === 'in_progress' ? '🔄' : '⬜';
|
||||||
|
const statusClass = status === 'completed' ? 'todo-done' : status === 'in_progress' ? 'todo-progress' : 'todo-pending';
|
||||||
|
row.classList.add(statusClass);
|
||||||
|
|
||||||
|
const iconSpan = document.createElement('span');
|
||||||
|
iconSpan.className = 'todo-icon';
|
||||||
|
iconSpan.textContent = icon;
|
||||||
|
|
||||||
|
const idSpan = document.createElement('span');
|
||||||
|
idSpan.className = 'todo-id';
|
||||||
|
idSpan.textContent = (todo.id || (i + 1)) + '.';
|
||||||
|
|
||||||
|
const textSpan = document.createElement('span');
|
||||||
|
textSpan.className = 'todo-text';
|
||||||
|
// CLI hat "activeForm" statt nur "content" – zeige content (Imperativ-Form)
|
||||||
|
textSpan.textContent = todo.content || todo.activeForm || '';
|
||||||
|
|
||||||
|
row.appendChild(iconSpan);
|
||||||
|
row.appendChild(idSpan);
|
||||||
|
row.appendChild(textSpan);
|
||||||
|
|
||||||
|
if (todo.priority) {
|
||||||
|
const prioSpan = document.createElement('span');
|
||||||
|
prioSpan.className = 'todo-prio todo-prio-' + todo.priority.toLowerCase();
|
||||||
|
prioSpan.textContent = todo.priority;
|
||||||
|
row.appendChild(prioSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.appendChild(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseFluentEmojis(container);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
function finishToolBox(div, data) {
|
function finishToolBox(div, data) {
|
||||||
if (!div) return;
|
if (!div) return;
|
||||||
renderToolBoxContent(div, data.name, data.input, data.result, data.isError, data.sources);
|
renderToolBoxContent(div, data.name, data.input, data.result, data.isError, data.sources);
|
||||||
@@ -334,10 +386,21 @@ function finishToolBox(div, data) {
|
|||||||
/** Fügt ein Tool-Result nachträglich an eine bestehende Tool-Box an (CLI tool_result Events). */
|
/** Fügt ein Tool-Result nachträglich an eine bestehende Tool-Box an (CLI tool_result Events). */
|
||||||
function appendToolResult(div, result, isError) {
|
function appendToolResult(div, result, isError) {
|
||||||
if (!div || !result) return;
|
if (!div || !result) return;
|
||||||
|
var toolName = div.dataset.toolName;
|
||||||
|
|
||||||
|
// todo_write: Liste wurde bereits aus Input gebaut (in renderToolBoxContent)
|
||||||
|
if (toolName === 'todo_write') {
|
||||||
|
if (div.querySelector('.todo-list')) return; // Bereits vorhanden
|
||||||
|
// Fallback: versuche aus Result zu parsen (API-Pfad)
|
||||||
|
var todoList = buildTodoList(result, isError);
|
||||||
|
div.appendChild(todoList);
|
||||||
|
scrollDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Nur anfügen wenn noch kein Result vorhanden
|
// Nur anfügen wenn noch kein Result vorhanden
|
||||||
if (div.querySelector('.tool-result')) return;
|
if (div.querySelector('.tool-result')) return;
|
||||||
// Bei edit_file/write_file: Diff reicht, kein extra Result nötig
|
// Bei edit_file/write_file: Diff reicht, kein extra Result nötig
|
||||||
var toolName = div.dataset.toolName;
|
|
||||||
if (toolName === 'edit_file' || toolName === 'write_file') return;
|
if (toolName === 'edit_file' || toolName === 'write_file') return;
|
||||||
|
|
||||||
var rd = document.createElement('div');
|
var rd = document.createElement('div');
|
||||||
|
|||||||
Reference in new issue
Block a user