fix(rag): detect top-level JSON arrays in auto format detection
PR Checklist
- The commit message follows our guidelines (conventional commits)
- Related issue(s) linked
- Tests for the changes have been added
- Docs have been added / updated
- Changesets have been added
What is the current behavior?
detectFormat() accepted { or [ as the opening character but only ever accepted } as the closing one:
if ((text.startsWith("{") || text.startsWith("[")) && text.endsWith("}")) {
A top-level JSON array ends with ], so it never entered the JSON.parse branch and was reported as "text". detectStrategy() in document/transformers.ts maps that result to a chunker, so with strategy: "auto" any document whose content is a JSON array — API response dumps, exported record sets, .json fixtures — went to RecursiveChunker instead of JsonChunker, losing the structural path: value chunks and the fields / samplePaths metadata.
Object payloads were unaffected.
What is the new behavior?
The brackets are paired, so arrays are detected too:
if (
(text.startsWith("{") && text.endsWith("}")) ||
(text.startsWith("[") && text.endsWith("]"))
) {
The existing try { JSON.parse(text) } catch still guards malformed input, so [unclosed] keeps falling through to the html / latex / code / table / markdown checks and still returns "text".
fixes (issue)
fixes #1458
Notes for reviewers
- Scope is the array case only. I deliberately did not touch the table check below (
/\n\|.+\|\n/requires a newline before the first row, so a table at the very start of a document is also missed) — that is a separate bug and I would rather not bundle it. - Also noted in #1458 but not changed here:
JsonChunker'sformat: "json"is overwritten by theformat: "text"it inherits from the token chunker, becausebuildMetadataends withObject.assign(meta, params.extra)and onlysourceTypeis stripped from the inherited metadata. - New file
packages/rag/src/__tests__/format-detector.spec.tswith four cases: array detection, object detection, malformed fall-through, and an end-to-end check thatchunkByStrategy("auto", '[{"name":"alice"},{"name":"bob"}]')now yieldsmetadata.fields === 2and a chunk containing0.name: alice.
Verified locally (Windows host, no network or API keys):
vitest runinpackages/rag-> 47 passed across 19 files.- With
format-detector.tsreverted tomain, the array detection test and the end-to-end test fail (expected 'text' to be 'json',expected undefined to be 2); with the change they pass. biome checkclean on both changed files (the CRLF complaint when checking a raw Windows checkout disappears against the committed LF blob).
AI assistance: this fix and its tests were produced with an AI coding agent under my direction. The bug, the paired-bracket fix, the duplicate check and every test result quoted above were verified by running those commands against a checkout of main at 72a46c7.
Summary by cubic
Fixes detectFormat() so top-level JSON arrays are detected as JSON instead of "text". Previously the check accepted { or [ as an opening bracket but only } as a closing one, so arrays ending in ] fell through to RecursiveChunker under the auto strategy, losing JSON structural chunks and metadata. Brackets are now paired ({...} and [...]), and JSON.parse still guards malformed input.
fixes #1458
Summary by CodeRabbit
- Bug Fixes
- Automatic format detection now recognizes top-level JSON arrays, allowing them to be chunked as JSON. Malformed bracketed input continues to be treated as text.