Files
Enterprise-Knowledge-Base/internal/application
draix 7adf88766a fix(graph): recover JSON from malformed/truncated fences in extract_entity
Closes #1113

The graph extraction pipeline relies on a strict markdown fence regex to
pull JSON out of LLM responses. In production the regex misses ~84% of
real-world responses, in three ways:

  1. The LLM hits max_tokens mid-output and produces no closing fence.
  2. The opening fence is malformed or surrounded by prose, so the
     non-greedy regex fails to anchor a match.
  3. The model returns raw JSON with stray backticks but no real fence.

In every case extractContent fell through to returning the raw text,
which then failed json.Unmarshal with errors like
"invalid character '` + "`" + "' looking for beginning of value".

This change keeps the existing happy path untouched and adds a
conservative recovery step in the default branch of extractContent:

  - If an opening ``` is present, take everything after it, drop a
    likely language tag on the first line, cut at any trailing closing
    fence, and trim stray backticks/whitespace.
  - Otherwise, look for an outermost JSON object/array in the text using
    a small bracket-balanced scanner that respects string literals, so
    embedded {} or [] inside JSON strings don't confuse it.
  - Only fall back to the original raw-text behavior when neither
    strategy yields anything plausible.

The recovery helpers (stripFencesAndExtract, extractJSONLike,
isLikelyLanguageTag) are package-private and have table-driven tests in
extract_entity_test.go covering the three failure patterns described in
the issue, plus the previously-working fenced and bare-JSON shapes to
guard against regressions.
2026-05-07 15:40:19 +08:00
..