fix: pass mime_type from Bricks API to Kreuzberg for correct file type detection#37
Conversation
- Replace BricksDocumentInfo (16 fields) with DocumentSummary (5 fields) in list_bricks_documents - Bedrock returns 400 'compiled grammar is too large' when tool schemas are too complex - Only expose what the LLM needs: id, file_name, mime_type, size, status
…e detection Instead of relying on the temp file extension (which was producing ._pdf from S3 URL paths), pass the mime_type directly to Kreuzberg's extract_file() which supports a mime_type parameter for format override. Also adds _normalize_extension as a safety net for malformed extensions.
Kaiohz
left a comment
There was a problem hiding this comment.
Review PR #37 — fix: pass mime_type from Bricks API to Kreuzberg
Score : 8/10 🟢
✅ Ce qui est excellent
-
Propagation du
mime_typebout en bout — Le flux est clean et logique :BricksApiAdapter.download_document→ReadBricksDocumentUseCase→KreuzbergAdapter.extract_content→extract_file(mime_type=...). Chaque couche fait son job, pas de court-circuit. -
DocumentSummaryPydantic model — Remplacer lelistnon typé par un modèle structuré surlist_bricks_documentsest un vrai plus pour les consumers MCP. Ça donne de l'autocomplétion et de la validation. 💪 -
_normalize_extensioncomme safety net — La regexre.sub(r"^[^a-zA-Z]+", ".", ext.lower())gère proprement les cas tordus (._pdf,..pdf). Le log en warning quand ça normalise est bien pensé. -
Tests — 6 nouveaux tests pour
_normalize_extension, 2 pourKreuzbergAdapter(avec et sansmime_type), 1 pour le use case. Bonne couverture des nouveaux chemins. -
Compat arrière —
mime_type: str = ""en paramètre optionnel surextract_content→ pas de breaking change pour les autres callers.
⚠️ Points à améliorer
-
tuple[bytes, str, str]est fragile — Le retour non nommé(data, filename, mime_type)surdownload_documentest un pattern error-prone. Si un jour on ajoute un 4ème élément, les déstructurationscontent, filename, mime_type = ...vont péter silencieusement ou nécessiter un refactor massif.- 💡 Suggestion : Utiliser un
NamedTupleou unBaseModel:
class DownloadedDocument(BaseModel): data: bytes filename: str mime_type: str
Ça rend le code auto-documenté et résistant aux refactorings.
- 💡 Suggestion : Utiliser un
-
_normalize_extension: le cas..pdf— Le testtest_double_dot_extensions'attend à ce quereport..pdfrestereport..pdf, ce qui est probablement un bug ou à tout le moins un cas que Kreuzberg va rejeter. La regex supprime les caractères non-alpha au début de l'extension, mais..contient un.qui est alpha... Du coup"..pdf"→"..pdf"inchangé. Est-ce intentionnel ? Si oui, un commentaire expliquant pourquoi serait utile. -
Fichiers sans newline finale —
bricks_api_adapter.pyet le fichier tests finissent sans newline (\ No newline at end of filedans le diff). C'est un détail mais ça fait râler certains linters. -
DocumentSummary.mime_typedefault""— Unmime_typevide n'est pas un MIME type valide. Ça serait plus propre d'utiliserOptional[str] = Nonepour distinguer « pas de MIME type connu » d'une chaîne vide qui pourrait être interprétée comme une valeur. -
Logging dans
_extract_filename— Leslogger.debugajoutés sont utiles au debug, maisurl[:200]pour tronquer est un peu magique. Un helper ou une constanteMAX_LOG_URL_LEN = 200rendrait l'intention explicite.
💡 Suggestions optionnelles
- Typer le retour de
list_bricks_documents:list[DocumentSummary]c'est bien, mais siDocumentSummaryest aussi utilisé côté client MCP, envisager de le mettre dans un moduleschemasoudtoséparé plutôt que dans le fichier tools MCP. _normalize_extensionpourrait être une@staticmethodou une fonction utilitaire dans un moduleutils.pysi elle est appelée à grossir — pour l'instant inline c'est ok.
Verdict
PR solide qui fixe un vrai bug de production (._pdf → ValidationError). La propagation du mime_type est la bonne approche, Kreuzberg supportant nativement ce paramètre. Les tests couvrent bien les nouveaux chemins.
Les points d'amélioration sont surtout des questions de robustesse long-terme (NamedTuple/Model au lieu de tuple, Optional[str] au lieu de ""). Rien de bloquant.
🟢 Approuvée avec suggestions — merge OK, mais les suggestions ci-dessus méritent un coup d'œil dans un follow-up.
Summary
mime_typefrom Bricks API throughdownload_document→ReadBricksDocumentUseCase→KreuzbergAdapter.extract_content→extract_file(mime_type=...)mime_typeparameter to override format detection — no need to rely on temp file extensionValidationError: Unknown extension: ._pdfcaused by S3 URL paths producing malformed extensions_normalize_extensionas safety net for future edge casesBricksApiPort.download_documentsignature:(bytes, str)→(bytes, str, str)(data, filename, mime_type)DocumentReaderPort.extract_contentsignature: add optionalmime_typeparamTest plan
TestNormalizeExtension(6 tests),test_extract_content_passes_mime_type,test_extract_content_without_mime_type,test_execute_passes_mime_type_to_document_reader