Commit Graph
75 Commits
Author SHA1 Message Date
xugangqiang 7c99668aee fix(parser): emit xlsx spreadsheets as typed table chunks (#19509) 2026-09-14 15:10:48 +08:00
jay77721 fbd374e92f refactor(parser): unify parser outputs to structured JSON items (#19467) 2026-09-11 18:52:15 +08:00
Yash Raj Pandey 05168a37fa Decode a single-part email body by its Content-Transfer-Encoding (#19178) 2026-09-10 10:34:18 +08:00
jay77721 e53e5de0cb fix(parser): recover text_box and nested table/list text in office IR (#19319) 2026-09-08 12:53:49 +08:00
jay77721 1c3c622329 fix(parser): recover invalid XLSX sheet names (#19264) 2026-09-04 18:51:27 +08:00
jay77721 5bcaa73cb7 fix(parser): support non-UTF-8 decoding across text, csv, and epub parsers (#19243) 2026-09-04 14:23:08 +08:00
xugangqiang a5a83a5653 refactor(parser): collapse docElementText into docxElementText (#19135) 2026-09-03 16:42:49 +08:00
Yash Raj Pandey 7d9bcbad58 fix(parser): stop the .msg date test depending on the host timezone (#19182)
Fix flaky timestamp test that only passed in Asia/Shanghai TZ. Now parses and compares the instant instead of literal string.

Signed-off-by: Yash Raj Pandey <yashpn62@gmail.com>
2026-09-03 10:45:56 +08:00
xugangqiang 4168b3f9df fix(parser): prefer structured IR over flatter views for .doc (#19147) 2026-09-02 21:29:00 +08:00
Harsh Kashyap be38e1eaf1 refactor(pptx): simplify buildPPTXJSONSections + drop Python-compat wording (Follow-ups 1+2 of #19076) (#19098) 2026-09-02 21:26:28 +08:00
xugangqiang 2132798f15 Fix(parser): raise legacy .doc parsing fidelity via structured IR (#18192) 2026-09-02 12:13:37 +08:00
euvre 8c31544787 fix(go): parse PPTX one chunk per slide (#18254) 2026-09-01 14:28:06 +08:00
xugangqiang c28edde895 feat(deepdoc): in-process static-linked ONNX Runtime DeepDoc backend (#18731) 2026-08-31 13:18:12 +08:00
euvre 0cc348ad22 fix(parser): make PDF "remove TOC" and "remove header/footer" options work without DeepDoc inference (#18602) 2026-08-31 13:14:56 +08:00
天海蒼灆 61298397f6 feat: locate Excel citation sources in document preview (#18853) 2026-08-29 23:56:57 +08:00
euvre f96316fa5e fix(parser): drop merged-block and wrapped PDF TOC entries when remove_toc is enabled (#18793) 2026-08-28 17:02:35 +08:00
euvre 9d90077455 fix(dataflow): decode non-UTF-8 HTML files before parsing in Go pipeline (#18801) 2026-08-28 17:01:58 +08:00
jay77721 34870e297d fix(parser): wire per-call VLM model config, harden vision dispatch (#18846) 2026-08-27 16:00:21 +08:00
jay77721 e9d5dff628 fix: fall back to the real office container format when extension is wrong (#18843) 2026-08-27 14:37:03 +08:00
jay77721 0947a87c76 fix(parser): align image output_format to json and use per-family defaults (strict) (#18802) 2026-08-27 10:05:10 +08:00
buua436 82e363919d feat: extract images from xlsx parser (#18800) 2026-08-27 09:54:31 +08:00
Taranum Wasu 28ce77fe5f refactor(parser): extract shared parseWithTCADP core from pptx/xls/pdf wrappers (#17671) 2026-08-26 19:30:19 +08:00
euvre e79b9bdc01 fix(parser): clean .eml text output for chunking (#18592) 2026-08-26 11:20:05 +08:00
Lynn 45a47d9d45 Fix(go): PaddleOCR -> PaddleOCR.local, PaddleOCR.net -> PaddleOCR (#18747) 2026-08-25 20:02:01 +08:00
jay77721 f9e86b1bb1 fix(parser): crop media sections in PDF JSON path, unify Data URI and markdown rendering (#18742) 2026-08-25 19:47:02 +08:00
Jack b78b559ac5 Remove noocr/SkipOCR dead code path and text-layer-only parity test (#18443) 2026-08-18 22:47:31 +08:00
Jack 0517aebb80 fix(parser): align Go spreadsheet HTML with Python and harden header detection (#18304)
Brings the Go `XLSX`/`XLS`/`CSV` parsers in line with the Python deepdoc spreadsheet HTML contract and improves header detection beyond it.
2026-08-17 15:17:14 +08:00
Jack 272645a27a fix(pdf): align DLA region handling with Python reference (#18295)
Aligns three Go DLA / PDF post-processing behaviors with the Python `deepdoc` reference so the Go PDF pipeline matches Python's DLA region / annotation semantics.
2026-08-17 14:33:44 +08:00
Jack c23d5fc819 fix(parser): support .msg parsing and make email attachments retrievable (#18198)
- Add Go `EmailParser` support for Outlook `.msg` (OLE2/CFB) files via
the `gomsg` library, in addition to the existing `.eml` (RFC 5322)
support. The `.msg` hard-error is gone; emails with `.msg` attachments
are now ingested end-to-end.
- Re-chunk email attachments into retrievable text (user-oriented). Each
attachment is re-parsed by its file extension through the shared parser
registry and folded back into the same document, so attachment content
becomes searchable. This mirrors Python's legacy `rag/app/email.py`.
Binary attachments (images/audio/video/folders) are skipped by design.
- Restore a corrupted `sample.msg` test fixture and add guards so binary
fixtures are never mangled again (`.gitattributes` marks `*.msg` binary;
`check_files.py` skips NUL-byte files). Also made `check_files.py`
ruff-clean.
2026-08-14 10:38:38 +08:00
Jack c7db20b8d3 test(parser): pin figure-aware reading order in PDF post-process (#18178)
Adds a characterization / regression test
(`pdf_postprocess_measure_test.go`) that pins the **figure-aware reading
order** produced by the PDF adapter layer
(`internal/parser/parser/pdf_postprocess.go`).
2026-08-12 20:28:23 +08:00
Jack 8c5c870470 fix(parser): emit a single structured table item in document order (#18168) 2026-08-12 18:36:21 +08:00
Jack 7b2d052f8a refactor(parser): align TextParser with Python _code delimiter split (#18128) 2026-08-12 13:07:23 +08:00
Jack 875ca966e9 refactor(parser): preserve HTML <table> structure (inline + structured item) (#18129)
Stop flattening `<table>` into a single text blob. A `<table>` now emits:
1. an inlined `doc_type_kwd:"text"` item keeping the `<table>…</table>`
markup (row/column structure survives for embedding/retrieval/LLM rendering),
2. a structured `doc_type_kwd:"table"` / `ck_type:"table"` item appended
after the walk, consumed by the downstream chunker.
2026-08-11 22:15:15 +08:00
Jack 93dca789b5 refactor(parser): make markdown golden meta-driven, drop generator script (#18125) 2026-08-11 19:53:56 +08:00
Jack 4a8bb1b72a test(parser): add shared golden-doc + alignment helpers (#18098)
Centralize the shared golden-doc + alignment helpers in `align_test.go` so the format-specific PRs (text&code, markdown golden, HTML) reuse one implementation instead of each carrying their own copy of the scaffolding.
2026-08-11 18:00:25 +08:00
Jin Hai d7661b676d Go: fix context and warnings (#18097)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-11 16:18:49 +08:00
Jack d6f6b6231f Fix(parser): don't collapse markdown doc into one item when a table is present (#18014) 2026-08-11 10:21:42 +08:00
Jin Hai c0bc146fcb Go: fix env variables (#18032)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-10 14:37:05 +08:00
Jack 4f15e261cd fix(parser/email): align metadata/text_html emission with Python flow contract (#18005)
Aligns the Go EML parser (`internal/parser/parser/email_parser.go`) with the Python flow parser (`rag/flow/parser/parser.py:_email`) on two structural points so the Go path is a faithful drop-in for the Python path on `.eml` inputs.
2026-08-07 21:57:51 +08:00
Jack 16ac94cff5 fix(parser/chunk): dedupe CompileDelimiterPatternList active entries (#17939)
Restore the deduplication that was dropped when #17926 was merged.
`CompileDelimiterPatternList` now keeps a `seen` set and collapses
equivalent active entries (both backtick-inner and bare) into a single
alternation. This PR also removes the dead code that the re-review
surfaced.
2026-08-07 10:06:04 +08:00
Jack 60df86bfa2 fix(go): unify children delimiter pattern with backtick-strip + rune order (#17926)
`compileChildrenPattern` re-implemented the delimiter-list compile
inline with two divergences from the shared
`CompileDelimiterListPattern`:

- It never stripped backticks, so a backtick-wrapped
`children_delimiter` like `` `###` `` matched the **literal wrapped
token** rather than the inner `###`.
- It sorted by **byte length** instead of rune count (`sortSlice`), so
multi-byte delimiters could be ordered incorrectly and a longer
delimiter could fail to win over a shorter prefix.
2026-08-06 16:10:30 +08:00
Jack f41f866aa1 Fix(parser): keep real line breaks when merging HTML fragments and PDF boxes (#17856)
Net effect: inline prose stays on one line (`Hello World`), real `<br>` boundaries survive (including before tags and repeated breaks), and source formatting whitespace no longer over-splits.
2026-08-06 09:57:23 +08:00
Jin Hai 86021932ae Go: fix warnings (#17738)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-08-03 21:30:01 +08:00
Sandkiloconnect[bot] d4ceeee4ed refactor(nlp): collapse 6 delimiter-parser implementations into one canonical helper (#17383) (#17387)
## Summary

Six sites used to read the same `parser_config.delimiter` field with
divergent grammars:

- `rag.nlp.get_delimiters` (PDF/DOCX/HTML/EPUB/JSON/CSV/XLSX/email/book)
- `rag.nlp.naive_merge` (custom-delimiter branch)
- `rag.nlp.naive_merge_with_images`
- `rag.nlp._build_cks`
- `deepdoc.parser.txt_parser.parser_txt` (.txt, code)
-
`deepdoc.parser.markdown_parser.MarkdownElementExtractor.get_delimiters`

The six implementations disagreed on bare-vs-wrapped chars, dedupe, sort
order, CRLF normalization, and `re.I` (#17384). The shipped default ``
`\n!?;。;!?` `` was a no-op for `.md` because the markdown path only
matched backtick-wrapped tokens.

## Changes

- **new:** `rag/nlp/delim.py` with `parse_delimiter_field` and
`compile_delimiter_pattern`. Single source of truth. CRLF normalization
at the top; longest-first stable sort; insertion-ordered dedupe; no
`re.I`.
- **refactor:** all six call sites delegate to the helper.
  - `rag/nlp/__init__.py::get_delimiters` becomes a thin shim.
- `deepdoc/parser/txt_parser.py::parser_txt` drops the
`[encode/decode/unicode_escape]` round-trip.
- `deepdoc/parser/markdown_parser.py::get_delimiters` honors bare chars
(fixes [1]).
- **tests:** `test/unit_test/rag/test_delim.py` (85 tests) — helper,
acceptance table, frontend parity, static guard against re-inlining.
- **tests:** `test/unit_test/rag/test_delimiter_case_sensitive.py` (from
#17386) updated to retarget the static check at the new helper +
AST-based broader scan.

## Acceptance criteria

- All six sites produce the same regex pattern for the same input.
- Shipped default keeps working for `.txt` / `.pdf` / `.docx`.
- Shipped default for `.md` now splits (was a silent no-op).
- Tooltip example `` `\n##;` `` produces three effective delimiters
regardless of file type.
- Bare whitespace inputs split on every occurrence.
- Backtick-wrapped whitespace splits only on the exact N-char sequence.
- CRLF-line-ending documents split identically to LF-line-ending
documents.
- 123 tests pass (85 new + 38 existing).

## Rebase protocol

As #17385 and #17386 evolve, this branch will be rebased on top. The
only overlap between this PR's diff and the other two is
`test_delimiter_case_sensitive.py`, where #17383 modifies the static
check to point at the new helper location.

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
2026-08-02 17:07:14 +08:00
Jin Hai b058229ab3 Go: fix SSRF (#17641)
### Summary

Check the URL to prevent SSRF attack.

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-07-31 19:15:38 +08:00
Jin Hai 36ae39bc60 Go: refactor config (#17544)
Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-07-31 17:18:45 +08:00
JackandCodeBuddy de17dda5f8 fix(parser): derive eng from content for DOCX/HTML TOC removal (#17585)
## Summary
- The `eng` flag passed to `removeTOCWord`/`removeContentsTable` was
hardcoded `false`, so English documents used the CJK 3-char TOC prefix
instead of Python's 2-word English prefix. This caused English tables of
contents to be under-deleted (left in indexed text) or over-deleted
(body paragraphs sharing the 3-char prefix dropped).
- `eng` is now derived from the parsed item content via `isEnglishItems`
(a port of Python `is_english`/`_is_english`), mirroring Python's
content heuristic.

## Changes
- `internal/parser/parser/text_toc.go`: add
`isEnglishItems`/`isEnglishTexts` (ASCII-ratio >80% ⇒ English,
fullmatch-anchored regex).
- `internal/parser/parser/docx_parser.go`: pass
`isEnglishItems(sections)` / `isEnglishItems(lineItems)` to
`removeTOCWord` (json + markdown paths).
- `internal/parser/parser/html_parser.go`: pass `isEnglishItems(items)`
to `removeContentsTable`.
- `docs/migration_python_go_diff.md`: close the 1.9/1.10 `eng` residual
and resolve the contradictory Parser 2.11 "Partially fixed" note.

## Notes
- `remove_toc` is a Parser-stage, DSL-configured feature (`remove_toc:
true/false` in the parser family setup). This change only fixes the
internal English/CJK prefix decision; it does not alter the pipeline or
the DSL contract. `remove_header_footer` (precise match) is unaffected.
- `eng` is auto-derived from content rather than exposed as a new config
knob, to stay faithful to Python behavior.

## Test plan
- `CGO_ENABLED=0 go test ./internal/parser/parser/ -run
'TestRemoveContentsTable|TestIsEnglishTexts|TestRemoveTOCWordEnglishDetection'`
- Added `TestIsEnglishTexts` (ASCII-ratio cases) and
`TestRemoveTOCWordEnglishDetection` (English TOC no longer over-deletes
"Chapter 2 Method").

---------

Co-authored-by: CodeBuddy <noreply@codebuddy.ai>
2026-07-31 13:09:02 +08:00
Wang Qi c77741e7a8 Porting change from #17477 python to go, parse table into chunk for markdown file (#17488)
Porting change from #17477 python to go, parse table into chunk for
markdown file
Before:
<img width="3606" height="1805" alt="image"
src="https://github.com/user-attachments/assets/363698be-c182-40cf-a167-0f0c13a68b12"
/>

After:
<img width="3606" height="1805" alt="image"
src="https://github.com/user-attachments/assets/9d0d18cb-843e-4a1a-b176-16ac32998310"
/>
2026-07-29 09:39:47 +08:00
Jack 9b0719fa94 fix: Go ingestion migration batch 5 (Parser 1.1/1.7/2.11, Chunker 1.7/1.8/2.6/2.7, Tokenizer 6x fixes) (#17419)
## Summary

Continuation of the Python→Go ingestion pipeline migration (File →
Parser → Chunker → Extractor → Tokenizer). Fixes cover Parser, Chunker,
and Tokenizer gaps identified. Fix page number (0-indexed and 1-index
mixed before fix; use 1-indexed after fix) and chunk order issues.

### Parser
- **Slides TCADP (1.7):** `pptx_tcadp.go` + TCADP branch in
`pptx_parser.go`/`ppt_parser.go` — PowerPoint files now support
`parse_method="tcadp"` via the TCADP cloud service, matching the
spreadsheet-family TCADP pattern. PPT containers pass `"PPT"` as
fileType (not hardcoded `"PPTX"`).
- **Audio default output_format (2.11):** `defaultSetups()` audio
default changed from `"text"` to `"json"`, aligning with Python
`parser.py:232` and `AllowedOutputFormat["audio"]={"json"}`.
- **PDF VLM enhancement (1.1):** `maybeDispatchPDFVisionEnhancement` in
`pdf_vision_dispatch.go` enriches image/table items with IMAGE2TEXT
model descriptions after PDF parsing, mirroring Python
`enhance_media_sections_with_vision`. Semaphore fix: acquire before
goroutine start to prevent unbounded goroutine creation.
- **json family (2.3):** reclassified as Keep Go — `json_parser.go` is a
functional enhancement, not a parity gap.
- **page number:** changed from "mixed use of 1-indexed & 0-indexed" to
"1-indexed"

### Chunker
- **BULLET_PATTERN fallback (1.7):** 4th-level fallback in
`resolveTitleLevels` (`title.go`) detects bullet/numbered-list patterns
(Chinese legal, numbering, English) when outline + regex levels produce
only bodyLevel. Guarded by `allBodyLevel` to never override existing
structure.
- **Tag/One chunker fields (1.8):** `tag.go` sets `TopInt` from source
row index; `one.go` preserves `Positions`/`PDFPositions` from source
items. TSV multi-line RowNum fix: tracks `contentStart` for correct row
attribution.
- **Overlapped_percent normalization (2.6):**
`NormalizeOverlappedPercent` in `schema/chunker.go` mirrors Python
`common/float_utils.py:50-58` — accepts `[0,1)` fraction or `[0,90]`
percent, normalizes to canonical `[0,90]`.
- **Paragraph splitting (2.7):** aligned to Python flow `naive_merge` —
`CRLF` normalization, `splitKeepingDelimiter` preserves sentence
delimiters, single-section merge with token-budget-governed chunking.
- **chunk order:** sort by reading order

### Tokenizer
- **Phantom chunk filtering (Omission 2):** `isPhantomChunk` + filter
loop in `chunksFromTokenizerUpstream` skips zero-value ChunkDocs.
- **Batch size env var (Omission 3):** `embeddingBatchSize()` reads
`TOKENIZER_EMBEDDING_BATCH_SIZE`, defaults to 16.
- **Summary empty check (Diff 5):** `TrimSpace(s) != ""` → `s != ""`,
matching Python truthy check.
- **chunk_order_int all paths (Diff 8):** set unconditionally before
full_text/embedding branching.
- **Timeout default (Diff 10):** `600s` → `60s`, matching Python
`@timeout(60)`.
- **Small maxTokens truncation (Diff 14):** `truncateForEmbedding`
returns `""` when `maxTokens <= 10`, matching Python.

### Code review fixes
- Semaphore acquire moved before goroutine in `pdf_vision_dispatch.go`
(concurrency control)
- Context propagation in `pptx_tcadp.go` (cancellation support)
- Test resolver leak fix in `media_dispatch_test.go` (defer restore)
- Migration history comments removed per AGENTS.md

## Test plan
```
bash build.sh --test ./internal/parser/parser/... ./internal/ingestion/component/...
```

## Notes
- Migration diff tracking: `docs/migration_python_go_diff.md`
- Remaining gaps: Extractor component only (21 items)
2026-07-28 11:12:52 +08:00
Jin Hai bdfc3ada41 Go: add context (#17314)
### Summary

As title.

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-07-24 16:47:12 +08:00