Add quality-aware server-side PDF OCR ingestion - #366
Conversation
|
| chunk_count: | ||
| type: integer | ||
| description: Number of indexable chunks derived from the units. | ||
| ocr_attempted_count: |
There was a problem hiding this comment.
I don't think this should be "ocr" specific (for instance it should also apply to auto image embedding of pages OR ocr) same for all these fields, a lot of them apply to chunks too
There was a problem hiding this comment.
[codex] Concrete proposal: replace the top-level ocr_* fields with processing_stages: []DocumentArtifactStageSummary. Each stage should identify an operation (extract, render, OCR, caption, transcribe, chunk, or embed) and expose common counts such as input, attempted, completed, selected, retained_source, failed, and output. Failures should identify a generic unit_id plus an optional locator, rather than only PDF page numbers. OCR-specific quality metrics can remain nested in the operation details. This gives chunking and direct page/image embedding the same observability contract.
| fn logReadProfileStep(phase: []const u8, step: usize, seq_len: usize, elapsed_ns: u64) void { | ||
| if (!readProfileEnabled()) return; | ||
| std.log.info("read-profile phase={s} step={d} seq_len={d} elapsed_ms={d:.3}", .{ phase, step, seq_len, nsToMs(elapsed_ns) }); | ||
| if (active_read_profile_correlation_id) |correlation_id| { |
There was a problem hiding this comment.
@timkaye11 can you review the inference changes
There was a problem hiding this comment.
[codex] @timkaye11 Could you review the inference portion, particularly the new Florence batch path and serial fallback, batch byte/image limits, the lifetime and nesting of the thread-local profiling context, and whether local-only diagnostic propagation is intentional?
| const platform = @import("antfly_platform"); | ||
|
|
||
| const antfly_cloud_binary = "antfly-cloud"; | ||
| const recommended_server_fd_limit: std.posix.rlim_t = 4096; |
There was a problem hiding this comment.
I don't think this file should reference std.posix? Seems like maybe this should be in lib/platform and the resource_manager abstraction
There was a problem hiding this comment.
[codex] Please move the OS mechanism behind antfly_platform.process, for example ensureFileDescriptorSoftLimitAtLeast(target: u64), and keep only the 4096 policy in startup code. The existing storage ResourceManager does not seem like the right owner unless it is deliberately expanded beyond memory and storage budgets. Also, isServerSubcommand already diverges from the dispatch block: it omits lite and ha, so those processes never receive the check. Ideally server command classification should have one source of truth.
| const results = try reader.readBatch(image_datas, .{ | ||
| .prompt = request.prompt, | ||
| .max_tokens = max_tokens, | ||
| .correlation_id = request.correlation_id, |
There was a problem hiding this comment.
This is typically called a "trace_id" and we should probably name it that
There was a problem hiding this comment.
[codex] Looking further upstream, this value is a stable prefix of the source SHA-256, so trace_id would overstate its semantics. Please either name it profile_source_id/source_fingerprint throughout and log it explicitly as such, or introduce a real per-execution trace ID and propagate that through the extraction and inference calls. correlation_id is too vague, but a stable content fingerprint should not be presented as a distributed trace identifier.
| .page_rotation = 90, | ||
| .extraction_method = "pdf_text", | ||
| .confidence = 0.94, | ||
| .ocr_attempted = true, |
There was a problem hiding this comment.
See my other comment but I don't think these fields should be ocr specific but should be more generic, maybe have a little convo with fable and codex about making this more adaptable to satisfy embedding multipage directly, ocr, document extraction, captioning, chunking for text/audio/images
There was a problem hiding this comment.
[codex] I would normalize this as provenance.source plus provenance.derivations[], instead of continuing to add sibling ocr_* fields. Each derivation can have a common operation, status, selected flag, parent references, output descriptor, confidence, and failure. Render dimensions and DPI belong to a render derivation, while OCR quality belongs to an OCR derivation. Chunks and embeddings should point to their parent unit/artifact through the same mechanism. The current payload emits the OCR values in three places, which makes future captioning, transcription, and multimodal embedding awkward and prone to drift. A pragmatic boundary for this PR would be to keep the internal OCR-specific Zig fields temporarily but map them into the generic public schema before merging.
|
[codex] e2e-base is still red: https://github.com/antflydb/antfly/actions/runs/29602361560/job/87957590465. The artifact restart test reaches produced/skipped/terminal-failed = 1/1/1, but strict coverage remains incomplete because the group is reported stale/config-mismatched. Please root-cause that state transition rather than widening the wait. The autoscaling split failure may be independent, but it also needs a clean rerun or diagnosis before merge. |
|
[codex] Re-review of the current head (01c28ba): there have been no code commits since the previous review, and the existing review threads remain unresolved.
The fix checks ASCII85 output only after ascii85DecodeAlloc returns. Inside the decoder, every z expands to four bytes with no budget check: antfly/zig/lib/pdf/src/reader.zig Lines 4878 to 4880 in 01c28ba antfly/zig/lib/pdf/src/reader.zig Lines 4925 to 4955 in 01c28ba
Columns, Colors, and BitsPerComponent are multiplied directly before casting to usize: antfly/zig/lib/pdf/src/reader.zig Lines 5114 to 5120 in 01c28ba
redactInlineEnrichmentProducerConfigs recursively removes every object key named producer_json from the entire serialized TableStatus, rather than only enrichment configurations: antfly/zig/pkg/antfly/src/api/tables.zig Lines 1840 to 1871 in 01c28ba antfly/specs/openapi/antfly/schema.yaml Lines 35 to 62 in 01c28ba Fix assessment:
|
|
[codex] I opened #392 with fixes for the concrete review blockers plus the platform/source-fingerprint cleanups. It is based on an exact mirror of this PR's reported head (01c28ba), because the visible fork branch currently points to a partial diverged history. The generic processing-stage and derivation-provenance schema redesign remains separate because it needs a coordinated public API/SDK migration. |
Fix PDF OCR review blockers
Summary
Adds end-to-end server-side PDF ingestion to Antfly. One artifact configuration accepts inline PDF bytes or a URL, fetches and parses the PDF inside Antfly, emits page units, selectively OCRs, chunks, embeds, and populates lexical plus semantic indexes—without external preprocessing or intermediate JSON.
What changed
<OCR>default, and prompt-echo/trivial-output rejection. Inline JPEG captioning is also supported./mergeE2Es cover inline/URL, born-digital, scanned, garbled, table, paged OCR, hybrid retrieval, and restart coverage paths.Notes
Replaces #360 after #335 merged and includes current
main, including its Florence optimizations. DocsAF is a client/configurator that uses Antfly; Antfly does not depend on DocsAF.