llama_bot_rails 0.1.1 → 0.1.3
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/app/assets/javascripts/llama_bot_rails/application.js +18 -3
- data/app/channels/llama_bot_rails/chat_channel.rb +9 -6
- data/app/views/llama_bot_rails/agent/chat.html.erb +44 -26
- data/lib/generators/llama_bot_rails/install/install_generator.rb +46 -0
- data/lib/llama_bot_rails/engine.rb +3 -0
- data/lib/llama_bot_rails/version.rb +1 -1
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34248e0bbf8e8047cad5836f03e4f37a4b0cc84a5f152a9fcc486f7c32de50ed
|
4
|
+
data.tar.gz: 0e4a0a1f0d0939d042e21cd1e2745daeae241e33877febe7f45740679b94ff50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5cee45f49487fcbf2203d326b62431c4c7fb540004e0004a7929b7ec6fe2487124ed146237333a10b5f75db0f2508d1f1b7e91c7fe41afc7eb67f02a6395231
|
7
|
+
data.tar.gz: a67f3f5278245e15a0b868a22b27bc56e317cdd3f2aa456ef9c60100bb4547abfabd50e6a37a84cc7a7cdf97e37e45a06ce17a9b1e4dd3cc9c55125834262d40
|
@@ -1,7 +1,22 @@
|
|
1
1
|
//= require action_cable
|
2
2
|
//= require_self
|
3
3
|
|
4
|
-
(function() {
|
4
|
+
(function () {
|
5
5
|
this.LlamaBotRails = this.LlamaBotRails || {};
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
function createLlamaCable() {
|
8
|
+
if (window.ActionCable && !LlamaBotRails.cable) {
|
9
|
+
console.log("🦙 Creating LlamaBot ActionCable consumer");
|
10
|
+
LlamaBotRails.cable = ActionCable.createConsumer();
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
// Run immediately if ActionCable is already present (classic asset pipeline)
|
15
|
+
if (window.ActionCable) {
|
16
|
+
createLlamaCable();
|
17
|
+
} else {
|
18
|
+
// Wait until DOM + importmap load finishes
|
19
|
+
document.addEventListener("DOMContentLoaded", createLlamaCable);
|
20
|
+
document.addEventListener("turbo:load", createLlamaCable); // covers Turbo + importmap apps
|
21
|
+
}
|
22
|
+
}).call(this);
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'async'
|
2
|
+
require 'async/http'
|
3
|
+
require 'async/websocket'
|
4
|
+
|
1
5
|
require 'json' # Ensure JSON is required if not already
|
2
6
|
|
3
7
|
module LlamaBotRails
|
@@ -147,28 +151,27 @@ module LlamaBotRails
|
|
147
151
|
Rails.logger.info "[LlamaBot] Setting up external websocket for connection: #{connection_id}"
|
148
152
|
|
149
153
|
# Check if the WebSocket URL is configured
|
150
|
-
websocket_url =
|
154
|
+
websocket_url = Rails.application.config.llama_bot_rails.websocket_url
|
151
155
|
if websocket_url.blank?
|
152
|
-
Rails.logger.warn "[LlamaBot]
|
156
|
+
Rails.logger.warn "[LlamaBot] LlamaBot Websocket URL is not configured in the config/initializers/llama_bot_rails.rb file, skipping external WebSocket setup"
|
153
157
|
return
|
154
158
|
end
|
155
159
|
|
156
|
-
# endpoint = Async::HTTP::Endpoint.parse(ENV['LLAMABOT_WEBSOCKET_URL'])
|
157
160
|
uri = URI(websocket_url)
|
158
161
|
|
159
162
|
uri.scheme = 'wss'
|
160
|
-
uri.scheme = 'ws' if
|
163
|
+
uri.scheme = 'ws' if Rails.env.development?
|
161
164
|
|
162
165
|
endpoint = Async::HTTP::Endpoint.new(
|
163
166
|
uri,
|
164
167
|
ssl_context: OpenSSL::SSL::SSLContext.new.tap do |ctx|
|
165
168
|
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
166
|
-
if
|
169
|
+
if Rails.env.staging?
|
167
170
|
ctx.ca_file = '/usr/local/etc/ca-certificates/cert.pem'
|
168
171
|
# M2 Air : ctx.ca_file = '/etc//ssl/cert.pem'
|
169
172
|
ctx.cert = OpenSSL::X509::Certificate.new(File.read(File.expand_path('~/.ssl/llamapress/cert.pem')))
|
170
173
|
ctx.key = OpenSSL::PKey::RSA.new(File.read(File.expand_path('~/.ssl/llamapress/key.pem')))
|
171
|
-
elsif
|
174
|
+
elsif Rails.env.development?
|
172
175
|
# do no ctx stuff
|
173
176
|
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
174
177
|
else # production
|
@@ -406,6 +406,7 @@
|
|
406
406
|
color: var(--text-secondary);
|
407
407
|
}
|
408
408
|
</style>
|
409
|
+
<%= javascript_importmap_tags %>
|
409
410
|
<%= javascript_include_tag "llama_bot_rails/application" %>
|
410
411
|
<%= action_cable_meta_tag %>
|
411
412
|
<!-- Add Snarkdown CDN -->
|
@@ -465,37 +466,47 @@
|
|
465
466
|
let redStatusStartTime = null;
|
466
467
|
let errorModalShown = false;
|
467
468
|
let connectionCheckInterval;
|
469
|
+
let subscription = null;
|
468
470
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
471
|
+
function waitForCableConnection(callback) {
|
472
|
+
const interval = setInterval(() => {
|
473
|
+
if (window.LlamaBotRails && LlamaBotRails.cable) {
|
474
|
+
clearInterval(interval);
|
475
|
+
callback(LlamaBotRails.cable);
|
476
|
+
}
|
477
|
+
}, 50);
|
478
|
+
}
|
479
|
+
|
480
|
+
waitForCableConnection((consumer) => {
|
481
|
+
subscription = consumer.subscriptions.create('LlamaBotRails::ChatChannel', {
|
482
|
+
connected() {
|
483
|
+
console.log('Connected to chat channel');
|
484
|
+
lastPongTime = Date.now();
|
485
|
+
loadThreads();
|
486
|
+
startConnectionCheck();
|
487
|
+
},
|
488
|
+
disconnected() {
|
489
|
+
console.log('Disconnected from chat channel');
|
490
|
+
updateStatusIcon('status-red');
|
491
|
+
},
|
492
|
+
received(data) {
|
493
|
+
const parsedData = JSON.parse(data).message;
|
494
|
+
switch (parsedData.type) {
|
485
495
|
case "ai":
|
486
496
|
addMessage(parsedData.content, parsedData.type, parsedData.base_message);
|
487
497
|
break;
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
498
|
+
case "tool":
|
499
|
+
addMessage(parsedData.content, parsedData.type, parsedData.base_message);
|
500
|
+
break;
|
501
|
+
case "error":
|
502
|
+
addMessage(parsedData.content, parsedData.type, parsedData.base_message);
|
503
|
+
break;
|
504
|
+
case "pong":
|
505
|
+
lastPongTime = Date.now();
|
506
|
+
break;
|
507
|
+
}
|
497
508
|
}
|
498
|
-
}
|
509
|
+
});
|
499
510
|
});
|
500
511
|
|
501
512
|
function startConnectionCheck() {
|
@@ -704,6 +715,13 @@
|
|
704
715
|
const message = input.value.trim();
|
705
716
|
|
706
717
|
if (message) {
|
718
|
+
// Check if subscription is available
|
719
|
+
if (!subscription) {
|
720
|
+
console.error('WebSocket connection not established yet');
|
721
|
+
addMessage('Connection not ready. Please wait...', 'error');
|
722
|
+
return;
|
723
|
+
}
|
724
|
+
|
707
725
|
// Clear welcome message if it exists
|
708
726
|
const welcomeMessage = document.querySelector('.welcome-message');
|
709
727
|
if (welcomeMessage) {
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# lib/generators/llama_bot_rails/install/install_generator.rb
|
2
|
+
module LlamaBotRails
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path("templates", __dir__)
|
6
|
+
|
7
|
+
def mount_engine
|
8
|
+
say <<~MSG, :yellow
|
9
|
+
⚠️ NOTE: LlamaBotRails requires ActionCable to be available on the frontend.
|
10
|
+
|
11
|
+
If you're using ImportMap (Rails 7 default), run:
|
12
|
+
|
13
|
+
bin/importmap pin @rails/actioncable
|
14
|
+
|
15
|
+
And in app/javascript/application.js, add:
|
16
|
+
|
17
|
+
import * as ActionCable from "@rails/actioncable"
|
18
|
+
window.ActionCable = ActionCable
|
19
|
+
|
20
|
+
If you're using Webpacker or jsbundling-rails:
|
21
|
+
Add @rails/actioncable via yarn/npm
|
22
|
+
And import + expose it the same way in your JS pack.
|
23
|
+
|
24
|
+
📘 See README → “JavaScript Setup” for full details.
|
25
|
+
|
26
|
+
MSG
|
27
|
+
|
28
|
+
route 'mount LlamaBotRails::Engine => "/llama_bot"'
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_initializer
|
32
|
+
create_file "config/initializers/llama_bot_rails.rb", <<~RUBY
|
33
|
+
Rails.application.configure do
|
34
|
+
config.llama_bot_rails.websocket_url = ENV.fetch("LLAMABOT_WEBSOCKET_URL", "ws://localhost:8000/ws")
|
35
|
+
config.llama_bot_rails.enable_console_tool = !Rails.env.production?
|
36
|
+
end
|
37
|
+
RUBY
|
38
|
+
end
|
39
|
+
|
40
|
+
def finish
|
41
|
+
say "\n✅ LlamaBotRails installed! Visit http://localhost:3000/llama_bot/agent/chat\n", :green
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -11,6 +11,9 @@ module LlamaBotRails
|
|
11
11
|
end
|
12
12
|
|
13
13
|
config.llama_bot_rails = ActiveSupport::OrderedOptions.new
|
14
|
+
config.llama_bot_rails.websocket_url = 'ws://localhost:8000/ws' # <-- default
|
15
|
+
config.llama_bot_rails.llamabot_api_url = "http://localhost:8000"
|
16
|
+
config.llama_bot_rails.enable_console_tool = true
|
14
17
|
|
15
18
|
initializer "llama_bot_rails.assets.precompile" do |app|
|
16
19
|
app.config.assets.precompile += %w( llama_bot_rails/application.js )
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: llama_bot_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kody Kendall
|
@@ -33,16 +33,22 @@ dependencies:
|
|
33
33
|
name: actioncable
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
35
35
|
requirements:
|
36
|
-
- - "
|
36
|
+
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: '7.0'
|
39
|
+
- - "<"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '9.0'
|
39
42
|
type: :runtime
|
40
43
|
prerelease: false
|
41
44
|
version_requirements: !ruby/object:Gem::Requirement
|
42
45
|
requirements:
|
43
|
-
- - "
|
46
|
+
- - ">="
|
44
47
|
- !ruby/object:Gem::Version
|
45
48
|
version: '7.0'
|
49
|
+
- - "<"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '9.0'
|
46
52
|
- !ruby/object:Gem::Dependency
|
47
53
|
name: async-websocket
|
48
54
|
requirement: !ruby/object:Gem::Requirement
|
@@ -71,6 +77,20 @@ dependencies:
|
|
71
77
|
- - ">="
|
72
78
|
- !ruby/object:Gem::Version
|
73
79
|
version: '0'
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: async
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
type: :runtime
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
74
94
|
description: LlamaBotRails is a gem that turns your existing Rails App into an AI
|
75
95
|
Agent by connecting it to an open source LangGraph agent, LlamaBot.
|
76
96
|
email:
|
@@ -101,6 +121,7 @@ files:
|
|
101
121
|
- bin/rubocop
|
102
122
|
- config/initializers/llama_bot_rails.rb
|
103
123
|
- config/routes.rb
|
124
|
+
- lib/generators/llama_bot_rails/install/install_generator.rb
|
104
125
|
- lib/llama_bot_rails.rb
|
105
126
|
- lib/llama_bot_rails/agent_state_builder.rb
|
106
127
|
- lib/llama_bot_rails/engine.rb
|