-
Notifications
You must be signed in to change notification settings - Fork 45k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
372 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
autogpt_platform/frontend/src/components/OttoChatWidget.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
.custom-launcher-button { | ||
background-color: #8b5cf6 !important; | ||
border: none !important; | ||
border-radius: 50% !important; | ||
color: white !important; | ||
cursor: pointer !important; | ||
height: 60px !important; | ||
padding: 18px !important; | ||
position: fixed !important; | ||
right: 35px !important; | ||
bottom: 15px !important; | ||
transition: all 0.2s ease-in-out !important; | ||
width: 60px !important; | ||
z-index: 999 !important; | ||
} | ||
|
||
.custom-launcher-button:hover { | ||
background-color: #7c3aed !important; | ||
transform: scale(1.1) !important; | ||
} | ||
|
||
.rcw-launcher { | ||
display: none !important; | ||
} | ||
|
||
.rcw-widget-container { | ||
height: 65vh !important; | ||
margin-bottom: 50px !important; | ||
border-radius: 10px !important; | ||
max-width: 610px !important; | ||
width: 100% !important; | ||
} | ||
|
||
.rcw-conversation-container { | ||
border-radius: 10px !important; | ||
background-color: white !important; | ||
border: none !important; | ||
} | ||
|
||
.rcw-header { | ||
background-color: #8b5cf6 !important; | ||
border-radius: 10px 10px 0 0 !important; | ||
padding: 0px !important; | ||
min-height: 0px !important; | ||
} | ||
|
||
.rcw-messages-container { | ||
background-color: white !important; | ||
padding: 12px 8px !important; | ||
max-width: 100% !important; | ||
overflow-x: hidden !important; | ||
font-size: 0.9rem !important; | ||
} | ||
|
||
.rcw-message { | ||
padding: 4px 8px !important; | ||
width: auto !important; | ||
max-width: 100% !important; | ||
display: flex !important; | ||
flex-direction: column !important; | ||
margin: 4px 0 !important; | ||
} | ||
|
||
.rcw-message-text { | ||
background-color: #f3f4f6 !important; | ||
color: #1f2937 !important; | ||
border-radius: 8px !important; | ||
padding: 8px !important; | ||
max-width: 100% !important; | ||
word-wrap: break-word !important; | ||
white-space: pre-wrap !important; | ||
overflow-wrap: break-word !important; | ||
line-height: 1.4 !important; | ||
overflow-x: auto !important; | ||
margin: 0 !important; | ||
} | ||
|
||
.rcw-message-text pre { | ||
max-width: 100% !important; | ||
overflow-x: auto !important; | ||
white-space: pre-wrap !important; | ||
word-wrap: break-word !important; | ||
margin: 8px 0 !important; | ||
} | ||
|
||
.rcw-message-text code { | ||
word-wrap: break-word !important; | ||
white-space: pre-wrap !important; | ||
display: block !important; | ||
width: 100% !important; | ||
} | ||
|
||
.rcw-client .rcw-message-text { | ||
background-color: #8b5cf6 !important; | ||
color: white !important; | ||
} | ||
|
||
.rcw-sender { | ||
background-color: white !important; | ||
padding: 10px !important; | ||
border-radius: 0 0 10px 10px !important; | ||
border-top: 1px solid #e5e7eb !important; | ||
} |
145 changes: 145 additions & 0 deletions
145
autogpt_platform/frontend/src/components/OttoChatWidget.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
"use client"; | ||
|
||
import React, { useEffect, useState, useRef } from 'react'; | ||
import { Widget, addResponseMessage, addLinkSnippet, deleteMessages } from 'react-chat-widget'; | ||
import 'react-chat-widget/lib/styles.css'; | ||
import './OttoChatWidget.css'; | ||
import useSupabase from '../hooks/useSupabase'; | ||
|
||
interface Document { | ||
url: string; | ||
relevance_score: number; | ||
} | ||
|
||
interface ApiResponse { | ||
answer: string; | ||
documents: Document[]; | ||
success: boolean; | ||
} | ||
|
||
interface Message { | ||
query: string; | ||
response: string; | ||
} | ||
|
||
interface ChatPayload { | ||
query: string; | ||
conversation_history: { query: string; response: string }[]; | ||
user_id: string; | ||
message_id: string; | ||
} | ||
|
||
const OttoChatWidget = () => { | ||
const [chatWindowOpen, setChatWindowOpen] = useState(false); | ||
const [messages, setMessages] = useState<Message[]>([]); | ||
const welcomeMessageSent = useRef(false); | ||
const processingMessageId = useRef<number | null>(null); | ||
const { user } = useSupabase(); | ||
|
||
useEffect(() => { | ||
if (!welcomeMessageSent.current) { | ||
addResponseMessage('Hello im Otto! Ask me anything about AutoGPT!'); | ||
welcomeMessageSent.current = true; | ||
} | ||
}, []); | ||
|
||
const formatResponse = (data: ApiResponse): void => { | ||
const cleanedResponse = data.answer.replace(/####|###|\*|-/g, ''); | ||
addResponseMessage(cleanedResponse); | ||
}; | ||
|
||
const handleNewUserMessage = async (newMessage: string) => { | ||
|
||
// Generate a message ID with timestamp and 'web' suffix, this is used to identify the message in the database | ||
const messageId = `${Date.now()}-web`; | ||
|
||
setMessages(prev => [...prev, { query: newMessage, response: '' }]); | ||
|
||
addResponseMessage('Processing your question...'); | ||
|
||
try { | ||
const payload: ChatPayload = { | ||
query: newMessage, | ||
conversation_history: messages.map(msg => ({ | ||
query: msg.query, | ||
response: msg.response | ||
})), | ||
user_id: user?.id || 'anonymous', | ||
message_id: messageId | ||
}; | ||
|
||
const response = await fetch('http://192.168.0.39:2344/ask', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
}, | ||
mode: 'cors', | ||
credentials: 'omit', | ||
body: JSON.stringify(payload) | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`API request failed with status ${response.status}`); | ||
} | ||
|
||
const data: ApiResponse = await response.json(); | ||
|
||
deleteMessages(1); | ||
|
||
if (data.success) { | ||
formatResponse(data); | ||
setMessages(prev => { | ||
const newMessages = [...prev]; | ||
newMessages[newMessages.length - 1].response = data.answer; | ||
return newMessages; | ||
}); | ||
} else { | ||
throw new Error('API request was not successful'); | ||
} | ||
|
||
} catch (error) { | ||
deleteMessages(1); | ||
|
||
console.error('Error calling API:', error); | ||
addResponseMessage('Sorry, there was an error processing your message. Please try again.'); | ||
} | ||
}; | ||
|
||
const handleToggle = () => { | ||
setChatWindowOpen(prev => !prev); | ||
}; | ||
|
||
return ( | ||
<Widget | ||
handleNewUserMessage={handleNewUserMessage} | ||
title="Otto Assistant" | ||
subtitle="" | ||
handleToggle={handleToggle} | ||
autofocus={true} | ||
emojis={true} | ||
launcher={(handleToggle: () => void) => ( | ||
<button | ||
onClick={handleToggle} | ||
className="custom-launcher-button" | ||
aria-label="Open chat widget" | ||
> | ||
<svg | ||
viewBox="0 0 24 24" | ||
width="24" | ||
height="24" | ||
stroke="currentColor" | ||
strokeWidth="2" | ||
fill="none" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
> | ||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /> | ||
</svg> | ||
</button> | ||
)} | ||
/> | ||
); | ||
}; | ||
|
||
export default OttoChatWidget; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.