The LLM now orchestrates the plan instead of only answering from a
static snapshot. It reads the live plan, calls deterministic client-side
tools, and proposes small fix-ops; the tools validate, compute and
commit, so every edit is undo-able (LLM proposes, tools decide).
This llama.cpp build ignores the native OpenAI `tools` field, so tool
calls use a text protocol: the model emits <tool>{"name","args"}</tool>,
the app executes it and feeds the JSON result back as the next turn; the
loop ends when the model stops calling (capped at 10 turns).
Tools: itinerary_summary, search_places, place_facts, route_between
(real OSRM walk, straight-line fallback), review_plan (day overrun /
meal-hour / duplicate checks), and fix-ops add_stop, remove_stop,
move_stop, set_duration, set_start. Places and stops resolve by id or
name; dayIds are surfaced in the plan snapshot ([D1 · date]) so the model
doesn't guess. A subtle ⚙ activity line shows each tool call in the chat.
Verified end-to-end in headless Chrome: factual routing (route_between),
search+swap (search_places→add_stop, incumbent demoted to backup), and
diagnose+fix (review_plan→move_stop→set_start→re-review), with clean
undo-able commits each time.