Skip to content

Commit

Permalink
Integrated Bot with UI changes (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
kpeluso authored Feb 26, 2025
2 parents 2c60fdf + 1f6c3c7 commit 1ad6f7e
Show file tree
Hide file tree
Showing 4 changed files with 364 additions and 10 deletions.
69 changes: 69 additions & 0 deletions .github/workflows/flux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: build-and-push-docker-image

on:
push:
branches:
- chore/Dockerize-Python

permissions:
contents: write

jobs:
build-and-push-docker-image:
runs-on: ubuntu-latest
steps:

- name: 'Setup yq'
uses: dcarbone/install-yq-action@v1

- name: Checkout code
uses: actions/checkout@v2

- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1

- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1

- name: Get version
run: |
VERSION=$(cat API/VERSION)
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Build, Tag, and Push Worker Image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: allora-chatbot-rag-model
IMAGE_BASE_PATH: API
VERSION: ${{ env.VERSION }}
run: |
IMAGE_TAG="${GITHUB_SHA:0:8}"
EXTRA_IMAGE_TAGS="${VERSION};latest"
# Build and push the image to ECR with the main image tag
docker build --pull -f ${{ env.IMAGE_BASE_PATH }}/Dockerfile -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ${{ env.IMAGE_BASE_PATH }}
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
# Build and PUSH additional tags
for tag in $(echo $EXTRA_IMAGE_TAGS| tr ";" "\n"); do
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$tag
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$tag
done
# - name: Update Flux Repo
# env:
# VERSION: ${{ env.VERSION }}
# run: |
# git clone https://github.com/allora-network/flux-infra-offchain.git
# cd flux-infra-offchain
# git checkout main
# git pull
# yq -i '.spec.values.containers.chatbot.image.tag="$VERSION"' apps/offchain-testnet/allora-chatbot-rag-model/values.yaml
# git add apps/offchain-testnet/allora-chatbot-api/values.yaml
# git commit -m "Update allora-chatbot-api tag to $VERSION"
# git push
43 changes: 43 additions & 0 deletions components/AiButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

import React, { useState } from "react";
import ChatComponent from "./chatbutton1"; // Adjust the path as needed

function AiButton() {
// State to control whether the ChatComponent is displayed
const [showChat, setShowChat] = useState(false);

// Toggle function to open or close the chat
const toggleChat = () => {
setShowChat((prev) => !prev);
};

return (
<div style={{ maxWidth: "800px", margin: "0 auto", padding: "20px" }}>
{/* Render the "Ask AI" button if the chat is not shown */}
{!showChat && (
<button
onClick={toggleChat}
style={{
padding: "10px 20px",
fontSize: "16px",
cursor: "pointer",
marginBottom: "20px",
backgroundColor: "#007bff", // Blue background
color: "#fff", // White text
border: "none", // Remove default border
borderRadius: "5px", // Rounded corners
transition: "background-color 0.3s ease", // Smooth hover effect
}}
onMouseOver={(e) => (e.target.style.backgroundColor = "#0056b3")} // Darker blue on hover
onMouseOut={(e) => (e.target.style.backgroundColor = "#007bff")} // Revert on mouse out
>
Ask AI
</button>
)}
{/* Render the ChatComponent when showChat is true, passing the onClose prop */}
{showChat && <ChatComponent onClose={toggleChat} />}
</div>
);
}

export default AiButton;
232 changes: 232 additions & 0 deletions components/chatbutton1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import React, { useState, useRef, useEffect } from "react";

function ChatComponent({ onClose }) {
// holds the current user input and the chat history.
const [inputMessage, setInputMessage] = useState("");
const [chatHistory, setChatHistory] = useState([]);
const [isLoading, setIsLoading] = useState(false);

// this references the chat history container.
const chatContainerRef = useRef(null);

// gives an auto-scroll effect to the bottom whenever the chat history changes.
useEffect(() => {
if (chatContainerRef.current) {
chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
}
}, [chatHistory]);

// this is handler for form submission.
const handleSubmit = async (e) => {
e.preventDefault();

// Store the message and immediately clear the input field
const message = inputMessage;
setInputMessage(""); // Clear input immediately

// Add user's message to the chat history.
const newUserEntry = { sender: "user", text: message };
setChatHistory((prev) => [...prev, newUserEntry]);

// Show loading indicator
setIsLoading(true);

try {
// Send user's message to the FastAPI backend.
const response = await fetch("https://b832b91b8183b88b9c22eda604f1e09.testnet.allora.run/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ message: message }),
});
console.log("API went through");

if (!response.ok) {
throw new Error(`Server error: ${response.statusText}`);
}

// Parse the JSON response.
const data = await response.json();

// Add the assistant's response to the chat history.
const newBotEntry = {
sender: "bot",
text: data.response,
sources: data.sources,
};
setChatHistory((prev) => [...prev, newBotEntry]);
} catch (error) {
console.error("Error fetching chat response:", error);
// display an error message in the UI.
const errorEntry = {
sender: "bot", text: "Sorry, something went wrong."
};
setChatHistory((prev) => [...prev, errorEntry]);
} finally {
// Hide loading indicator
setIsLoading(false);
}
};

return (
<div
className="chat-container"
style={{
maxWidth: "600px",
margin: "0 auto",
backgroundColor: "#000",
color: "#fff",
padding: "20px",
borderRadius: "10px",
}}
>
{/* Header with title and close button */}
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "10px",
}}
>
<h2 style={{ color: "#fff", margin: 0 }}>Chat with our AI</h2>
<button
onClick={onClose}
style={{
background: "transparent",
border: "none",
color: "#fff",
cursor: "pointer",
fontSize: "16px",
}}
aria-label="Close Chat"
>
</button>
</div>

