Files
Upload, browse, search, tag, and version documents in the file library.
The file library is a central place to keep documents, attachments, and other assets alongside the rest of your workspace data. You can upload files, search and filter them, tag them, and keep version history. The data model also relates files to the contacts and conversations they belong to. You can link a file to contacts and to a conversation thread manually, at upload or on its detail page. Open it from Files in the dashboard (/dashboard/files).
The Files pages are available to any signed-in team member. Uploading, editing, and deleting files require an admin role — viewing and searching do not.
The file library
The library lists your files newest-first. A toolbar across the top gives you three controls:
- Search — type in the search box to find files by name, title, tags, AI summary, auto-detected tags, or the start of their extracted text. Search uses a full-text index and updates as you type. Semantic (meaning-based) search is not wired to this box — see Search.
- Source filter — chips for All sources, Uploads, Email attachments, and AI generated narrow the list to a single origin.
- View toggle — switch between a grid of cards and a compact list table.
Each file shows its name (or title, if you've set one), type, size, source, and creation date. Click any file to open its detail page.
File source
Every file records where it came from. The source is shown as a badge in the list and on the detail page:
| Source | Badge | Meaning |
|---|---|---|
upload | Upload | Added by a team member through the upload dialog. |
email_attachment | Tagged as originating from an inbound email attachment. | |
agent_generated | AI | Tagged as produced by the AI agent. |
The source is a label you choose in the upload dialog. Today every file is added through that dialog, so even an "AI generated" file is one you uploaded and labelled yourself. Inbound email attachments, however, ARE captured automatically into the library (source email_attachment) on delivery; only agent output is not yet auto-captured.
Uploading files
Click Upload to open the upload dialog, then:
Choose a file
Drag a file onto the drop zone or click to browse. Any file type is accepted. The dialog enforces a 50 MB limit; oversized files are rejected by the server's create mutation, not just hidden behind a UI hint.
Add a title and tags (optional)
Give the file a descriptive title (otherwise the original filename is used as its display name) and a comma-separated list of tags to label and organise it. Both are searchable straight away — a file is findable by its tags before the AI pipeline has run.
Pick a source
Choose Manual Upload, Email Attachment, or AI Generated to label where the file came from. This only sets the source badge — it doesn't change how the file is processed.
Upload
The file is stored and added to the library immediately. You'll land back in the list with the new file at the top.
File detail
Opening a file shows everything Owlat knows about it. The left column holds the file's content sections; the right column holds metadata.
- Title — click the title to rename it inline. The original filename is always shown beneath.
- Download — opens the stored file in a new tab.
- Details — MIME type, size, creation date, and source badge.
- Tags — edit the comma-separated tags with the pencil button. Auto-detected tags, when present, appear in a separate group. Editing tags or the title re-indexes the file immediately, so it's findable by the new values.
- Linked Contacts — contacts this file is associated with, each linking to its contact record.
- Linked Conversation — the thread this file belongs to, linking into the Team Inbox. Use the pencil button to search conversations by subject or sender and pick one, or clear the link.
AI summary, extracted text, and auto-tags
The detail page has collapsible sections for an AI Summary, the file's Extracted Text, and an Auto-detected tag group. These only appear when the underlying file actually has that data.
A processing pipeline (apps/api/convex/semanticFileProcessing.ts) extracts text, writes an AI summary, generates auto-tags, and computes a search embedding for each file. It is scheduled on upload (semanticFileProcessing.processFile, kicked off by the create mutation) and a safety-net cron re-runs it every 15 minutes for recent files still missing an embedding. The summary, auto-tags, and embedding are only produced when an LLM and embedding provider are configured — without them those sections stay hidden. Note that plain text, HTML, JSON, CSV, and PDF are text-extracted, but Word, Excel, and images yield only a filename placeholder, and images are not OCR'd.
Once a file has real extracted text, the pipeline also mines it into the Knowledge Graph (source File), so facts in your documents become typed entries you can browse and search alongside knowledge captured from email. Binary stubs (a Word/Excel/image placeholder) carry no text, so they don't produce knowledge entries.
Version history
Each file tracks a version number and a pointer to its previous version, and the detail page renders the full version chain as a timeline. The current version is marked.
The data model supports versions (a new upload can reference a previousVersionId), but the upload dialog doesn't yet offer a "replace / new version" option, so in practice every upload is a standalone file at version 1.
Linking files to contacts and conversations
A file can be associated with one or more contacts and with a single conversation thread:
- Contacts — linked contacts appear in the file's right column and link straight to each contact record. On a contact's own page, the Files tab lists every file linked to that contact (uploads and attachments alike). See Contacts and Audience Data.
- Conversation — when a file is tied to a thread, the Linked Conversation panel links to that conversation in the Team Inbox.
You set both kinds of link in the same two places:
- At upload — the upload dialog has a Linked contacts picker and a Linked conversation picker. Search a contact by name or email and add as many as apply; search a conversation by subject or sender and pick one. Both are saved with the file.
- After upload — the file detail page's Linked Contacts and Linked Conversation panels each have an edit (pencil) control that opens the same picker, so you can add, change, or remove links at any time.
The conversation picker searches the most recent shared-inbox threads by subject and participant address. It's admin-only, like every other file edit.
Inbound email attachments are captured on delivery and, when the sender address already matches an existing contact, linked automatically to that sender contact (they then appear on that contact's Files tab). A sender with no existing contact stays org-general — capture never creates a contact. Captured attachments carry the source message's Message-ID as provenance. Automatic thread-linking on capture is still not wired up (see below).
Manual thread linking is available on both the upload dialog and the detail page. What's still missing is the automatic path: a captured email attachment does not inherit its source message's thread, so you have to pick the conversation yourself.
Search
The search box runs a full-text search over each file's searchable text. It's fast and forgiving of partial words, and it respects the active source filter.
A file's searchable text is composed from its filename (whole, and split into words, so q3-budget_v2.pdf matches "budget"), its title, its tags, and — once the AI pipeline has run — its summary, auto-detected tags, and the first stretch of its extracted text. It is rebuilt whenever the file changes: on upload, when processing finishes, and on every title or tag edit.
Rows created earlier carry the old filename-and-title-only index entry. An operator re-indexes them once with
npx convex run migrations/0038_rebuild_file_search_text:run — it's idempotent and safe to re-run.
The library supports semantic (vector) search — files carry an embedding field and the table has a vector index. Real vector search lives in the semanticFileProcessing.semanticSearch action (used by the agent pipeline). The dashboard search box, however, calls the full-text search query: Convex vector search runs only on an action ctx, never in a query, so the live-updating search box can't call it. Meaning-based retrieval is available through ask-anything (below).
Beyond the dashboard search box, the ask-anything box (QuickQueryPanel, on the Knowledge Graph dashboard) does semantically retrieve across the file store: quickQuery.ask fans out over semanticFileProcessing.semanticSearch (real vector_files search) and the Knowledge Graph, then LLM-synthesizes a grounded answer that cites the files and entries it used. So a natural-language question can surface an uploaded contract or invoice by meaning, where the library's own search box matches on the words actually in the file's name, tags, summary, and text.
Current limitations
A quick summary of what's shipped versus planned, so you know what to expect:
| Capability | Status |
|---|---|
| Upload, browse, grid/list views, source filter | Available |
| Full-text search by filename and title | Available |
| Search by tags, AI summary, auto-tags, or extracted text | Available (re-indexed on upload, on processing, and on every edit) |
| Manual tags, inline title editing | Available |
| Version history timeline (chain display, current marked, per-version download) | Available (no "new version" upload action) |
| Manual file→contact linking (upload picker + detail-page editor) | Available |
| Manual file→conversation linking (upload picker + detail-page editor) | Available |
| Text extraction for plain text, HTML, JSON, CSV, PDF | Available |
| Text extraction for Word / Excel, image OCR | Not yet active |
| AI summaries and auto-tags on upload | Available (requires a configured LLM provider) |
| Semantic / vector search in the dashboard search box | Not yet active (available through ask-anything and the agent) |
| Automatic capture of email attachments | Available |
| Auto-linking captured attachments to an existing sender contact | Available |
| Auto-linking captured attachments to a conversation thread | Not yet active (link it manually) |
| Automatic capture of agent output | Not yet active |