|
planning: fix LLM-output failure modes that killed every plan
Production planning_logs showed three ways a plan silently dies:
1. glm-5.3-flash wraps the whole answer in a structured envelope
(response:unknown{value:...}<tool_call|>) — the planner only knew the
gemma4 thought<channel|> artifact, so the wrapped analysis/plan failed
to parse. The stripper now unwraps response:<type>{value:...} envelopes,
including a truncated (unbalanced) one.
2. Empty content with spent completion tokens: glm on ollama-cloud puts
the whole answer in the thinking channel on some calls. Both planning
phases now fall back to thinking when content is empty; the debug log
records which channel served (source: content|thinking).
3. phase3_timeout at the shared 120s LLM_COMPLETE_TIMEOUT: planning now
has its own PLANNING_LLM_TIMEOUT_SEC (default 240).
Unit tests cover the envelope unwrap (balanced/truncated/inner braces),
the thinking fallback in both phases, and the clean-fail path.
|
|---|
|
|
| docs/config.md |
|---|
| navi/config.py |
|---|
| navi/core/planning.py |
|---|
| tests/unit/core/test_planning.py |
|---|