Implement File References in Chat Messages #164
Labels
No labels
Epic 5
MCP
P1
PR-0
PR-1
api
api-layer
architecture
area:backend
area:frontend
arrow
authentication
backend
bug
chat
client
clipboard
common-module
compose
cross-cutting
cross-cutting-requirement
data-layer
data-models
database
desktop-client
documentation
duplicate
enhancement
epic
epic-1
epic-2
epic-3
epic-4
epic-5
epic-6
epic-7
epic-llm-config
error-handling
feature
frontend
good first issue
help wanted
implementation
infrastructure
installer
invalid
kotlin
ktor
llm
medium-priority
message
multiplatform
needs-review
needs-triage
packaging
performance
phase-1
phase-2
phase-3
phase-4
phase-5
phase3
phase:3
priority: high
question
refactor
refactoring
resource-sharing
security
server
server-module
services
session
session-management
settings
setup
shutdown
state
storage
streaming
sub-issue
tests
tooling
type:task
ui
ui/ux
user-accounts
user-management
ux
viewmodel
websocket
windows
windows-integration
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Torvian.eu/chatbot#164
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
Add comprehensive file reference support to allow users to attach files to messages, send them inline or as non-inline references, and display them as interactive badges throughout the chat interface. Files can be referenced without sending content (for LLM tool use with MCP) or with content included (for direct context, text files only).
Implementation Steps
Create data models - Add
FileReferencedata class incommon/src/commonMain/kotlin/eu/torvian/chatbot/common/models/core/with stored properties:basePath,relativePath,fileSize,lastModified,mimeType,content(optional String),inlinePosition(optional Int for cursor placement); add computed propertiesfileName(fromrelativePath) andisInline(frominlinePosition != null)Extend database schema - Add
fileReferencesTEXT column (JSON array) toChatMessageTableand updateChatMessage.UserMessageandChatMessage.AssistantMessageto includefileReferences: List<FileReference>propertyUpdate persistence layer - Modify
MessageDaoExposedto serialize/deserialize file references using kotlinx.serialization JSON, updatetoUserMessageandtoAssistantMessagemappers to handle file references column with default empty list for existing messagesExtend API contracts - Add
fileReferences: List<FileReference>field toProcessNewMessageRequestandInsertMessageRequest, add validation inChatServicefor 5MB total content size limit across all file references with contentImplement UI badge components - Create
FileReferenceBadge.ktcomposable (similar toToolCallBadge) showing file name and file icon, createFileReferenceDetailsDialog.ktmodal (similar toToolCallDetailsDialog) displaying full path, base path, relative path, size, modified date, MIME type, whether content is included, and scrollable content previewAdd file picker UI - Extend
InputAreawith file attachment button (in action row below text field), add badge display section for attached non-inline file references with remove button, implement base path selector UI with automatic detection of common parent path from selected files, add content inclusion toggle per file (default off for files > 100KB)Add state management - Extend
ChatAreaStatewithattachedFileReferences: List<FileReference>andbasePathOverride: String?(stored in ViewModel only, per session), add actions toChatAreaActionsfor file operations:onAddFiles,onRemoveFile,onSelectBasePath,onToggleFileContentInclusionDisplay badges in messages - Update
MessageItemto render non-inline file reference badges below tool call badges section in new "Files" section, render inline file reference badges within the message content at their character positions using custom text rendering, add click handlers to openFileReferenceDetailsDialogwith file detailsImplement LLM context integration - Update
ChatServicemessage preparation to build LLM context string: append non-inline references as "\n\nReferenced files: [file1.txt, file2.txt]" at end of message, insert inline references atinlinePositionby injecting filecontentwhen present or"[reference: filename.txt]"placeholder when absent, preserve original message content structureAdd platform-specific file picker - Create
expect fun selectFiles(): List<SelectedFileInfo>?incommonMainwith data class for file path/size/lastModified, implement desktop version indesktopMainusingJFileChooserwith multi-select, read file metadata and attempt UTF-8 content reading with validation (null byte check), calculate common parent path across selections for default base path, enforce 5MB total content limit with user-friendly errorImplement file re-reading on reuse - When user selects file references from previous messages for new message (future feature), re-read files from disk using stored
basePath + relativePath, updatecontent,fileSize, andlastModifiedfields, preserverelativePathandbasePathfrom original, show error notification if file not found or not readable, allow user to browse for moved fileKey Constraints
contentfield from FileReference if present - no file handling on backendcontentatinlinePosition, or"[reference: filename.txt]"if content absentConsiderations for Implementation
Database migration - Add
fileReferencescolumn to existingchat_messagestable with ALTER TABLE statement, default to empty JSON array'[]'for existing rowsLarge file content warnings - Show warning icon/tooltip on files > 1MB when user enables content inclusion, suggest using reference-only mode for large files
MIME type detection - Use file extension mapping as primary method with fallback to
"application/octet-stream", validate text MIME types (text/*, application/json, application/xml) against UTF-8 decode successMessage content length limits - Consider separate limit on final message content length after inline file content injection (e.g., 1MB text limit for LLM context window considerations)
Relative path normalization - Normalize path separators to forward slash
/for cross-platform consistency in stored references, convert back to platform-specific separator when reading filesFuture Implementation
Add/remove inline file references in UI - Implement custom TextField with "#" key trigger for file reference popup, show list of attached files for current message, allow inline insertion at cursor position with visual badge rendering, support removal via backspace or click-to-remove
Select file references from previous messages - Dialog to browse conversation history, filter messages with file references, select existing references, option to insert inline or non-inline in current message with automatic file re-reading
Tech Stack