working chatbot, rag weird

This commit is contained in:
2025-09-19 20:34:51 +02:00
parent 25778ab94e
commit 0c20de4ca1
9 changed files with 230 additions and 192 deletions

View File

@@ -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",

View File

@@ -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>
);
}

View File

@@ -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' })

View File

@@ -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

View File

@@ -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())
}
}