todo_write: rename the items param to todos

A top-level arguments key named "items" shadows minijinja's .items() in Together's GLM-5.2 chat template — every replayed turn 400s.
Old key still executes; GUI renders both; regression tests added.
This commit is contained in:
Rohit C Prasad
2026-07-21 15:45:26 -07:00
parent 76224a06d3
commit dc8e7b6fe8
5 changed files with 58 additions and 10 deletions
+2 -1
View File
@@ -554,7 +554,8 @@ export function App() {
setStreaming(""); // finalized into items (or empty tool-only turn)
break;
case "tool_proposed":
if (d.name === "todo_write" && d.arguments?.items) setTodo(normalizeTodos(d.arguments.items));
if (d.name === "todo_write" && (d.arguments?.todos || d.arguments?.items))
setTodo(normalizeTodos(d.arguments.todos ?? d.arguments.items));
setItems((p) => [
...p,
{ kind: "tool", id: newId(), name: d.name, args: d.arguments, status: "…" },
@@ -195,9 +195,14 @@ describe("humanizeTool", () => {
});
it("summarizes todo_write by its single item and status", () => {
const line = humanizeTool("todo_write", { items: [{ content: "Post the digest", status: "in_progress" }] });
const line = humanizeTool("todo_write", { todos: [{ content: "Post the digest", status: "in_progress" }] });
expect(line.pre).toBe("Updated the plan — ");
expect(line.obj).toContain("Post the digest");
expect(line.post).toBe(" → in progress");
});
it("still renders pre-rename todo_write histories (legacy `items` key)", () => {
const line = humanizeTool("todo_write", { items: [{ content: "Old plan", status: "pending" }] });
expect(line.obj).toContain("Old plan");
});
});
+3 -1
View File
@@ -56,7 +56,9 @@ export function humanizeTool(name: string, args: any): HumanLine {
case "git_log":
return { pre: "Looked through recent git history" };
case "todo_write": {
const items = Array.isArray(a.items) ? a.items : [];
// `todos` is current; `items` renders histories from before the rename (the old
// key breaks Together's GLM-5.2 chat template — see coworker/tools/todo.py).
const items = Array.isArray(a.todos) ? a.todos : Array.isArray(a.items) ? a.items : [];
if (items.length === 1) {
const it = items[0] || {};
const status = String(it.status || "").replace(/_/g, " ");