mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-08 03:07:53 +00:00
fix: preserve todo metadata on updateTodoList
Prefer history todos when they contain subtaskId/tokens/cost so updateTodoList preserves injected metadata. Adds regression test covering history-vs-memory selection.
This commit is contained in:
parent
5bead50ced
commit
188a1c6e8e
2 changed files with 70 additions and 6 deletions
|
|
@ -26,11 +26,23 @@ export class UpdateTodoListTool extends BaseTool<"update_todo_list"> {
|
|||
const { pushToolResult, handleError, askApproval, toolProtocol } = callbacks
|
||||
|
||||
try {
|
||||
// Pull the previous todo list so we can preserve metadata fields across update_todo_list calls.
|
||||
// Prefer the in-memory task.todoList when available; otherwise fall back to the latest todo list
|
||||
// stored in the conversation history.
|
||||
const previousTodos =
|
||||
getTodoListForTask(task) ?? (getLatestTodo(task.clineMessages) as unknown as TodoItem[])
|
||||
const previousFromMemory = getTodoListForTask(task)
|
||||
const previousFromHistory = getLatestTodo(task.clineMessages) as unknown as TodoItem[] | undefined
|
||||
|
||||
const historyHasMetadata =
|
||||
Array.isArray(previousFromHistory) &&
|
||||
previousFromHistory.some(
|
||||
(t) => t?.subtaskId !== undefined || t?.tokens !== undefined || t?.cost !== undefined,
|
||||
)
|
||||
|
||||
const previousTodos: TodoItem[] =
|
||||
(previousFromMemory?.length ?? 0) === 0
|
||||
? (previousFromHistory ?? [])
|
||||
: (previousFromHistory?.length ?? 0) === 0
|
||||
? (previousFromMemory ?? [])
|
||||
: historyHasMetadata
|
||||
? (previousFromHistory ?? [])
|
||||
: (previousFromMemory ?? [])
|
||||
|
||||
const todosRaw = params.todos
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, it, expect, beforeEach, vi } from "vitest"
|
||||
import { parseMarkdownChecklist } from "../UpdateTodoListTool"
|
||||
import { parseMarkdownChecklist, UpdateTodoListTool, setPendingTodoList } from "../UpdateTodoListTool"
|
||||
import { TodoItem } from "@roo-code/types"
|
||||
|
||||
describe("parseMarkdownChecklist", () => {
|
||||
|
|
@ -241,3 +241,55 @@ Just some text
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("UpdateTodoListTool.execute", () => {
|
||||
beforeEach(() => {
|
||||
setPendingTodoList([])
|
||||
})
|
||||
|
||||
it("should prefer history todos when they contain metadata (subtaskId/tokens/cost)", async () => {
|
||||
const md = "[ ] Task 1"
|
||||
|
||||
const previousFromMemory = parseMarkdownChecklist(md)
|
||||
const previousFromHistory: TodoItem[] = previousFromMemory.map((t) => ({
|
||||
...t,
|
||||
subtaskId: "subtask-1",
|
||||
tokens: 123,
|
||||
cost: 0.01,
|
||||
}))
|
||||
|
||||
const task = {
|
||||
todoList: previousFromMemory,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "ask",
|
||||
ask: "tool",
|
||||
text: JSON.stringify({ tool: "updateTodoList", todos: previousFromHistory }),
|
||||
},
|
||||
],
|
||||
consecutiveMistakeCount: 0,
|
||||
recordToolError: vi.fn(),
|
||||
didToolFailInCurrentTurn: false,
|
||||
say: vi.fn(),
|
||||
} as any
|
||||
|
||||
const tool = new UpdateTodoListTool()
|
||||
await tool.execute({ todos: md }, task, {
|
||||
pushToolResult: vi.fn(),
|
||||
handleError: vi.fn(),
|
||||
askApproval: vi.fn().mockResolvedValue(true),
|
||||
removeClosingTag: vi.fn(),
|
||||
toolProtocol: "xml",
|
||||
})
|
||||
|
||||
expect(task.todoList).toHaveLength(1)
|
||||
expect(task.todoList[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
content: "Task 1",
|
||||
subtaskId: "subtask-1",
|
||||
tokens: 123,
|
||||
cost: 0.01,
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue