refactor(todo): schema diet — item shape and merge semantics taught once, by the param schema (323 -> 232 tok/call, -28%) (#97257)
This commit is contained in:
50
tests/tools/test_todo_schema_diet.py
Normal file
50
tests/tools/test_todo_schema_diet.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""todo schema diet contract (#95681).
|
||||
|
||||
Pins the dedup: item shape and merge semantics are taught ONLY by the
|
||||
parameter schema (types/enum/required), never re-spelled in the
|
||||
description — and the load-bearing behavioral teachings survive.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
|
||||
from tools.todo_tool import TODO_SCHEMA
|
||||
|
||||
|
||||
class TestTodoSchemaDiet(unittest.TestCase):
|
||||
def test_description_does_not_respell_param_structure(self):
|
||||
desc = TODO_SCHEMA["description"]
|
||||
# The old '{id: string, content: string, status: ...}' spell-out
|
||||
# and the 'Writing:' merge bullets duplicated the param schema.
|
||||
self.assertNotIn("{id:", desc)
|
||||
self.assertNotIn("Writing:", desc)
|
||||
self.assertNotIn("merge=", desc)
|
||||
self.assertNotIn("pending|in_progress", desc)
|
||||
|
||||
def test_param_schema_is_the_single_structure_source(self):
|
||||
item = TODO_SCHEMA["parameters"]["properties"]["todos"]["items"]
|
||||
self.assertEqual(item["required"], ["id", "content", "status"])
|
||||
self.assertEqual(
|
||||
item["properties"]["status"]["enum"],
|
||||
["pending", "in_progress", "completed", "cancelled"],
|
||||
)
|
||||
merge_desc = TODO_SCHEMA["parameters"]["properties"]["merge"]["description"]
|
||||
self.assertIn("replace the entire list", merge_desc)
|
||||
self.assertIn("update existing items by id", merge_desc)
|
||||
|
||||
def test_behavioral_teachings_survive(self):
|
||||
"""The parts that fight real model failure modes must not be
|
||||
dieted away: enumerate-all-N, one in_progress, verified-done,
|
||||
cancel-and-revise."""
|
||||
desc = TODO_SCHEMA["description"]
|
||||
self.assertIn("enumerate every instance", desc)
|
||||
self.assertIn("ONE item in_progress", desc)
|
||||
self.assertIn("verified done", desc)
|
||||
self.assertIn("cancel it and add a revised item", desc)
|
||||
self.assertIn("3+ steps", desc)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -293,36 +293,31 @@ def check_todo_requirements() -> bool:
|
||||
|
||||
TODO_SCHEMA = {
|
||||
"name": "todo",
|
||||
# Dieted (#95681): the item shape and merge semantics live ONLY in the
|
||||
# parameter schema below — the description teaches behavior, not
|
||||
# structure the params already define.
|
||||
"description": (
|
||||
"Manage your task list for the current session. Use for complex tasks "
|
||||
"with 3+ steps or when the user provides multiple tasks. "
|
||||
"For 'all N items' tasks, enumerate every instance as its own checklist "
|
||||
"item so none are silently dropped. "
|
||||
"Call with no parameters to read the current list.\n\n"
|
||||
"Writing:\n"
|
||||
"- Provide 'todos' array to create/update items\n"
|
||||
"- merge=false (default): replace the entire list with a fresh plan\n"
|
||||
"- merge=true: update existing items by id, add any new ones\n\n"
|
||||
"Each item: {id: string, content: string, "
|
||||
"status: pending|in_progress|completed|cancelled}\n"
|
||||
"List order is priority. Only ONE item in_progress at a time.\n"
|
||||
"Call with no parameters to read the current list.\n"
|
||||
"List order is priority. Only ONE item in_progress at a time. "
|
||||
"Mark an item completed only after the work is verified done, never "
|
||||
"based on intent. If something fails, "
|
||||
"cancel it and add a revised item.\n\n"
|
||||
"Always returns the full current list."
|
||||
"based on intent. If something fails, cancel it and add a revised "
|
||||
"item. Always returns the full current list."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"todos": {
|
||||
"type": "array",
|
||||
"description": "Task items to write. Omit to read current list.",
|
||||
"description": "Task items to write.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique item identifier"
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
@@ -330,8 +325,7 @@ TODO_SCHEMA = {
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["pending", "in_progress", "completed", "cancelled"],
|
||||
"description": "Current status"
|
||||
"enum": ["pending", "in_progress", "completed", "cancelled"]
|
||||
}
|
||||
},
|
||||
"required": ["id", "content", "status"]
|
||||
@@ -341,7 +335,7 @@ TODO_SCHEMA = {
|
||||
"type": "boolean",
|
||||
"description": (
|
||||
"true: update existing items by id, add new ones. "
|
||||
"false (default): replace the entire list."
|
||||
"false (default): replace the entire list with a fresh plan."
|
||||
),
|
||||
"default": False
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user