A Rails engine for managing LLM chat conversations with CSV export, auto-titling, and ready-to-use UI components.
- Chat Management — Controller concern (
ChatManageable) for initializing and managing chat arrays with duplicate/nil prevention - Automatic Title Generation — Model concern (
TitleGeneratable) for generating chat titles from initial prompts - CSV Export — Controller concern (
CsvDownloadable) for individual and bulk chat CSV downloads - UI Components — Chat list and chat card partials with Stimulus-powered inline title editing
- Database Migration Generator —
chat_manager:modelinggenerator for creating the chats table - Turbo/Turbolinks Safe — CSV download links work correctly with modern Rails JS frameworks
- Ruby 4.0+
- Rails 8.1+
Add this line to your application's Gemfile:
gem "chat_manager"And then execute:
$ bundle installOr install it yourself as:
$ gem install chat_manager$ rails generate chat_manager:modeling
$ rails db:migrateThis creates the chat_manager_chats table with the following columns:
| Column | Type | Description |
|---|---|---|
uuid |
string (NOT NULL) | Unique identifier for the chat |
title |
string | Chat title (auto-generated or manually set) |
llm_uuid |
string | LLM identifier |
model |
string | Model name/type |
created_at |
datetime | Timestamp |
updated_at |
datetime | Timestamp |
class ChatsController < ApplicationController
include ChatManager::ChatManageable
include ChatManager::CsvDownloadable
def index
initialize_chat(current_user.chats)
set_active_chat_uuid(params[:uuid])
end
endclass Chat < ApplicationRecord
include ChatManager::TitleGeneratable
# You must implement this method
def summarize_for_title(prompt_text, jwt_token)
# Call your LLM API to generate a title from the prompt
# Return a string (max 255 characters)
end
endProvides methods for managing chat arrays in your controller:
initialize_chat(chats) # Initialize with a collection of chats
set_active_chat_uuid(uuid) # Set the active chat UUID
add_chat(chat) # Add a chat (prevents nil and duplicates)Provides CSV export actions:
download_csv # Download a single chat as CSV
download_all_csv # Download all user chats as CSVCSV output includes the following columns: Chat Title, Role, Message Content, Sent At, Model.
Prerequisites: The host application must provide:
current_usermethod in the controller (returning an object with achatsassociation)chatsassociation that supports.includes(messages: :prompt_manager_prompt_execution)ordered_messagesmethod on the Chat model- Each message must have a
roleattribute and aprompt_manager_prompt_executionassociation withpromptandresponseattributes
Generates a chat title from the initial user prompt:
chat.generate_title(prompt_text, jwt_token)Delegates to the summarize_for_title method which must be implemented by the including model.
Use the chat_list helper in your views to render the chat list UI:
<%= chat_list(
->(uuid) { chat_path(uuid) },
active_uuid: @active_uuid,
download_csv_path: ->(uuid) { download_csv_chat_path(uuid) },
download_all_csv_path: download_all_csv_chats_path
) %>Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
card_path |
Positional | Yes | Proc/lambda that receives a UUID string and returns the path for each chat card link |
active_uuid |
Keyword | No | ID of the currently active chat (for highlighting) |
download_csv_path |
Keyword | No | Proc/lambda that receives a UUID string and returns the CSV download path for each chat |
download_all_csv_path |
Keyword | No | Path for the "Download All Chats CSV" button |
The engine provides two partials:
chat_manager/chat_list— Renders the full chat list with optional bulk CSV download buttonchat_manager/chat_card— Renders an individual chat card with:- Title display (truncated to 30 characters)
- Active state highlighting
- Inline title editing via Stimulus (
chat-title-editcontroller) - Optional per-chat CSV download button
The engine includes CSS for the chat interface. Available CSS classes:
.chat-stack— Flex column layout for the chat list.chat-card— Card styling with hover effects and active state (.is-activemodifier).chat-card-row— Flex row layout for card content and download button.chat-card-link— Grid layout for card link area.chat-card-prompt— Title text display with line clamping.chat-card-number— Chat number label.chat-card-download— Per-chat CSV download button.chat-card-title-input— Inline edit input field.chat-download-all— Container for the bulk download button.chat-download-all-link— Bulk download button
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
The gem is available as open source under the terms of the MIT License.