Commit ceade4c
fix(file_processors): Preserve Docling chunk structure metadata (#6398)
# What does this PR do?
Fixes #6396.
Docling returns useful information for each chunk, such as section
headings and page numbers. OGX was reading some of this information from
the wrong place, so it was lost during file processing.
This PR fixes that for:
- local Docling;
- Docling Serve sync processing; and
- Docling Serve async processing.
The values are stored as existing chunk attributes. Headings and page
numbers are converted to strings so they work with the current vector
store search response.
For example:
```json
{
"headings": "Installation > Database setup",
"page_numbers": "4, 5"
}
```
The `>` separator keeps the heading order clear. A comma inside a
heading is not treated as a new heading.
The old nested Docling heading format is still supported as a fallback.
No new API field is added. Existing user attributes continue to work.
Applications can use the filename, heading, and page number to create
citations such as:
```text
manual.pdf, page 4, "Installation > Database setup"
```
## Related discussion
#6399 proposed returning a separate structured metadata field from
vector store search.
During review, we agreed to use the existing `attributes` field with
string values instead. This PR follows that decision, so it does not
depend on #6399.
## Test Plan
Run the focused unit tests:
```bash
uv run pytest -q \
tests/unit/providers/file_processor/test_docling_serve.py \
tests/unit/providers/file_processor/test_docling_metadata.py
```
Output:
```text
30 passed, 1 warning
```
The warning is an existing `AsyncMock` warning in the IBM SaaS
compatibility test.
Run the repository checks for the changed files:
```bash
uv run pre-commit run --files \
src/ogx/providers/utils/files/structural_metadata.py \
src/ogx/providers/inline/file_processor/docling/_metadata.py \
src/ogx/providers/remote/file_processor/docling_serve/docling_serve.py \
tests/unit/providers/file_processor/test_docling_metadata.py \
tests/unit/providers/file_processor/test_docling_serve.py
```
All checks passed.
I also tested this with a running OGX stack using Docling Serve and
PGVector. A search result for text on the second page returned:
```json
{
"file_id": "file-31dffd91a4be4f1196cac053379c9fbe",
"filename": "precise-citation.pdf",
"headings": "Precise Citations, Chapter Two",
"page_numbers": "2",
"verification": "citation-backward-compatibility"
}
```
This was enough to create the following document, section, and page
citation:
```text
precise-citation.pdf, page 2, "Precise Citations, Chapter Two"
```
---------
Signed-off-by: Peter Gustafsson <peter.gustafsson6@gmail.com>
Co-authored-by: Peter Gustafsson <peter.gustafsson6@gmail.com>1 parent 59872d4 commit ceade4c
6 files changed
Lines changed: 231 additions & 20 deletions
File tree
- src/ogx/providers
- inline/file_processor/docling
- remote/file_processor/docling_serve
- utils/files
- tests/unit/providers/file_processor
Lines changed: 31 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
Lines changed: 2 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
277 | 278 | | |
278 | 279 | | |
279 | 280 | | |
280 | | - | |
281 | 281 | | |
282 | 282 | | |
283 | 283 | | |
| |||
286 | 286 | | |
287 | 287 | | |
288 | 288 | | |
289 | | - | |
290 | | - | |
| 289 | + | |
291 | 290 | | |
292 | 291 | | |
293 | 292 | | |
| |||
Lines changed: 25 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
339 | 340 | | |
340 | 341 | | |
341 | 342 | | |
342 | | - | |
343 | | - | |
344 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
345 | 355 | | |
346 | 356 | | |
347 | 357 | | |
| |||
418 | 428 | | |
419 | 429 | | |
420 | 430 | | |
421 | | - | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
426 | | - | |
427 | | - | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
428 | 443 | | |
429 | 444 | | |
430 | 445 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
Lines changed: 87 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
Lines changed: 58 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
47 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
48 | 69 | | |
49 | 70 | | |
50 | 71 | | |
| |||
206 | 227 | | |
207 | 228 | | |
208 | 229 | | |
209 | | - | |
| 230 | + | |
210 | 231 | | |
211 | 232 | | |
212 | 233 | | |
213 | 234 | | |
214 | 235 | | |
215 | | - | |
| 236 | + | |
| 237 | + | |
216 | 238 | | |
217 | | - | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
218 | 260 | | |
219 | 261 | | |
220 | 262 | | |
| |||
478 | 520 | | |
479 | 521 | | |
480 | 522 | | |
481 | | - | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
482 | 531 | | |
483 | 532 | | |
484 | 533 | | |
| |||
493 | 542 | | |
494 | 543 | | |
495 | 544 | | |
| 545 | + | |
| 546 | + | |
496 | 547 | | |
0 commit comments