Recover structured JSON from local-LLM output that strict schema parsing rejected.
Ollama-served models routinely wrap their JSON object in a json fence and
occasionally leave a trailing comma before a closing brace/bracket, despite
being sent a response_format. LlmCore's strict structured-output parse then
fails even though the body is otherwise valid and complete. The error tuple
carries the raw body, so this module best-effort strips the fence + trailing
commas and re-decodes. Shared by retain fact extraction and consolidation.
Summary
Functions
Strip a surrounding markdown code fence and trailing commas, then JSON-decode.
Best-effort: returns {:ok, term} or {:error, reason} (from Jason.decode/1).
Pull the raw model body out of the known structured-output error shapes.
Try to decode a valid map from the error reason a complete_json_schema call
returned. Returns {:ok, decoded_map} or :error.
Like recover/1, but casts the recovered map into module's struct using the
same string-key → struct-field mapping Foresight.LLMs.LlmCore.complete_structured
uses on the happy path. Lets the reflect agentic loop's structured calls survive a
JSON-fenced body from models like gpt-oss:20b instead of hard-failing the whole
reflect (fairness). Returns {:ok, struct} or :error so the caller keeps
its original error when recovery is impossible.
Functions
Strip a surrounding markdown code fence and trailing commas, then JSON-decode.
Best-effort: returns {:ok, term} or {:error, reason} (from Jason.decode/1).
Pull the raw model body out of the known structured-output error shapes.
Try to decode a valid map from the error reason a complete_json_schema call
returned. Returns {:ok, decoded_map} or :error.
Like recover/1, but casts the recovered map into module's struct using the
same string-key → struct-field mapping Foresight.LLMs.LlmCore.complete_structured
uses on the happy path. Lets the reflect agentic loop's structured calls survive a
JSON-fenced body from models like gpt-oss:20b instead of hard-failing the whole
reflect (fairness). Returns {:ok, struct} or :error so the caller keeps
its original error when recovery is impossible.