llama_bot_rails 0.1.3 → 0.1.4
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 +18 -6
- data/app/views/llama_bot_rails/agent/chat.html.erb +166 -7
- data/lib/llama_bot_rails/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bd4c2d542ae02f6d430d6c6233792445b79dcff44b265d508c9d985db22b09b
|
4
|
+
data.tar.gz: '09ad72a1840000cf121133633dc104517e5937a843be0cba48dadd0a3bf60a66'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 192fe783f3c6e91170bb3109dbb116d21ca7bb6c68ecb064a92435d416efa16a1e765e5ff59d07af5978e348724e9f70569dbbf2faaeab8ac9a432f7df1712e6
|
7
|
+
data.tar.gz: 02362ff59435fd5a0b88038f276e2cc69d8fd70fac868b16ee4c1fa98bfb4ae36c298e541aec388a37856de636b9ee841bff81be971fbae50949925d2c9e3cd2
|
data/README.md
CHANGED
@@ -27,7 +27,6 @@ Chat with a powerful agent that has access to your models, your application cont
|
|
27
27
|
|
28
28
|
## 🚀 **Quickstart** →
|
29
29
|
|
30
|
-
|
31
30
|
```bash
|
32
31
|
|
33
32
|
# 1. Add the gem
|
@@ -38,14 +37,27 @@ rails generate llama_bot_rails:install
|
|
38
37
|
|
39
38
|
# 3. Clone & run the LangGraph backend
|
40
39
|
git clone https://github.com/kodykendall/llamabot
|
41
|
-
cd llamabot
|
42
|
-
OPENAI_API_KEY=your_key
|
43
|
-
cd backend && uvicorn app:app --reload
|
44
40
|
|
45
|
-
#
|
41
|
+
# 4. Set up your environment
|
42
|
+
python3 -m venv venv
|
43
|
+
|
44
|
+
source venv/bin/activate
|
45
|
+
|
46
|
+
pip install -r requirements.txt
|
47
|
+
|
48
|
+
echo "OPENAI_API_KEY=your_openai_api_key_here" > .env
|
49
|
+
|
50
|
+
# 5. Run the agent
|
51
|
+
cd backend
|
52
|
+
uvicorn app:app --reload
|
53
|
+
|
54
|
+
# 6. Confirm our agent is running properly. You should see: Hello, World! 🦙💬
|
55
|
+
curl http://localhost:8000/hello
|
56
|
+
|
57
|
+
# 7. Start your Rails server.
|
46
58
|
rails server
|
47
59
|
|
48
|
-
# Visit the chat interface and start chatting.
|
60
|
+
# 8. Visit the chat interface and start chatting.
|
49
61
|
open http://localhost:3000/llama_bot/agent/chat
|
50
62
|
|
51
63
|
```
|
@@ -405,6 +405,109 @@
|
|
405
405
|
font-size: 1em;
|
406
406
|
color: var(--text-secondary);
|
407
407
|
}
|
408
|
+
|
409
|
+
/* Clean loading indicator - just animated text */
|
410
|
+
.loading-indicator {
|
411
|
+
display: none;
|
412
|
+
align-items: center;
|
413
|
+
padding: 16px 20px;
|
414
|
+
color: var(--text-secondary);
|
415
|
+
font-size: 14px;
|
416
|
+
margin-bottom: 10px;
|
417
|
+
background: rgba(255, 255, 255, 0.02);
|
418
|
+
border-radius: 8px;
|
419
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
420
|
+
}
|
421
|
+
|
422
|
+
.loading-indicator.visible {
|
423
|
+
display: flex;
|
424
|
+
}
|
425
|
+
|
426
|
+
.loading-text {
|
427
|
+
font-style: italic;
|
428
|
+
}
|
429
|
+
|
430
|
+
.loading-dots::after {
|
431
|
+
content: '';
|
432
|
+
animation: dots 1.5s steps(4, end) infinite;
|
433
|
+
}
|
434
|
+
|
435
|
+
@keyframes dots {
|
436
|
+
0%, 20% { content: ''; }
|
437
|
+
40% { content: '.'; }
|
438
|
+
60% { content: '..'; }
|
439
|
+
80%, 100% { content: '...'; }
|
440
|
+
}
|
441
|
+
|
442
|
+
/* Suggested Prompts Styling - Always visible above input */
|
443
|
+
.suggested-prompts {
|
444
|
+
margin-bottom: 16px;
|
445
|
+
padding: 0 4px;
|
446
|
+
}
|
447
|
+
|
448
|
+
.prompts-label {
|
449
|
+
font-size: 13px;
|
450
|
+
color: var(--text-secondary);
|
451
|
+
margin-bottom: 8px;
|
452
|
+
font-weight: 500;
|
453
|
+
letter-spacing: 0.3px;
|
454
|
+
}
|
455
|
+
|
456
|
+
.prompts-container {
|
457
|
+
display: flex;
|
458
|
+
flex-direction: column;
|
459
|
+
gap: 6px;
|
460
|
+
}
|
461
|
+
|
462
|
+
.prompts-row {
|
463
|
+
display: flex;
|
464
|
+
gap: 8px;
|
465
|
+
overflow-x: auto;
|
466
|
+
padding: 2px;
|
467
|
+
scrollbar-width: none; /* Firefox */
|
468
|
+
-ms-overflow-style: none; /* IE and Edge */
|
469
|
+
}
|
470
|
+
|
471
|
+
.prompts-row::-webkit-scrollbar {
|
472
|
+
display: none; /* Chrome, Safari, Opera */
|
473
|
+
}
|
474
|
+
|
475
|
+
.prompt-button {
|
476
|
+
background: rgba(255, 255, 255, 0.03);
|
477
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
478
|
+
border-radius: 6px;
|
479
|
+
padding: 8px 12px;
|
480
|
+
color: var(--text-secondary);
|
481
|
+
font-size: 13px;
|
482
|
+
cursor: pointer;
|
483
|
+
transition: all 0.2s ease;
|
484
|
+
font-family: inherit;
|
485
|
+
white-space: nowrap;
|
486
|
+
flex-shrink: 0;
|
487
|
+
min-width: fit-content;
|
488
|
+
}
|
489
|
+
|
490
|
+
.prompt-button:hover {
|
491
|
+
background: rgba(33, 150, 243, 0.08);
|
492
|
+
border-color: rgba(33, 150, 243, 0.2);
|
493
|
+
color: var(--text-primary);
|
494
|
+
transform: translateY(-1px);
|
495
|
+
}
|
496
|
+
|
497
|
+
.prompt-button:active {
|
498
|
+
transform: translateY(0);
|
499
|
+
}
|
500
|
+
|
501
|
+
@media (max-width: 768px) {
|
502
|
+
.prompts-grid {
|
503
|
+
grid-template-columns: 1fr;
|
504
|
+
}
|
505
|
+
|
506
|
+
.prompt-button {
|
507
|
+
font-size: 13px;
|
508
|
+
padding: 10px 14px;
|
509
|
+
}
|
510
|
+
}
|
408
511
|
</style>
|
409
512
|
<%= javascript_importmap_tags %>
|
410
513
|
<%= javascript_include_tag "llama_bot_rails/application" %>
|
@@ -431,7 +534,7 @@
|
|
431
534
|
</button>
|
432
535
|
<div class="logo-container">
|
433
536
|
<img src="https://service-jobs-images.s3.us-east-2.amazonaws.com/7rl98t1weu387r43il97h6ipk1l7" alt="LlamaBot Logo" class="logo">
|
434
|
-
<div id="connectionStatusIconForLlamaBot" class="connection-status status-
|
537
|
+
<div id="connectionStatusIconForLlamaBot" class="connection-status status-yellow"></div>
|
435
538
|
</div>
|
436
539
|
<h1>LlamaBot Chat</h1>
|
437
540
|
</div>
|
@@ -445,6 +548,30 @@
|
|
445
548
|
<div class="chat-messages" id="chat-messages">
|
446
549
|
<!-- Messages will be added here dynamically -->
|
447
550
|
</div>
|
551
|
+
|
552
|
+
<!-- Simple loading indicator with just animated text -->
|
553
|
+
<div class="loading-indicator" id="loading-indicator">
|
554
|
+
<span class="loading-text">LlamaBot is thinking<span class="loading-dots"></span></span>
|
555
|
+
</div>
|
556
|
+
|
557
|
+
<!-- Suggested Prompts - Always visible above input -->
|
558
|
+
<div class="suggested-prompts" id="suggested-prompts">
|
559
|
+
<div class="prompts-label">Quick actions:</div>
|
560
|
+
<div class="prompts-container">
|
561
|
+
<div class="prompts-row">
|
562
|
+
<button class="prompt-button" onclick="selectPrompt(this)">What models are defined in this app?</button>
|
563
|
+
<button class="prompt-button" onclick="selectPrompt(this)">What routes exist?</button>
|
564
|
+
<button class="prompt-button" onclick="selectPrompt(this)">How many users are in the database?</button>
|
565
|
+
<button class="prompt-button" onclick="selectPrompt(this)">Show me the schema for the User model</button>
|
566
|
+
</div>
|
567
|
+
<div class="prompts-row">
|
568
|
+
<button class="prompt-button" onclick="selectPrompt(this)">Send a text with Twilio</button>
|
569
|
+
<button class="prompt-button" onclick="selectPrompt(this)">Create a BlogPost with title and body fields</button>
|
570
|
+
<button class="prompt-button" onclick="selectPrompt(this)">Generate a scaffolded Page model</button>
|
571
|
+
</div>
|
572
|
+
</div>
|
573
|
+
</div>
|
574
|
+
|
448
575
|
<div class="input-container">
|
449
576
|
<input type="text" id="message-input" placeholder="Type your message...">
|
450
577
|
<button onclick="sendMessage()">Send</button>
|
@@ -478,7 +605,9 @@
|
|
478
605
|
}
|
479
606
|
|
480
607
|
waitForCableConnection((consumer) => {
|
481
|
-
|
608
|
+
const sessionId = crypto.randomUUID();
|
609
|
+
|
610
|
+
subscription = consumer.subscriptions.create({channel: 'LlamaBotRails::ChatChannel', session_id: sessionId}, {
|
482
611
|
connected() {
|
483
612
|
console.log('Connected to chat channel');
|
484
613
|
lastPongTime = Date.now();
|
@@ -692,11 +821,6 @@
|
|
692
821
|
|
693
822
|
// Show welcome message
|
694
823
|
showWelcomeMessage();
|
695
|
-
|
696
|
-
// Clear active thread selection
|
697
|
-
document.querySelectorAll('.thread-item').forEach(item => {
|
698
|
-
item.classList.remove('active');
|
699
|
-
});
|
700
824
|
}
|
701
825
|
|
702
826
|
function showWelcomeMessage() {
|
@@ -710,6 +834,33 @@
|
|
710
834
|
messagesDiv.appendChild(welcomeDiv);
|
711
835
|
}
|
712
836
|
|
837
|
+
function showLoadingIndicator() {
|
838
|
+
const loadingIndicator = document.getElementById('loading-indicator');
|
839
|
+
loadingIndicator.classList.add('visible');
|
840
|
+
}
|
841
|
+
|
842
|
+
function hideLoadingIndicator() {
|
843
|
+
const loadingIndicator = document.getElementById('loading-indicator');
|
844
|
+
loadingIndicator.classList.remove('visible');
|
845
|
+
}
|
846
|
+
|
847
|
+
function selectPrompt(buttonElement) {
|
848
|
+
const promptText = buttonElement.textContent;
|
849
|
+
const messageInput = document.getElementById('message-input');
|
850
|
+
|
851
|
+
// Populate the input field
|
852
|
+
messageInput.value = promptText;
|
853
|
+
|
854
|
+
// Focus the input field for better UX
|
855
|
+
messageInput.focus();
|
856
|
+
|
857
|
+
// Add a subtle animation to show the prompt was selected
|
858
|
+
buttonElement.style.transform = 'scale(0.98)';
|
859
|
+
setTimeout(() => {
|
860
|
+
buttonElement.style.transform = '';
|
861
|
+
}, 150);
|
862
|
+
}
|
863
|
+
|
713
864
|
function sendMessage() {
|
714
865
|
const input = document.getElementById('message-input');
|
715
866
|
const message = input.value.trim();
|
@@ -731,6 +882,9 @@
|
|
731
882
|
addMessage(message, 'human');
|
732
883
|
input.value = '';
|
733
884
|
|
885
|
+
// Show loading indicator
|
886
|
+
showLoadingIndicator();
|
887
|
+
|
734
888
|
// Generate timestamp-based thread ID if we don't have one
|
735
889
|
let threadId = currentThreadId;
|
736
890
|
if (!threadId || threadId === 'global_thread_id') {
|
@@ -764,6 +918,11 @@
|
|
764
918
|
function addMessage(text, sender, base_message=null) {
|
765
919
|
console.log('🧠 Message from LlamaBot:', text, sender, base_message);
|
766
920
|
|
921
|
+
// Hide loading indicator when we receive an AI response
|
922
|
+
if (sender === 'ai') {
|
923
|
+
hideLoadingIndicator();
|
924
|
+
}
|
925
|
+
|
767
926
|
const messagesDiv = document.getElementById('chat-messages');
|
768
927
|
const messageDiv = document.createElement('div');
|
769
928
|
messageDiv.className = `message ${sender}-message`;
|