mirror of
https://github.com/larchanka/manbot.git
synced 2026-05-13 21:42:08 +00:00
2.1 KiB
2.1 KiB
FP-07: Build the File Processor Service
File: src/services/file-processor.ts
Dependencies: FP-03, FP-04, FP-05, FP-06
Phase: 3 — File Processor Process
Description
Create the file-processor as an independent BaseProcess subprocess. It listens for file.process envelopes, routes the file to the appropriate handler (text reader, image OCR, audio transcription), and responds with a ProcessedFile result. After processing, it deletes the original file from disk.
Acceptance Criteria
- Extends
BaseProcesswithprocessName: "file-processor" - Handles
file.processenvelope withFileProcessRequestpayload - Routing logic:
category: 'text'→ read file withfs/promises.readFile(UTF-8)- If content.length <=
textMaxInlineChars: respond withtype: 'text', full content - If content.length >
textMaxInlineChars: respond withtype: 'text_long', full content (chunking/summarizing is Orchestrator's responsibility — see FP-10)
- If content.length <=
category: 'image'andocrEnabled: true→ callLemonadeAdapter.chatWithImage()with OCR prompt; respond withtype: 'image_ocr'category: 'audio'→ callconvertToWav()thentranscribeAudio(); respond withtype: 'audio_transcript'category: 'unknown'→ respond withtype: 'ignored', empty content
- After any processing attempt (success or failure), delete the original file from disk
- If audio: also delete the intermediate
.wavfile - On processing error: respond with a standard
errorenvelope (do NOT crash the process) - Emit
event.file.processedfire-and-forget tologgerafter each file
Implementation Notes
- OCR prompt:
"Examine this image carefully. If it contains readable text, extract ALL text verbatim. If it contains no significant text, describe the image in detail. Return ONLY the extracted text or description — no preamble." - Use
fs/promises.unlink()for file deletion; wrap in try/catch (file may already be gone) - The service is stateless — no database, no in-memory state between requests
- Register in
main()function at the bottom, callingagent.start()— follow planner-agent.ts pattern