mirror of
https://github.com/aljazceru/enclava.git
synced 2025-12-17 23:44:24 +01:00
working chatbot, rag weird
This commit is contained in:
6
frontend/package-lock.json
generated
6
frontend/package-lock.json
generated
@@ -2613,9 +2613,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
|
||||
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
|
||||
"version": "1.12.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
|
||||
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { Suspense } from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -93,7 +94,7 @@ const PERMISSION_OPTIONS = [
|
||||
{ value: "llm:embeddings", label: "LLM Embeddings" },
|
||||
];
|
||||
|
||||
export default function ApiKeysPage() {
|
||||
function ApiKeysContent() {
|
||||
const { toast } = useToast();
|
||||
const searchParams = useSearchParams();
|
||||
const [apiKeys, setApiKeys] = useState<ApiKey[]>([]);
|
||||
@@ -905,4 +906,12 @@ export default function ApiKeysPage() {
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function ApiKeysPage() {
|
||||
return (
|
||||
<Suspense fallback={<div>Loading API keys...</div>}>
|
||||
<ApiKeysContent />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -87,9 +87,8 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface
|
||||
const [messages, setMessages] = useState<ChatMessage[]>([])
|
||||
const [input, setInput] = useState("")
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [conversationId, setConversationId] = useState<string | null>(null)
|
||||
const scrollAreaRef = useRef<HTMLDivElement>(null)
|
||||
const { toast } = useToast()
|
||||
const { success: toastSuccess, error: toastError } = useToast()
|
||||
|
||||
const scrollToBottom = useCallback(() => {
|
||||
if (scrollAreaRef.current) {
|
||||
@@ -120,23 +119,20 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface
|
||||
setIsLoading(true)
|
||||
|
||||
try {
|
||||
// Build conversation history in OpenAI format
|
||||
let data: any
|
||||
|
||||
// Use internal API
|
||||
const conversationHistory = messages.map(msg => ({
|
||||
role: msg.role,
|
||||
content: msg.content
|
||||
}))
|
||||
|
||||
const data = await chatbotApi.sendMessage(
|
||||
|
||||
data = await chatbotApi.sendMessage(
|
||||
chatbotId,
|
||||
messageToSend,
|
||||
conversationId || undefined,
|
||||
undefined, // No conversation ID
|
||||
conversationHistory
|
||||
)
|
||||
|
||||
// Update conversation ID if it's a new conversation
|
||||
if (!conversationId && data.conversation_id) {
|
||||
setConversationId(data.conversation_id)
|
||||
}
|
||||
|
||||
const assistantMessage: ChatMessage = {
|
||||
id: data.message_id || generateTimestampId('msg'),
|
||||
@@ -153,16 +149,16 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface
|
||||
|
||||
// More specific error handling
|
||||
if (appError.code === 'UNAUTHORIZED') {
|
||||
toast.error("Authentication Required", "Please log in to continue chatting.")
|
||||
toastError("Authentication Required", "Please log in to continue chatting.")
|
||||
} else if (appError.code === 'NETWORK_ERROR') {
|
||||
toast.error("Connection Error", "Please check your internet connection and try again.")
|
||||
toastError("Connection Error", "Please check your internet connection and try again.")
|
||||
} else {
|
||||
toast.error("Message Failed", appError.message || "Failed to send message. Please try again.")
|
||||
toastError("Message Failed", appError.message || "Failed to send message. Please try again.")
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
}, [input, isLoading, chatbotId, conversationId, messages, toast])
|
||||
}, [input, isLoading, chatbotId, messages, toastError])
|
||||
|
||||
const handleKeyPress = useCallback((e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
@@ -174,11 +170,11 @@ export function ChatInterface({ chatbotId, chatbotName, onClose }: ChatInterface
|
||||
const copyMessage = useCallback(async (content: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(content)
|
||||
toast.success("Copied", "Message copied to clipboard")
|
||||
toastSuccess("Copied", "Message copied to clipboard")
|
||||
} catch (error) {
|
||||
toast.error("Copy Failed", "Unable to copy message to clipboard")
|
||||
toastError("Copy Failed", "Unable to copy message to clipboard")
|
||||
}
|
||||
}, [toast])
|
||||
}, [toastSuccess, toastError])
|
||||
|
||||
const formatTime = useCallback((date: Date) => {
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
||||
|
||||
@@ -138,6 +138,7 @@ export function ChatbotManager() {
|
||||
const [editingChatbot, setEditingChatbot] = useState<ChatbotInstance | null>(null)
|
||||
const [showChatInterface, setShowChatInterface] = useState(false)
|
||||
const [testingChatbot, setTestingChatbot] = useState<ChatbotInstance | null>(null)
|
||||
const [chatbotApiKeys, setChatbotApiKeys] = useState<Record<string, string>>({})
|
||||
const { toast } = useToast()
|
||||
|
||||
// New chatbot form state
|
||||
|
||||
@@ -86,11 +86,31 @@ export const chatbotApi = {
|
||||
deleteChatbot(id: string) {
|
||||
return apiClient.delete(`/api-internal/v1/chatbot/delete/${encodeURIComponent(id)}`)
|
||||
},
|
||||
// Legacy method with JWT auth (to be deprecated)
|
||||
sendMessage(chatbotId: string, message: string, conversationId?: string, history?: Array<{role: string; content: string}>) {
|
||||
const body: any = { chatbot_id: chatbotId, message }
|
||||
const body: any = { message }
|
||||
if (conversationId) body.conversation_id = conversationId
|
||||
if (history) body.history = history
|
||||
return apiClient.post('/api-internal/v1/chatbot/chat', body)
|
||||
return apiClient.post(`/api-internal/v1/chatbot/chat/${encodeURIComponent(chatbotId)}`, body)
|
||||
},
|
||||
// OpenAI-compatible chatbot API with API key auth
|
||||
sendOpenAIChatMessage(chatbotId: string, messages: Array<{role: string; content: string}>, apiKey: string, options?: {
|
||||
temperature?: number
|
||||
max_tokens?: number
|
||||
stream?: boolean
|
||||
}) {
|
||||
const body: any = {
|
||||
messages,
|
||||
...options
|
||||
}
|
||||
return fetch(`/api/v1/chatbot/external/${encodeURIComponent(chatbotId)}/chat/completions`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${apiKey}`
|
||||
},
|
||||
body: JSON.stringify(body)
|
||||
}).then(res => res.json())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user