ruby_llm_community 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -7
- data/lib/generators/ruby_llm/chat_ui/chat_ui_generator.rb +127 -67
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/chats_controller.rb.tt +12 -12
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/messages_controller.rb.tt +7 -7
- data/lib/generators/ruby_llm/chat_ui/templates/controllers/models_controller.rb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/jobs/chat_response_job.rb.tt +6 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_chat.html.erb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/_form.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/index.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/new.html.erb.tt +4 -4
- data/lib/generators/ruby_llm/chat_ui/templates/views/chats/show.html.erb.tt +8 -8
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_content.html.erb.tt +1 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_form.html.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_message.html.erb.tt +9 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/_tool_calls.html.erb.tt +7 -0
- data/lib/generators/ruby_llm/chat_ui/templates/views/messages/create.turbo_stream.erb.tt +5 -5
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/_model.html.erb.tt +9 -9
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/index.html.erb.tt +4 -6
- data/lib/generators/ruby_llm/chat_ui/templates/views/models/show.html.erb.tt +11 -11
- data/lib/generators/ruby_llm/generator_helpers.rb +131 -87
- data/lib/generators/ruby_llm/install/install_generator.rb +75 -73
- data/lib/generators/ruby_llm/install/templates/add_references_to_chats_tool_calls_and_messages_migration.rb.tt +9 -0
- data/lib/generators/ruby_llm/install/templates/create_chats_migration.rb.tt +0 -1
- data/lib/generators/ruby_llm/install/templates/create_messages_migration.rb.tt +3 -3
- data/lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb.tt +0 -1
- data/lib/generators/ruby_llm/install/templates/initializer.rb.tt +1 -1
- data/lib/generators/ruby_llm/upgrade_to_v1_7/upgrade_to_v1_7_generator.rb +88 -85
- data/lib/generators/ruby_llm/upgrade_to_v1_9/templates/add_v1_9_message_columns.rb.tt +15 -0
- data/lib/generators/ruby_llm/upgrade_to_v1_9/upgrade_to_v1_9_generator.rb +49 -0
- data/lib/ruby_llm/active_record/acts_as.rb +17 -8
- data/lib/ruby_llm/active_record/chat_methods.rb +41 -13
- data/lib/ruby_llm/active_record/message_methods.rb +11 -2
- data/lib/ruby_llm/active_record/model_methods.rb +1 -1
- data/lib/ruby_llm/aliases.json +46 -20
- data/lib/ruby_llm/attachment.rb +8 -0
- data/lib/ruby_llm/chat.rb +13 -2
- data/lib/ruby_llm/configuration.rb +10 -1
- data/lib/ruby_llm/connection.rb +4 -4
- data/lib/ruby_llm/content.rb +23 -0
- data/lib/ruby_llm/message.rb +17 -9
- data/lib/ruby_llm/model/info.rb +4 -0
- data/lib/ruby_llm/models.json +12050 -9940
- data/lib/ruby_llm/models.rb +21 -25
- data/lib/ruby_llm/moderation.rb +56 -0
- data/lib/ruby_llm/provider.rb +29 -1
- data/lib/ruby_llm/providers/anthropic/chat.rb +18 -5
- data/lib/ruby_llm/providers/anthropic/content.rb +44 -0
- data/lib/ruby_llm/providers/anthropic/media.rb +5 -4
- data/lib/ruby_llm/providers/anthropic/models.rb +9 -2
- data/lib/ruby_llm/providers/anthropic/tools.rb +20 -18
- data/lib/ruby_llm/providers/bedrock/media.rb +2 -1
- data/lib/ruby_llm/providers/bedrock/streaming/content_extraction.rb +9 -2
- data/lib/ruby_llm/providers/gemini/chat.rb +353 -72
- data/lib/ruby_llm/providers/gemini/media.rb +59 -1
- data/lib/ruby_llm/providers/gemini/tools.rb +146 -25
- data/lib/ruby_llm/providers/gemini/transcription.rb +116 -0
- data/lib/ruby_llm/providers/gemini.rb +2 -1
- data/lib/ruby_llm/providers/gpustack/media.rb +1 -0
- data/lib/ruby_llm/providers/ollama/media.rb +1 -0
- data/lib/ruby_llm/providers/openai/capabilities.rb +15 -7
- data/lib/ruby_llm/providers/openai/chat.rb +7 -3
- data/lib/ruby_llm/providers/openai/media.rb +2 -1
- data/lib/ruby_llm/providers/openai/moderation.rb +34 -0
- data/lib/ruby_llm/providers/openai/streaming.rb +7 -3
- data/lib/ruby_llm/providers/openai/tools.rb +34 -12
- data/lib/ruby_llm/providers/openai/transcription.rb +70 -0
- data/lib/ruby_llm/providers/openai_base.rb +2 -0
- data/lib/ruby_llm/providers/red_candle/capabilities.rb +124 -0
- data/lib/ruby_llm/providers/red_candle/chat.rb +317 -0
- data/lib/ruby_llm/providers/red_candle/models.rb +121 -0
- data/lib/ruby_llm/providers/red_candle/streaming.rb +40 -0
- data/lib/ruby_llm/providers/red_candle.rb +90 -0
- data/lib/ruby_llm/providers/vertexai/transcription.rb +16 -0
- data/lib/ruby_llm/providers/vertexai.rb +3 -0
- data/lib/ruby_llm/railtie.rb +1 -1
- data/lib/ruby_llm/stream_accumulator.rb +8 -12
- data/lib/ruby_llm/tool.rb +126 -0
- data/lib/ruby_llm/transcription.rb +35 -0
- data/lib/ruby_llm/utils.rb +46 -0
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm_community.rb +38 -1
- metadata +35 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b347c49cf17f54616f1a3dae46674509ab2a5809bc36522cf6d2275da8a3605d
|
|
4
|
+
data.tar.gz: 7d80d568b98caeb73b4f36e6c6e610e2dac201b455cc270ea9001cbec5e1a839
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 320df6f2d9250ea9df1fbea5db215927fe9ae5665344a3065fd2f185ae8b53f38e8ab4c7f174258cd290a6d8b5cabb8277a8c2a91b3d6d5f4e3094437a508fcd
|
|
7
|
+
data.tar.gz: 92caeac605d923fd1c1eef4f5d8cc39f57e0972a33a57c09c518d3694da5202b0df7de5023135e9183931085bdfa5fadc76d8a354697ff11cbaa9255cc2b673c
|
data/README.md
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="https://chatwithwork.com/logotype-dark.svg"><img src="https://chatwithwork.com/logotype.svg" alt="Chat with Work" height="30" align="absmiddle"></picture>](https://chatwithwork.com) — *Claude Code for your documents*
|
|
11
11
|
|
|
12
|
-
[](https://badge.fury.io/rb/ruby_llm)
|
|
13
|
+
[](https://github.com/rubocop/rubocop)
|
|
14
14
|
[](https://rubygems.org/gems/ruby_llm)
|
|
15
15
|
[](https://codecov.io/gh/crmne/ruby_llm)
|
|
16
16
|
|
|
@@ -18,7 +18,7 @@ Battle tested at [<picture><source media="(prefers-color-scheme: dark)" srcset="
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
> [!NOTE]
|
|
21
|
-
> Using RubyLLM
|
|
21
|
+
> Using RubyLLM? [Share your story](https://tally.so/r/3Na02p)! Takes 5 minutes.
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
@@ -40,6 +40,7 @@ Some examples --
|
|
|
40
40
|
- Image editing for Gemini and OpenAI
|
|
41
41
|
- Responses API for OpenAI
|
|
42
42
|
- xAI provider that supports Grok 2, Grok 3, Grok 4, and Grok Code
|
|
43
|
+
- Red Candle provider
|
|
43
44
|
|
|
44
45
|
This project is intended to be compatible with RubyLLM. I will attempt to keep it up to date as Carmine pushes commits often.
|
|
45
46
|
|
|
@@ -84,6 +85,16 @@ RubyLLM.paint "a sunset over mountains in watercolor style"
|
|
|
84
85
|
RubyLLM.embed "Ruby is elegant and expressive"
|
|
85
86
|
```
|
|
86
87
|
|
|
88
|
+
```ruby
|
|
89
|
+
# Transcribe audio to text
|
|
90
|
+
RubyLLM.transcribe "meeting.wav"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
# Moderate content for safety
|
|
95
|
+
RubyLLM.moderate "Check if this text is safe"
|
|
96
|
+
```
|
|
97
|
+
|
|
87
98
|
```ruby
|
|
88
99
|
# Let AI use your code
|
|
89
100
|
class Weather < RubyLLM::Tool
|
|
@@ -117,17 +128,18 @@ response = chat.with_schema(ProductSchema).ask "Analyze this product", with: "pr
|
|
|
117
128
|
|
|
118
129
|
* **Chat:** Conversational AI with `RubyLLM.chat`
|
|
119
130
|
* **Vision:** Analyze images and videos
|
|
120
|
-
* **Audio:** Transcribe and understand speech
|
|
131
|
+
* **Audio:** Transcribe and understand speech with `RubyLLM.transcribe`
|
|
121
132
|
* **Documents:** Extract from PDFs, CSVs, JSON, any file type
|
|
122
133
|
* **Image generation:** Create images with `RubyLLM.paint`
|
|
123
|
-
* **Embeddings:**
|
|
134
|
+
* **Embeddings:** Generate embeddings with `RubyLLM.embed`
|
|
135
|
+
* **Moderation:** Content safety with `RubyLLM.moderate`
|
|
124
136
|
* **Tools:** Let AI call your Ruby methods
|
|
125
137
|
* **Structured output:** JSON schemas that just work
|
|
126
138
|
* **Streaming:** Real-time responses with blocks
|
|
127
139
|
* **Rails:** ActiveRecord integration with `acts_as_chat`
|
|
128
140
|
* **Async:** Fiber-based concurrency
|
|
129
141
|
* **Model registry:** 500+ models with capability detection and pricing
|
|
130
|
-
* **Providers:** OpenAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, and any OpenAI-compatible API
|
|
142
|
+
* **Providers:** OpenAI, Anthropic, Gemini, VertexAI, Bedrock, DeepSeek, Mistral, Ollama, OpenRouter, Perplexity, GPUStack, [RedCandle](https://github.com/scientist-labs/red-candle), and any OpenAI-compatible API
|
|
131
143
|
|
|
132
144
|
## Installation
|
|
133
145
|
|
|
@@ -148,7 +160,11 @@ end
|
|
|
148
160
|
## Rails
|
|
149
161
|
|
|
150
162
|
```bash
|
|
163
|
+
# Install Rails Integration
|
|
151
164
|
rails generate ruby_llm:install
|
|
165
|
+
|
|
166
|
+
# Add Chat UI (optional)
|
|
167
|
+
rails generate ruby_llm:chat_ui
|
|
152
168
|
```
|
|
153
169
|
|
|
154
170
|
```ruby
|
|
@@ -156,10 +172,12 @@ class Chat < ApplicationRecord
|
|
|
156
172
|
acts_as_chat
|
|
157
173
|
end
|
|
158
174
|
|
|
159
|
-
chat = Chat.create!
|
|
175
|
+
chat = Chat.create! model: "claude-sonnet-4"
|
|
160
176
|
chat.ask "What's in this file?", with: "report.pdf"
|
|
161
177
|
```
|
|
162
178
|
|
|
179
|
+
Visit `http://localhost:3000/chats` for a ready-to-use chat interface!
|
|
180
|
+
|
|
163
181
|
## Documentation
|
|
164
182
|
|
|
165
183
|
[rubyllm.com](https://rubyllm.com)
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rails/generators'
|
|
4
|
+
require_relative '../generator_helpers'
|
|
4
5
|
|
|
5
6
|
module RubyLLM
|
|
6
7
|
module Generators
|
|
7
8
|
# Generates a simple chat UI scaffold for RubyLLM
|
|
8
9
|
class ChatUIGenerator < Rails::Generators::Base
|
|
10
|
+
include RubyLLM::Generators::GeneratorHelpers
|
|
11
|
+
|
|
9
12
|
source_root File.expand_path('templates', __dir__)
|
|
10
13
|
|
|
11
14
|
namespace 'ruby_llm:chat_ui'
|
|
@@ -15,113 +18,170 @@ module RubyLLM
|
|
|
15
18
|
desc 'Creates a chat UI scaffold with Turbo streaming\n' \
|
|
16
19
|
'Usage: rails g ruby_llm:chat_ui [chat:ChatName] [message:MessageName] ...'
|
|
17
20
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
message: 'Message',
|
|
22
|
-
tool_call: 'ToolCall',
|
|
23
|
-
model: 'Model'
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
model_mappings.each do |mapping|
|
|
27
|
-
if mapping.include?(':')
|
|
28
|
-
key, value = mapping.split(':', 2)
|
|
29
|
-
@model_names[key.to_sym] = value.classify
|
|
30
|
-
end
|
|
31
|
-
end
|
|
21
|
+
def check_model_exists
|
|
22
|
+
model_path = "app/models/#{message_model_name.underscore}.rb"
|
|
23
|
+
return if File.exist?(model_path)
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
# Build the argument string for the install/upgrade commands
|
|
26
|
+
args = []
|
|
27
|
+
args << "chat:#{chat_model_name}" if chat_model_name != 'Chat'
|
|
28
|
+
args << "message:#{message_model_name}" if message_model_name != 'Message'
|
|
29
|
+
args << "model:#{model_model_name}" if model_model_name != 'Model'
|
|
30
|
+
args << "tool_call:#{tool_call_model_name}" if tool_call_model_name != 'ToolCall'
|
|
31
|
+
arg_string = args.any? ? " #{args.join(' ')}" : ''
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@model_names ||= parse_model_mappings
|
|
39
|
-
@model_names[type]
|
|
40
|
-
end
|
|
33
|
+
raise Thor::Error, <<~ERROR
|
|
34
|
+
Model file not found: #{model_path}
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
Please run the install generator first:
|
|
37
|
+
rails generate ruby_llm:install#{arg_string}
|
|
38
|
+
|
|
39
|
+
Or if upgrading from <= 1.6.x, run the upgrade generator:
|
|
40
|
+
rails generate ruby_llm:upgrade_to_v1_7#{arg_string}
|
|
41
|
+
ERROR
|
|
45
42
|
end
|
|
46
43
|
|
|
47
44
|
def create_views
|
|
45
|
+
# For namespaced models, use the proper Rails convention path
|
|
46
|
+
chat_view_path = chat_model_name.underscore.pluralize
|
|
47
|
+
message_view_path = message_model_name.underscore.pluralize
|
|
48
|
+
model_view_path = model_model_name.underscore.pluralize
|
|
49
|
+
|
|
48
50
|
# Chat views
|
|
49
|
-
template 'views/chats/index.html.erb', "app/views/#{
|
|
50
|
-
template 'views/chats/new.html.erb', "app/views/#{
|
|
51
|
-
template 'views/chats/show.html.erb', "app/views/#{
|
|
51
|
+
template 'views/chats/index.html.erb', "app/views/#{chat_view_path}/index.html.erb"
|
|
52
|
+
template 'views/chats/new.html.erb', "app/views/#{chat_view_path}/new.html.erb"
|
|
53
|
+
template 'views/chats/show.html.erb', "app/views/#{chat_view_path}/show.html.erb"
|
|
52
54
|
template 'views/chats/_chat.html.erb',
|
|
53
|
-
"app/views/#{
|
|
54
|
-
template 'views/chats/_form.html.erb', "app/views/#{
|
|
55
|
+
"app/views/#{chat_view_path}/_#{chat_model_name.demodulize.underscore}.html.erb"
|
|
56
|
+
template 'views/chats/_form.html.erb', "app/views/#{chat_view_path}/_form.html.erb"
|
|
55
57
|
|
|
56
58
|
# Message views
|
|
57
59
|
template 'views/messages/_message.html.erb',
|
|
58
|
-
"app/views/#{
|
|
59
|
-
template 'views/messages/
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
"app/views/#{message_view_path}/_#{message_model_name.demodulize.underscore}.html.erb"
|
|
61
|
+
template 'views/messages/_tool_calls.html.erb',
|
|
62
|
+
"app/views/#{message_view_path}/_tool_calls.html.erb"
|
|
63
|
+
template 'views/messages/_content.html.erb', "app/views/#{message_view_path}/_content.html.erb"
|
|
64
|
+
template 'views/messages/_form.html.erb', "app/views/#{message_view_path}/_form.html.erb"
|
|
65
|
+
template 'views/messages/create.turbo_stream.erb', "app/views/#{message_view_path}/create.turbo_stream.erb"
|
|
62
66
|
|
|
63
67
|
# Model views
|
|
64
|
-
template 'views/models/index.html.erb', "app/views/#{
|
|
65
|
-
template 'views/models/show.html.erb', "app/views/#{
|
|
68
|
+
template 'views/models/index.html.erb', "app/views/#{model_view_path}/index.html.erb"
|
|
69
|
+
template 'views/models/show.html.erb', "app/views/#{model_view_path}/show.html.erb"
|
|
66
70
|
template 'views/models/_model.html.erb',
|
|
67
|
-
"app/views/#{
|
|
71
|
+
"app/views/#{model_view_path}/_#{model_model_name.demodulize.underscore}.html.erb"
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
def create_controllers
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
# For namespaced models, use the proper Rails convention path
|
|
76
|
+
chat_controller_path = chat_model_name.underscore.pluralize
|
|
77
|
+
message_controller_path = message_model_name.underscore.pluralize
|
|
78
|
+
model_controller_path = model_model_name.underscore.pluralize
|
|
79
|
+
|
|
80
|
+
template 'controllers/chats_controller.rb', "app/controllers/#{chat_controller_path}_controller.rb"
|
|
81
|
+
template 'controllers/messages_controller.rb', "app/controllers/#{message_controller_path}_controller.rb"
|
|
82
|
+
template 'controllers/models_controller.rb', "app/controllers/#{model_controller_path}_controller.rb"
|
|
74
83
|
end
|
|
75
84
|
|
|
76
85
|
def create_jobs
|
|
77
|
-
template 'jobs/chat_response_job.rb', "app/jobs/#{chat_model_name
|
|
86
|
+
template 'jobs/chat_response_job.rb', "app/jobs/#{variable_name_for(chat_model_name)}_response_job.rb"
|
|
78
87
|
end
|
|
79
88
|
|
|
80
89
|
def add_routes
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
# For namespaced models, use Rails convention with namespace blocks
|
|
91
|
+
if chat_model_name.include?('::')
|
|
92
|
+
namespace = chat_model_name.deconstantize.underscore
|
|
93
|
+
chat_resource = chat_model_name.demodulize.underscore.pluralize
|
|
94
|
+
message_resource = message_model_name.demodulize.underscore.pluralize
|
|
95
|
+
model_resource = model_model_name.demodulize.underscore.pluralize
|
|
96
|
+
|
|
97
|
+
routes_content = <<~ROUTES.strip
|
|
98
|
+
namespace :#{namespace} do
|
|
99
|
+
resources :#{model_resource}, only: [:index, :show] do
|
|
100
|
+
collection do
|
|
101
|
+
post :refresh
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
resources :#{chat_resource} do
|
|
105
|
+
resources :#{message_resource}, only: [:create]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
ROUTES
|
|
109
|
+
route routes_content
|
|
110
|
+
else
|
|
111
|
+
model_routes = <<~ROUTES.strip
|
|
112
|
+
resources :#{model_table_name}, only: [:index, :show] do
|
|
113
|
+
collection do
|
|
114
|
+
post :refresh
|
|
115
|
+
end
|
|
85
116
|
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
117
|
+
ROUTES
|
|
118
|
+
route model_routes
|
|
119
|
+
chat_routes = <<~ROUTES.strip
|
|
120
|
+
resources :#{chat_table_name} do
|
|
121
|
+
resources :#{message_table_name}, only: [:create]
|
|
122
|
+
end
|
|
123
|
+
ROUTES
|
|
124
|
+
route chat_routes
|
|
125
|
+
end
|
|
95
126
|
end
|
|
96
127
|
|
|
97
128
|
def add_broadcasting_to_message_model
|
|
98
|
-
msg_var = message_model_name
|
|
99
|
-
chat_var = chat_model_name
|
|
100
|
-
|
|
129
|
+
msg_var = variable_name_for(message_model_name)
|
|
130
|
+
chat_var = variable_name_for(chat_model_name)
|
|
131
|
+
msg_path = message_model_name.underscore
|
|
132
|
+
|
|
133
|
+
# For namespaced models, we need the association name which might be different
|
|
134
|
+
# e.g., for LLM::Message, the chat association might be :llm_chat
|
|
135
|
+
chat_association = chat_table_name.singularize
|
|
136
|
+
|
|
137
|
+
# Use Rails convention paths for partials
|
|
138
|
+
partial_path = message_model_name.underscore.pluralize
|
|
139
|
+
|
|
140
|
+
# For broadcasts, we need to explicitly set the partial path
|
|
141
|
+
# Turbo will pass the record with the demodulized name (e.g. 'message' for Llm::Message)
|
|
142
|
+
broadcasting_code = if message_model_name.include?('::')
|
|
143
|
+
partial_name = "#{partial_path}/#{message_model_name.demodulize.underscore}"
|
|
144
|
+
<<~RUBY.strip
|
|
145
|
+
broadcasts_to ->(#{msg_var}) { "#{chat_var}_\#{#{msg_var}.#{chat_association}_id}" },
|
|
146
|
+
partial: "#{partial_name}"
|
|
147
|
+
RUBY
|
|
148
|
+
else
|
|
149
|
+
"broadcasts_to ->(#{msg_var}) { \"#{chat_var}_\#{#{msg_var}.#{chat_association}_id}\" }"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
broadcast_append_chunk_method = <<-RUBY
|
|
153
|
+
|
|
154
|
+
def broadcast_append_chunk(content)
|
|
155
|
+
broadcast_append_to "#{chat_var}_\#{#{chat_association}_id}",
|
|
156
|
+
target: "#{msg_var}_\#{id}_content",
|
|
157
|
+
partial: "#{partial_path}/content",
|
|
158
|
+
locals: { content: content }
|
|
159
|
+
end
|
|
160
|
+
RUBY
|
|
101
161
|
|
|
102
|
-
|
|
103
|
-
"
|
|
162
|
+
inject_into_file "app/models/#{msg_path}.rb", before: "end\n" do
|
|
163
|
+
" #{broadcasting_code}\n#{broadcast_append_chunk_method}"
|
|
104
164
|
end
|
|
105
165
|
rescue Errno::ENOENT
|
|
106
166
|
say "#{message_model_name} model not found. Add broadcasting code to your model.", :yellow
|
|
107
167
|
say " #{broadcasting_code}", :yellow
|
|
168
|
+
say broadcast_append_chunk_method, :yellow
|
|
108
169
|
end
|
|
109
170
|
|
|
110
171
|
def display_post_install_message
|
|
111
172
|
return unless behavior == :invoke
|
|
112
173
|
|
|
174
|
+
# Show the correct URL based on whether models are namespaced
|
|
175
|
+
url_path = if chat_model_name.include?('::')
|
|
176
|
+
chat_model_name.underscore.pluralize
|
|
177
|
+
else
|
|
178
|
+
chat_table_name
|
|
179
|
+
end
|
|
180
|
+
|
|
113
181
|
say "\n ✅ Chat UI installed!", :green
|
|
114
|
-
say "\n Start your server and visit http://localhost:3000/#{
|
|
182
|
+
say "\n Start your server and visit http://localhost:3000/#{url_path}", :cyan
|
|
115
183
|
say "\n"
|
|
116
184
|
end
|
|
117
|
-
|
|
118
|
-
private
|
|
119
|
-
|
|
120
|
-
def table_name_for(model_name)
|
|
121
|
-
# Convert namespaced model names to proper table names
|
|
122
|
-
# e.g., "Assistant::Chat" -> "assistant_chats" (not "assistant/chats")
|
|
123
|
-
model_name.underscore.pluralize.tr('/', '_')
|
|
124
|
-
end
|
|
125
185
|
end
|
|
126
186
|
end
|
|
127
187
|
end
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
class <%=
|
|
2
|
-
before_action :set_<%=
|
|
1
|
+
class <%= chat_controller_class_name %> < ApplicationController
|
|
2
|
+
before_action :set_<%= chat_variable_name %>, only: [:show]
|
|
3
3
|
|
|
4
4
|
def index
|
|
5
|
-
@<%=
|
|
5
|
+
@<%= chat_table_name %> = <%= chat_model_name %>.order(created_at: :desc)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def new
|
|
9
|
-
@<%=
|
|
9
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.new
|
|
10
10
|
@selected_model = params[:model]
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def create
|
|
14
14
|
return unless prompt.present?
|
|
15
15
|
|
|
16
|
-
@<%=
|
|
17
|
-
<%=
|
|
16
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.create!(model: model)
|
|
17
|
+
<%= chat_job_class_name %>.perform_later(@<%= chat_variable_name %>.id, prompt)
|
|
18
18
|
|
|
19
|
-
redirect_to @<%=
|
|
19
|
+
redirect_to @<%= chat_variable_name %>, notice: '<%= chat_model_name.humanize %> was successfully created.'
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def show
|
|
23
|
-
@<%=
|
|
23
|
+
@<%= message_variable_name %> = @<%= chat_variable_name %>.<%= message_table_name %>.build
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
private
|
|
27
27
|
|
|
28
|
-
def set_<%=
|
|
29
|
-
@<%=
|
|
28
|
+
def set_<%= chat_variable_name %>
|
|
29
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.find(params[:id])
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def model
|
|
33
|
-
params[:<%=
|
|
33
|
+
params[:<%= chat_variable_name %>][:model].presence
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def prompt
|
|
37
|
-
params[:<%=
|
|
37
|
+
params[:<%= chat_variable_name %>][:prompt]
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
class <%=
|
|
2
|
-
before_action :set_<%=
|
|
1
|
+
class <%= message_controller_class_name %> < ApplicationController
|
|
2
|
+
before_action :set_<%= chat_variable_name %>
|
|
3
3
|
|
|
4
4
|
def create
|
|
5
5
|
return unless content.present?
|
|
6
6
|
|
|
7
|
-
<%=
|
|
7
|
+
<%= chat_job_class_name %>.perform_later(@<%= chat_variable_name %>.id, content)
|
|
8
8
|
|
|
9
9
|
respond_to do |format|
|
|
10
10
|
format.turbo_stream
|
|
11
|
-
format.html { redirect_to @<%=
|
|
11
|
+
format.html { redirect_to @<%= chat_variable_name %> }
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
|
-
def set_<%=
|
|
18
|
-
@<%=
|
|
17
|
+
def set_<%= chat_variable_name %>
|
|
18
|
+
@<%= chat_variable_name %> = <%= chat_model_name %>.find(params[:<%= chat_model_name.include?('::') ? chat_model_name.demodulize.underscore : chat_variable_name %>_id])
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def content
|
|
22
|
-
params[:<%=
|
|
22
|
+
params[:<%= message_variable_name %>][:content]
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
class <%=
|
|
1
|
+
class <%= model_controller_class_name %> < ApplicationController
|
|
2
2
|
def index
|
|
3
|
-
@<%=
|
|
3
|
+
@<%= model_table_name %> = <%= model_model_name %>.all
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
def show
|
|
7
|
-
@<%=
|
|
7
|
+
@<%= model_variable_name %> = <%= model_model_name %>.find(params[:id])
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def refresh
|
|
11
11
|
<%= model_model_name %>.refresh!
|
|
12
|
-
redirect_to <%=
|
|
12
|
+
redirect_to <%= model_table_name %>_path, notice: "<%= model_model_name.pluralize %> refreshed successfully"
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
class <%=
|
|
2
|
-
def perform(<%=
|
|
3
|
-
<%=
|
|
1
|
+
class <%= chat_job_class_name %> < ApplicationJob
|
|
2
|
+
def perform(<%= chat_variable_name %>_id, content)
|
|
3
|
+
<%= chat_variable_name %> = <%= chat_model_name %>.find(<%= chat_variable_name %>_id)
|
|
4
4
|
|
|
5
|
-
<%=
|
|
5
|
+
<%= chat_variable_name %>.ask(content) do |chunk|
|
|
6
6
|
if chunk.content && !chunk.content.blank?
|
|
7
|
-
<%=
|
|
8
|
-
<%=
|
|
7
|
+
<%= message_variable_name %> = <%= chat_variable_name %>.<%= message_table_name %>.last
|
|
8
|
+
<%= message_variable_name %>.broadcast_append_chunk(chunk.content)
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<div id="<%%= dom_id <%= chat_model_name.underscore %> %>">
|
|
1
|
+
<div id="<%%= dom_id <%= chat_model_name.demodulize.underscore %> %>">
|
|
2
2
|
<div>
|
|
3
3
|
<strong>Model:</strong>
|
|
4
|
-
<%%= <%= chat_model_name.underscore
|
|
4
|
+
<%%= <%= chat_model_name.demodulize.underscore %>.<%= model_table_name.singularize %>&.name || 'Default' %>
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<div>
|
|
8
8
|
<strong>Messages:</strong>
|
|
9
|
-
<%%= <%= chat_model_name.underscore %>.
|
|
9
|
+
<%%= <%= chat_model_name.demodulize.underscore %>.<%= message_table_name %>.count %>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
12
|
<div>
|
|
13
13
|
<strong>Created:</strong>
|
|
14
|
-
<%%= <%= chat_model_name.underscore %>.created_at.strftime("%B %d, %Y at %I:%M %p") %>
|
|
14
|
+
<%%= <%= chat_model_name.demodulize.underscore %>.created_at.strftime("%B %d, %Y at %I:%M %p") %>
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<%%= form_with(model: <%=
|
|
2
|
-
<%% if <%=
|
|
1
|
+
<%%= form_with(model: <%= chat_variable_name %>, url: <%= chat_table_name %>_path) do |form| %>
|
|
2
|
+
<%% if <%= chat_variable_name %>.errors.any? %>
|
|
3
3
|
<div style="color: red">
|
|
4
|
-
<h2><%%= pluralize(<%=
|
|
4
|
+
<h2><%%= pluralize(<%= chat_variable_name %>.errors.count, "error") %> prohibited this <%= chat_table_name.singularize.humanize.downcase %> from being saved:</h2>
|
|
5
5
|
|
|
6
6
|
<ul>
|
|
7
|
-
<%% <%=
|
|
7
|
+
<%% <%= chat_variable_name %>.errors.each do |error| %>
|
|
8
8
|
<li><%%= error.full_message %></li>
|
|
9
9
|
<%% end %>
|
|
10
10
|
</ul>
|
|
@@ -24,6 +24,6 @@
|
|
|
24
24
|
</div>
|
|
25
25
|
|
|
26
26
|
<div>
|
|
27
|
-
<%%= form.submit "Start new <%=
|
|
27
|
+
<%%= form.submit "Start new <%= chat_table_name.singularize.humanize.downcase %>" %>
|
|
28
28
|
</div>
|
|
29
29
|
<%% end %>
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
<h1><%= chat_model_name.pluralize %></h1>
|
|
6
6
|
|
|
7
|
-
<div id="<%=
|
|
8
|
-
<%% @<%=
|
|
9
|
-
<%%= render <%=
|
|
7
|
+
<div id="<%= chat_table_name %>">
|
|
8
|
+
<%% @<%= chat_table_name %>.each do |<%= chat_variable_name %>| %>
|
|
9
|
+
<%%= render <%= chat_variable_name %> %>
|
|
10
10
|
<p>
|
|
11
|
-
<%%= link_to "Show this <%=
|
|
11
|
+
<%%= link_to "Show this <%= chat_table_name.singularize.humanize.downcase %>", <%= chat_variable_name %> %>
|
|
12
12
|
</p>
|
|
13
13
|
<%% end %>
|
|
14
14
|
</div>
|
|
15
15
|
|
|
16
|
-
<%%= link_to "New <%=
|
|
16
|
+
<%%= link_to "New <%= chat_table_name.singularize.humanize.downcase %>", new_<%= chat_variable_name %>_path %>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<%% content_for :title, "New <%=
|
|
1
|
+
<%% content_for :title, "New <%= chat_table_name.singularize.humanize.downcase %>" %>
|
|
2
2
|
|
|
3
|
-
<h1>New <%=
|
|
3
|
+
<h1>New <%= chat_table_name.singularize.humanize.downcase %></h1>
|
|
4
4
|
|
|
5
|
-
<%%= render "form", <%=
|
|
5
|
+
<%%= render "form", <%= chat_variable_name %>: @<%= chat_variable_name %> %>
|
|
6
6
|
|
|
7
7
|
<br>
|
|
8
8
|
|
|
9
9
|
<div>
|
|
10
|
-
<%%= link_to "Back to <%=
|
|
10
|
+
<%%= link_to "Back to <%= chat_table_name.humanize.downcase %>", <%= chat_table_name %>_path %>
|
|
11
11
|
</div>
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
<p style="color: green"><%%= notice %></p>
|
|
2
2
|
|
|
3
|
-
<%%= turbo_stream_from "<%=
|
|
3
|
+
<%%= turbo_stream_from "<%= chat_variable_name %>_#{@<%= chat_variable_name %>.id}" %>
|
|
4
4
|
|
|
5
5
|
<%% content_for :title, "<%= chat_model_name %>" %>
|
|
6
6
|
|
|
7
|
-
<h1><%= chat_model_name %> <%%= @<%=
|
|
7
|
+
<h1><%= chat_model_name %> <%%= @<%= chat_variable_name %>.id %></h1>
|
|
8
8
|
|
|
9
|
-
<p>Using <strong><%%= @<%=
|
|
9
|
+
<p>Using <strong><%%= @<%= chat_variable_name %>.<%= model_table_name.singularize %>.name %></strong></p>
|
|
10
10
|
|
|
11
|
-
<div id="<%=
|
|
12
|
-
<%% @<%=
|
|
13
|
-
<%%= render
|
|
11
|
+
<div id="<%= message_table_name %>">
|
|
12
|
+
<%% @<%= chat_variable_name %>.<%= message_table_name %>.where.not(id: nil).each do |<%= message_variable_name %>| %>
|
|
13
|
+
<%%= render <%= message_variable_name %> %>
|
|
14
14
|
<%% end %>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
17
|
<div style="margin-top: 30px;">
|
|
18
|
-
<%%= render "<%= message_model_name.
|
|
18
|
+
<%%= render "<%= message_model_name.underscore.pluralize %>/form", <%= chat_variable_name %>: @<%= chat_variable_name %>, <%= message_variable_name %>: @<%= message_variable_name %> %>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<div style="margin-top: 20px;">
|
|
22
|
-
<%%= link_to "Back to <%=
|
|
22
|
+
<%%= link_to "Back to <%= chat_table_name.humanize.downcase %>", <%= chat_table_name %>_path %>
|
|
23
23
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%%= content %>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
<%%= form_with(model:
|
|
2
|
-
<%% if <%=
|
|
1
|
+
<%%= form_with(model: <%= message_variable_name %>, url: <%= chat_model_name.include?('::') ? "#{chat_model_name.split('::').first.underscore}_#{chat_model_name.demodulize.underscore}_#{message_model_name.demodulize.underscore.pluralize}_path(@#{chat_variable_name})" : "[@#{chat_variable_name}, #{message_variable_name}]" %>, id: "new_<%= message_variable_name %>") do |form| %>
|
|
2
|
+
<%% if <%= message_variable_name %>.errors.any? %>
|
|
3
3
|
<div style="color: red">
|
|
4
|
-
<h2><%%= pluralize(<%=
|
|
4
|
+
<h2><%%= pluralize(<%= message_variable_name %>.errors.count, "error") %> prohibited this <%= message_table_name.singularize.humanize.downcase %> from being saved:</h2>
|
|
5
5
|
|
|
6
6
|
<ul>
|
|
7
|
-
<%% <%=
|
|
7
|
+
<%% <%= message_variable_name %>.errors.each do |error| %>
|
|
8
8
|
<li><%%= error.full_message %></li>
|
|
9
9
|
<%% end %>
|
|
10
10
|
</ul>
|
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
<div>
|
|
19
|
-
<%%= form.submit "Send <%=
|
|
19
|
+
<%%= form.submit "Send <%= message_table_name.singularize.humanize.downcase %>" %>
|
|
20
20
|
</div>
|
|
21
21
|
<%% end %>
|