33from __future__ import annotations
44
55import os
6+ import json
67import re
78from pathlib import Path
89from typing import Any , Dict , List , Optional , Union
@@ -92,12 +93,39 @@ class FileIndex(BaseModel):
9293
9394 chunks : Optional [str ] = None
9495 markdown : Optional [str ] = None
96+ chunks_slim : Optional [str ] = None
9597 kb_csv : Optional [str ] = None
9698 hierarchy : Optional [str ] = None
99+ toc_hierarchies : Optional [str ] = None
100+ hierarchy_view_html : Optional [str ] = None
97101 images : List [ImageFileInfo ] = Field (default_factory = list )
98102 tables : List [TableFileInfo ] = Field (default_factory = list )
99103
100104
105+ class ProcessingCost (BaseModel ):
106+ """Billing details emitted by manifest v2."""
107+
108+ micro_dollars : Optional [int ] = None
109+ credits : Optional [float ] = None
110+
111+
112+ class ProcessingTiming (BaseModel ):
113+ """Timing details emitted by manifest v2."""
114+
115+ started_at : Optional [str ] = None
116+ completed_at : Optional [str ] = None
117+ duration_ms : Optional [int ] = None
118+
119+
120+ class ProcessingMetadata (BaseModel ):
121+ """Worker-side processing metadata emitted by manifest v2."""
122+
123+ page_count : Optional [int ] = None
124+ billing_status : Optional [str ] = None
125+ cost : Optional [ProcessingCost ] = None
126+ timing : Optional [ProcessingTiming ] = None
127+
128+
101129class Manifest (BaseModel ):
102130 """Top-level manifest describing the result ZIP contents."""
103131
@@ -106,6 +134,7 @@ class Manifest(BaseModel):
106134 data_id : Optional [str ] = None
107135 source_file_name : Optional [str ] = None
108136 processing_date : Optional [str ] = None
137+ processing : Optional [ProcessingMetadata ] = None
109138 checksum : Optional [Checksum ] = None
110139 statistics : Optional [Statistics ] = None
111140 files : Optional [FileIndex ] = None
@@ -123,6 +152,7 @@ class BaseChunk(BaseModel):
123152 type : str
124153 content : str = ""
125154 path : Optional [str ] = None
155+ page_nums : Optional [List [int ]] = None
126156
127157
128158TextChunkTokens : TypeAlias = List [str ]
@@ -136,6 +166,7 @@ class TextChunk(BaseChunk):
136166 tokens : Optional [TextChunkTokens ] = None
137167 keywords : Optional [List [str ]] = None
138168 summary : Optional [str ] = None
169+ connect_to : Optional [List [Dict [str , Any ]]] = None
139170 relationships : Optional [List [Union [Dict [str , Any ], str ]]] = None
140171
141172
@@ -210,6 +241,15 @@ def save(self, directory: Union[str, Path]) -> Path:
210241Chunk = Union [TextChunk , ImageChunk , TableChunk ]
211242
212243
244+ class SlimChunk (BaseModel ):
245+ """Minimal chunk entry emitted in chunks_slim.json."""
246+
247+ type : str
248+ path : Optional [str ] = None
249+ content : str = ""
250+ summary : Optional [str ] = None
251+
252+
213253# ---------------------------------------------------------------------------
214254# ParseResult — the top-level object returned to the user
215255# ---------------------------------------------------------------------------
@@ -225,23 +265,35 @@ class ParseResult:
225265
226266 manifest : Manifest
227267 chunks : List [Chunk ]
268+ chunks_slim : Optional [List [SlimChunk ]]
228269 full_markdown : str
229270 hierarchy : Optional [Any ]
271+ toc_hierarchies : Optional [Any ]
272+ kb_csv : Optional [str ]
273+ hierarchy_view_html : Optional [str ]
230274 raw_zip : bytes
231275
232276 def __init__ (
233277 self ,
234278 * ,
235279 manifest : Manifest ,
236280 chunks : List [Chunk ],
281+ chunks_slim : Optional [List [SlimChunk ]],
237282 full_markdown : str ,
238283 hierarchy : Optional [Any ],
284+ toc_hierarchies : Optional [Any ],
285+ kb_csv : Optional [str ],
286+ hierarchy_view_html : Optional [str ],
239287 raw_zip : bytes ,
240288 ) -> None :
241289 self .manifest = manifest
242290 self .chunks = chunks
291+ self .chunks_slim = chunks_slim
243292 self .full_markdown = full_markdown
244293 self .hierarchy = hierarchy
294+ self .toc_hierarchies = toc_hierarchies
295+ self .kb_csv = kb_csv
296+ self .hierarchy_view_html = hierarchy_view_html
245297 self .raw_zip = raw_zip
246298
247299 # -- convenience properties --
@@ -296,10 +348,58 @@ def save(self, directory: Union[str, Path]) -> Path:
296348 dir_path : Path = Path (directory )
297349 dir_path .mkdir (parents = True , exist_ok = True )
298350
351+ # Manifest / chunks
352+ manifest_path : Path = dir_path / "manifest.json"
353+ manifest_path .write_text (
354+ self .manifest .model_dump_json (indent = 2 ),
355+ encoding = "utf-8" ,
356+ )
357+
358+ chunks_path : Path = dir_path / "chunks.json"
359+ chunks_path .write_text (
360+ json .dumps ([chunk .model_dump () for chunk in self .chunks ], indent = 2 ),
361+ encoding = "utf-8" ,
362+ )
363+
364+ if self .chunks_slim is not None :
365+ chunks_slim_path : Path = dir_path / "chunks_slim.json"
366+ chunks_slim_path .write_text (
367+ json .dumps (
368+ {"chunks" : [chunk .model_dump () for chunk in self .chunks_slim ]},
369+ indent = 2 ,
370+ ),
371+ encoding = "utf-8" ,
372+ )
373+
299374 # Full markdown
300375 md_path : Path = dir_path / "full.md"
301376 md_path .write_text (self .full_markdown , encoding = "utf-8" )
302377
378+ if self .hierarchy is not None :
379+ hierarchy_path : Path = dir_path / "hierarchy.json"
380+ hierarchy_path .write_text (
381+ json .dumps (self .hierarchy , indent = 2 ),
382+ encoding = "utf-8" ,
383+ )
384+
385+ if self .toc_hierarchies is not None :
386+ toc_hierarchies_path : Path = dir_path / "toc_hierarchies.json"
387+ toc_hierarchies_path .write_text (
388+ json .dumps (self .toc_hierarchies , indent = 2 ),
389+ encoding = "utf-8" ,
390+ )
391+
392+ if self .kb_csv is not None :
393+ kb_csv_path : Path = dir_path / "kb.csv"
394+ kb_csv_path .write_text (self .kb_csv , encoding = "utf-8" )
395+
396+ if self .hierarchy_view_html is not None :
397+ hierarchy_view_path : Path = dir_path / "hierarchy_view.html"
398+ hierarchy_view_path .write_text (
399+ self .hierarchy_view_html ,
400+ encoding = "utf-8" ,
401+ )
402+
303403 # Images
304404 if self .image_chunks :
305405 images_dir : Path = dir_path / "images"
0 commit comments