<div
className="chat-history"
ref={chatContainerRef}
style={{
border: "1px solid #ccc",
padding: "10px",
height: "300px",
overflowY: "scroll",
backgroundColor: "#1e1e1e",
position: "relative",
}}
>
{chatHistory.map((entry, index) => (
<div
key={index}
style={{
textAlign: entry.sender === "user" ? "right" : "left",
margin: "10px 0",
}}
>
<div
style={{
display: "inline-block",
background: entry.sender === "user" ? "#4caf50" : "#333",
color: "#fff",
padding: "10px",
borderRadius: "10px",
}}
>
<p style={{ margin: 0 }}>{entry.text}</p>
{entry.sources && entry.sources.length > 0 }
</div>
</div>
))}

{/* Loading indicator */}
{isLoading && (
<div
style={{
textAlign: "left",
margin: "10px 0",
}}
>
<div
style={{
display: "inline-block",
background: "#333",
color: "#fff",
padding: "10px",
borderRadius: "10px",
}}
>
<div className="loading-indicator" style={{ display: "flex", alignItems: "center" }}>
<div
style={{
width: "16px",
height: "16px",
border: "3px solid rgba(255,255,255,0.3)",
borderRadius: "50%",
borderTopColor: "#fff",
animation: "spin 1s ease-in-out infinite",
marginRight: "10px"
}}
/>
<span>Thinking...</span>
</div>
<style jsx>{`
@keyframes spin {
to { transform: rotate(360deg); }
}
`}</style>
</div>
</div>
)}
</div>
<form
onSubmit={handleSubmit}
style={{
marginTop: "10px",
display: "flex",
alignItems: "center",
gap: "10px"
}}
>
<input
type="text"
value={inputMessage}
onChange={(e) => setInputMessage(e.target.value)}
placeholder="Type your message..."
required
style={{
flex: "1",
padding: "10px",
backgroundColor: "#333",
color: "#fff",
border: "1px solid #555",
borderRadius: "5px",
}}
/>
<button
type="submit"
style={{
minWidth: "80px",
padding: "10px 15px",
backgroundColor: "#4caf50",
color: "#fff",
border: "none",
borderRadius: "5px",
cursor: "pointer",
whiteSpace: "nowrap",
height: "40px",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
Send
</button>
</form>
</div>
);
}

export default ChatComponent;
Loading

0 comments on commit 1ad6f7e

Please sign in to comment.