feat(chatbot): per-user history via X-User-Id + agentic tools calling
Backend: - New chatbot.tools.ts: 4 tools (get_server_stats, get_top_channels, get_recent_activity, get_top_flagged) with real DB executors - chatbot.service: agentic loop — stream:true, parse SSE, execute tool_calls, feed results back, up to 4 rounds - controller: resolve userId from X-User-Id header (no-login device uuid) with auth middleware precedence; history/clear scoped per user Frontend: - use-chatbot-user: mint UUID in localStorage, send as X-User-Id - chatbotApi.send/getHistory/clearHistory accept userId header - client.ts: apiRequest supports custom headers per call - provider: history load + send + clear keyed to device user id
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const STORAGE_KEY = "gmw-chatbot-user-id";
|
||||
|
||||
/**
|
||||
* Per-device anonymous identity. The app has no login, so we mint a random
|
||||
* UUID on first visit, persist it to localStorage, and send it as the
|
||||
* X-User-Id header. Each visitor gets their own chat history — the backend
|
||||
* keys `chatbot_messages` by this id.
|
||||
*/
|
||||
export function useChatbotUserId(): string {
|
||||
const [userId, setUserId] = useState<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
let id = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (!id || id.length < 16) {
|
||||
id =
|
||||
typeof crypto !== "undefined" && crypto.randomUUID
|
||||
? crypto.randomUUID()
|
||||
: `u_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 12)}`;
|
||||
window.localStorage.setItem(STORAGE_KEY, id);
|
||||
}
|
||||
setUserId(id);
|
||||
} catch {
|
||||
// localStorage unavailable (private mode) — use in-memory fallback
|
||||
setUserId(
|
||||
typeof crypto !== "undefined" && crypto.randomUUID
|
||||
? crypto.randomUUID()
|
||||
: `u_${Date.now().toString(36)}`,
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return userId;
|
||||
}
|
||||
|
||||
export { STORAGE_KEY };
|
||||
Reference in New Issue
Block a user