Fix LLM returning null for repo_relative_path in routing

Two changes:
1. Add `format: "json"` to Ollama API calls so the model enforces
   JSON output mode, reducing malformed responses
2. Strengthen the routing prompt with explicit type constraints
   ("NEVER null or empty"), rules to copy manifest paths exactly,
   and a concrete example response

This fixes the validation error: "repo_relative_path: Expected
string, received null" from qwen3.5:397b-cloud.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Khalid A
2026-04-17 20:07:16 -05:00
parent 75e4c96a78
commit 464d2c8230

View File

@@ -20,7 +20,7 @@ async function ollamaChat(messages: Array<{ role: string; content: string }>, mo
'Content-Type': 'application/json',
...(OLLAMA_API_KEY ? { Authorization: `Bearer ${OLLAMA_API_KEY}` } : {}),
},
body: JSON.stringify({ model, messages, stream: false }),
body: JSON.stringify({ model, messages, stream: false, format: 'json' }),
});
if (!resp.ok) {
@@ -124,14 +124,20 @@ export async function routeEditIntent(params: RouteEditIntentParams, chat?: LlmC
role: 'system',
content: `You are a routing assistant for a website CMS. Given a natural language edit request and a manifest of available content sections, determine which section file the edit applies to.
Return a JSON object with:
- "repo_relative_path": the path of the target section file
- "needs_clarification": true if the request is ambiguous
- "reason": short explanation
- "clarification_message": (only if needs_clarification) a question to ask the user
Return a JSON object with EXACTLY these fields:
- "repo_relative_path": a STRING — the path of the target section file from the manifest (e.g. "content/sections/hero.json"). NEVER null or empty.
- "needs_clarification": a boolean — true only if the request is genuinely ambiguous between multiple sections
- "reason": a short string explaining the routing decision
- "clarification_message": a string (only when needs_clarification is true) — a question to ask the user
If the request is about showing/hiding/enabling/disabling a section, route to that section's file.
If the request mentions events, route to "content/events.json".`,
Rules:
- "repo_relative_path" MUST be one of the paths listed in the MANIFEST. Copy it exactly.
- If the request is about showing/hiding/enabling/disabling a section, route to that section's file.
- If the request mentions events, route to "content/events.json".
- When in doubt, pick the most likely section rather than marking ambiguous.
Example response:
{"repo_relative_path": "content/sections/hero.json", "needs_clarification": false, "reason": "Request about hero section headline"}`,
},
{
role: 'user',