(AI generated. Not reviewed.)
How Fichero Works
This page describes the current shipped architecture on main. It is grounded
in the SwiftUI app under fichero/fichero/ and the FastAPI engine under
fichero-server/src/fichero_server/.
1. Top-level runtime model
Fichero is a two-part system:
fichero/fichero/: the Apple client, built in SwiftUIfichero-server/src/fichero_server/: the Python FastAPI engine
The normal app path is not “Swift reads and writes the library directly.” The app talks to the engine over the HTTP API and the engine owns persistence, workflows, search, and AI behavior.
On the client side:
EngineConfig.swiftdefines the engine host and/apibase URLEmbeddedBackendService.swiftmanages the embedded/local-engine path on macOSFicheroApp.swiftmountsLibraryWindowLibraryWindow.swiftinjects the per-library environment and opensDocumentTabViewDocumentTabView.swifthostsContentView, which is the main workspace shell
On current main, macOS can use a local engine host, while iPhone and iPad use
the configured external-host path rather than starting an embedded engine.
2. Frontend → backend contract
The frontend uses the generated OpenAPI client plus hand-written Swift service wrappers:
fichero/fichero/Services/APIClient.swiftis the shared client wrapper- domain services are hand-written wrappers over the generated client, such as
DocumentService.swift,SearchService.swift,WorkflowService.swift,AnnotationService.swift, andNoteService.swift, with stores underfichero/fichero/Models/
The important architectural rule is that the app does not invent a second backend protocol. The contract is the engine’s OpenAPI surface plus the typed Swift wrappers built on top of it.
3. Backend shape
The engine entry point is fichero_server.api.main. Feature behavior is mostly split
by route module under fichero-server/src/fichero_server/api/routes/.
Examples:
- documents and folders:
api/routes/documents.py - search and saved searches:
api/routes/search.py - entities:
api/routes/entities.py - claims:
api/routes/claims.py - claim curation:
api/routes/claim_curation.py - entity curation:
api/routes/kg_entity_curation.py - workflows:
api/routes/workflows.py
That route layer sits on top of shared storage and workflow modules rather than each route owning its own persistence strategy.
4. Storage: DuckDB + LanceDB
fichero-server/src/fichero_server/db/ is the main storage wrapper.
Current built split:
- DuckDB stores the typed library rows and most queryable metadata
- LanceDB stores vector indexes used for semantic search and KG embeddings
The Database class in db.py wraps both layers. The database comments and
helper methods on current main are explicit that one process owns a library
read-write, DuckDB is the structured store, and LanceDB is the vector store.
Related pieces:
db_manager.pymanages per-libraryDatabaseinstancesdb_embeddings.pyowns the canonical embedding write/search helpers
5. Workflows and the execution engine
The workflow engine is LangGraph-backed on current main.
Grounded code points:
fichero-server/src/fichero_server/execution/runner.pybuilds and compiles a LangGraphStateGraph- workflow tools live under
fichero-server/src/fichero_server/workflows/tools/ - tool registration lives in
fichero-server/src/fichero_server/workflows/registry.py workflows/tools/agent.pywraps workflow tools for LangChain/LangGraph agent use
So the accurate description is:
- route layer accepts workflow requests
- execution runner builds the LangGraph graph
- tools do the real document/AI/search/KG work
6. LLM path
The centralized LLM entry surface is fichero-server/src/fichero_server/llm/.
For current workflow/tool code, the important public helpers are:
chat(...)chat_structured(...)chat_with_tools(...)chat_workflow(...)
chat_workflow(...) is the shared workflow/tool dispatcher. It delegates to
the same centralized helpers rather than each workflow constructing its own
provider path. get_langchain_model(...) still exists, but as the LangChain
model factory under those higher-level entry points.
7. Knowledge-graph extraction path
The current KG extraction pipeline is not one monolithic “KG route.” It is a
workflow/tool pipeline that produces and persists KnowledgeEntity and
KnowledgeClaim rows.
The main shipped path is:
- extract text/records from documents
- run extractor tools
- turn extracted items into entity/claim rows
- optionally write or finalize KG payloads for downstream workflow steps
Grounded code points:
workflows/tools/extract_all.pyis the combined extraction tool and can emitkg_payloadworkflows/tools/extractors.pycontains the typed extractor logic and the persistence helpers that turn extractor output intoKnowledgeEntityandKnowledgeClaimrowsworkflows/tools/_entity_writer.pyis the shared entity/claim write path for deduping, upserting entities, and saving claimsworkflows/tools/kg_writer.pyis the downstream writer forkg_payloadwhen a workflow splits extraction from persistence
That means “KG extraction” is currently a workflow/tool concern first, and a query/render concern second.
8. Entity and claim curation
Entity/claim curation is built as explicit API and workflow surfaces, not just an internal post-processing step.
Current built pieces include:
- CRUD and query routes for entities in
api/routes/entities.py - CRUD and query routes for claims in
api/routes/claims.py - entity curation routes in
api/routes/kg_entity_curation.py - claim curation routes in
api/routes/claim_curation.py - workflow cleanup/merge passes in
workflows/tools/cleanup.pyandworkflows/tools/merge_dedup_only.py
So there are two complementary layers:
- the route layer for reviewer-facing curation and API access
- the workflow/tool layer for extraction cleanup, dedup, and merge flows
9. Where to read next
Use this page as the short mental model, then drill down:
- deeper backend/frontend split: ../contributor/architecture-overview.md
- OpenAPI client path: ../contributor/openapi-and-clients.md
- storage and KG details: ../contributor/data-search-and-kg.md
- workflows and curation: ../contributor/workflows-activity-and-curation.md