Skip to content

fix(tools): harden UpdateTodoList for local LLM task JSON quirks#548

Closed
JessicaMulein wants to merge 1 commit into
cecli-dev:mainfrom
Digital-Defiance:pr/update-todo-list-json
Closed

fix(tools): harden UpdateTodoList for local LLM task JSON quirks#548
JessicaMulein wants to merge 1 commit into
cecli-dev:mainfrom
Digital-Defiance:pr/update-todo-list-json

Conversation

@JessicaMulein
Copy link
Copy Markdown

Summary

Hardens UpdateTodoList so local models can pass tasks as a JSON string, char-split arrays, or brace-prefixed strings without breaking format_output or writing garbage one-character “tasks” to todo.txt.

Problem

On Ollama and similar local models we routinely see:

  • tasks passed as a JSON string instead of a parsed array
  • Character-split “arrays” from the model
  • Strings that start with { but are not valid JSON

main already has normalize_json_array() in cecli.tools.utils.helpers (used by Grep and others), but UpdateTodoList still used naive json.loads + a loop that treated each character as a task in format_output.

Solution

  • normalize_task_items() / format_task_lines() — shared coercion for execute and format_output
  • coerce_task_item() — dict passthrough; invalid {…} strings fall back to plain task text
  • format_outputjson.loads guard; surface ToolError from normalization instead of silent corruption
  • LIST_PARAMS = ["tasks"] preserved for base tool list handling

Tests

New file: tests/tools/test_update_todo_list.py (7 cases)

Test Covers
test_normalize_task_items_does_not_split_characters Char-split regression
test_format_task_lines_accepts_json_string Tasks as embedded JSON string
test_format_output_accepts_tasks_as_json_string End-to-end format_output
test_format_output_reports_invalid_tasks_json Clear error on bad tasks
test_coerce_task_item_plain_string_starting_with_brace Invalid { prefix fallback
pytest tests/tools/test_update_todo_list.py -v
# 7 passed (local run)

pytest tests/helpers/monorepo -q
# 24 passed — no monorepo regression on this branch

Scope

In scope: cecli/tools/update_todo_list.py, tests/tools/test_update_todo_list.py, minor import-order touch in tests/tools/test_get_lines.py.

Out of scope: General glued-tool JSON (parse_tool_arguments), Grep, session encryption — separate PRs if still needed on main.

Checklist

  • Uses existing normalize_json_array (no duplicate helper stack)
  • execute and format_output share the same normalization path
  • Tests added and passing locally
  • No change to clone/multi-repo workspace behavior

normalize_json_array for tasks in execute and format_output; coerce
brace-prefixed strings without breaking on invalid JSON; add
test_update_todo_list coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant