Repository navigation
File Support Architecture
Canonical source:
docs/FILE_SUPPORT_ARCHITECTURE.md— this page is rendered from it on every publish; edit the source.
The file-service (port 4006) handles file upload, validation, storage, chunking, and retrieval. It uses PostgreSQL (claw_files) with Prisma ORM and communicates via RabbitMQ for async processing events.
User Upload → Validate (type/size) → Store (local disk) → Chunk (by MIME type) → Retrieve (internal API)
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Frontend ZodValidation file-storage FileProcessing /internal/files
file picker pipe + DTO utility.ts Manager :id/chunks
-
FilesControlleraccepts multipart file upload - DTO validation via
upload-file.dto.tswith Zod pipe - Auth guard enforces JWT authentication
- MIME type checking at controller level
- File size limits enforced
- Supported types: JSON, CSV, Markdown, plain text
-
file-storage.utility.tswrapsfsoperations (follows library wrapping rule) - Files written to local disk at
storagePath - File metadata persisted to PostgreSQL via
FilesRepository
-
FileProcessingManagerreads file from disk, splits by MIME type - JSON: splits by top-level keys (objects) or array items
- CSV: splits into 50-row batches, preserving header row
- Markdown: splits by heading boundaries (
# ## ###) - Plain text: splits by paragraph (double newline)
- Chunks stored via
FileChunksRepository.createMany() -
FILE_CHUNKEDevent published to RabbitMQ on success -
file.failedevent published on error
-
FilesInternalControllerat/internal/files/:id/chunks— public (no auth), service-to-service only - Returns all
FileChunk[]for a given file ID - Used by chat-service during context assembly to inject file content
| MIME Type | Chunking Strategy | Status |
|---|---|---|
application/json |
Top-level keys or array items | Working |
text/csv |
50-row batches with header | Working |
text/markdown |
Section boundaries (headings) | Working |
text/plain (default) |
Paragraph splits | Working |
| Not implemented | Missing | |
| Images (PNG/JPG) | Not implemented | Missing |
| DOCX/XLSX | Not implemented | Missing |
-
Chunking pipeline works end-to-end —
FileProcessingManager.processFile()reads files, splits by type, stores chunks in DB -
Internal retrieval endpoint exists —
/internal/files/:id/chunksreturns chunks for context assembly -
File IDs in message DTO — chat-service accepts
fileIdsin message payloads - File attachment picker in chat UI — frontend has file upload UI component
-
Ingestion status tracking —
FileIngestionStatusenum (PENDING/PROCESSING/COMPLETED/FAILED) with real state transitions -
RabbitMQ events —
FILE_CHUNKEDandfile.failedevents are published - Per-file-type parsing logic — JSON, CSV, Markdown, and text each have dedicated splitters
- Error handling — failed processing updates status to FAILED and publishes error event
- No vector embeddings — chunks are stored as raw text, no embedding generation, no similarity search
-
No PDF parsing — no
pdf-parseor equivalent library, PDF uploads will fall through to plain text splitter - No image/vision support — no OCR, no vision model integration, no image description pipeline
- No semantic search — file chunks are retrieved by file ID only, no query-based retrieval
- No chunk size limits — JSON objects or CSV batches could produce arbitrarily large chunks
- No overlap between chunks — no sliding window, context can be lost at chunk boundaries
- No file deduplication — same file can be uploaded multiple times
- No file deletion cascade — unclear if deleting a file removes its chunks
-
No streaming for large files —
readFileloads entire file into memory - No DOCX/XLSX/HTML parsers — only 4 MIME types handled
┌──────────────────────────────────────────────────────────────┐
│ FILE SERVICE (4006) │
│ │
│ POST /files/upload │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Validate │───▶│ Store to │───▶│ Persist metadata│ │
│ │ (Zod DTO) │ │ local disk │ │ (PostgreSQL) │ │
│ └─────────────┘ └──────────────┘ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Process File │ │
│ │ (async) │ │
│ └──────┬───────┘ │
│ │ │
│ ┌────────────────────┼──────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────┐ │
│ │ splitJson│ │ splitCsv │ │split │ │
│ │ │ │ │ │Text │ │
│ └────┬─────┘ └────┬─────┘ └──┬───┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ FileChunksRepository.createMany() │ │
│ └──────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ RabbitMQ: FILE_CHUNKED │
│ │
│ GET /internal/files/:id/chunks ◄── chat-service calls this │
│ │
└──────────────────────────────────────────────────────────────┘
FileProcessingManager
├── processFile(file) — orchestrator
├── splitIntoChunks(content) — filters empties, assigns indices
├── splitByType(content, mime) — dispatcher by MIME type
├── splitJson(content) — JSON-specific logic
├── splitCsv(content) — CSV-specific logic (50-row batches)
├── splitMarkdown(content) — heading-based splitting
└── splitText(content) — paragraph-based fallback
- Clean separation of concerns (repository/manager/controller)
- Each MIME type has a dedicated splitting strategy
- Follows the library wrapping rule (file I/O wrapped in utility)
- Ingestion status provides visibility into pipeline state
- All parsing logic in a single manager class — should extract per-type parsers
- No pluggable parser interface — adding new types requires modifying the switch statement
- No chunk metadata (line numbers, section titles, byte offsets)
- No configurable chunk sizes
| # | Check | Status | Notes |
|---|---|---|---|
| 1 | Can a user upload a file and see it in the UI? | REAL | Upload endpoint + file picker exist |
| 2 | Are uploaded files actually stored on disk? | REAL |
file-storage.utility.ts writes to disk |
| 3 | Are files chunked after upload? | REAL |
FileProcessingManager.processFile() chunks them |
| 4 | Can chat-service retrieve chunks? | REAL |
/internal/files/:id/chunks endpoint exists |
| 5 | Do file chunks influence AI responses? | PARTIAL | Chunks are fetched during context assembly, but no semantic relevance filtering |
| 6 | Can users search within uploaded files? | FAKE | No search endpoint, no embeddings, no similarity query |
| 7 | Does the UI show file processing status? | UNKNOWN | Ingestion status tracked in DB, unclear if frontend polls it |
| 8 | Are PDF files supported? | FAKE | No PDF parser, falls through to plain text |
| 9 | Do large files get processed correctly? | RISKY | Entire file loaded into memory, no streaming |
| 10 | Are chunks relevant to the user's query? | NO | All chunks for a file are injected, no relevance filtering |
File support is partially real. The upload-store-chunk pipeline works. The critical gap is the absence of vector embeddings and semantic search — files are chunked but all chunks are dumped into context regardless of relevance, which means file grounding is brute-force rather than intelligent.
- Add chunk size limits + overlap — prevent context overflow, maintain coherence
- Add vector embeddings — use pgvector (already available in PG images) for semantic retrieval
- Add relevance filtering — only inject chunks that match the user's query
-
Add PDF parser —
pdf-parseor similar, most commonly uploaded file type - Extract parser interface — make parsers pluggable for new MIME types
- Add chunk metadata — section titles, line numbers, byte ranges for attribution
- Stream large files — avoid loading entire file into memory
- Add file deduplication — hash-based detection of duplicate uploads
ClawAI Wiki · source-controlled under wiki/ · generated/mirrored from the current repository knowledge layer.
ClawAI Wiki
Product
- Product-Vision
- Flagship-Features
- Business-Overview
- Requirements-Register
- Drift-Log
- Runtime-Managed-Connector-Providers
- Threads
- ADR-Index
Architecture
- System-at-a-Glance
- Architecture-Map
- System-Architecture
- Message-Flow
- End-to-End-Data-Flow
- Routing-Engine
- Event-Bus
- Security-Architecture
Platform
- Backend-Services
- Frontend-Architecture
- Shared-Packages
- Database-Reference
- API-Reference
- Provider-Catalog
- Memory-and-Context-Architecture
- File-Support-Architecture
- Research-and-Web-Crawling
Runtime & Ops
- Docker-Guide
- Nginx-Reference
- CI-CD-Pipeline
- Logging-and-Observability
- Operational-Runbooks
- Troubleshooting
Quality
Engineering OS
- AI-Native-Engineering-OS
- Generated-Manifests
- Rules-Catalog
- Skills-Catalog
- Context-Layer
- Engineering-Memory
- Tooling-and-Automation
- Scripts-and-Operations
- ESLint-and-Architecture-Enforcement
- Extended-Work-Skills
Agents
Reference