feat(ui): adopt canonical WS session key format + channel filter

- buildNewSessionKey uses agent:{id}:ws:direct:{uuid} format
- sessions.list sends channel:"ws" to filter WS-only sessions
- isOwnSession supports both new and legacy key formats
- Read-only bar now floating with rounded corners
This commit is contained in:
viettranx committed 2026-03-19 21:47:35 +07:00
1 parent 6b747d7571
commit 8409db5890
3 files changed
+10 -9

No files matched your search

+3 -1
View File
@@ -21,11 +21,13 @@ export function buildSessionKey(agentId: string, scope: string): string {
/**
* Check if a session belongs to the current web user.
* Web sessions have scope format: "ws-{userId}-{timestamp}".
* New format: "ws:direct:{convId}" — API already filters by userId, so all WS sessions are own.
* Legacy format: "ws-{userId}-{timestamp}".
* Sessions from other channels (telegram, discord, etc.) are foreign.
*/
export function isOwnSession(sessionKey: string, userId: string): boolean {
if (!userId) return false;
const { scope } = parseSessionKey(sessionKey);
if (scope.startsWith("ws:direct:")) return true;
return scope.startsWith(`ws-${userId}-`);
}
+3 -3
View File
@@ -108,11 +108,11 @@ export function ChatPage() {
const handleAgentChange = useCallback(
(newAgentId: string) => {
setAgentId(newAgentId);
const newKey = `agent:${newAgentId}:ws-${userId}-${Date.now().toString(36)}`;
const newKey = `agent:${newAgentId}:ws:direct:${crypto.randomUUID()}`;
setSessionKey(newKey);
navigate(`/chat/${encodeURIComponent(newKey)}`);
},
[navigate, userId],
[navigate],
);
const handleSend = useCallback(
@@ -235,7 +235,7 @@ export function ChatPage() {
disabled={!connected}
/>
) : (
<div className="flex items-center gap-2 border-t bg-muted/50 px-4 py-3 text-sm text-muted-foreground">
<div className="mx-3 mb-3 flex items-center gap-2 rounded-xl border bg-muted/50 px-4 py-3 text-sm text-muted-foreground shadow-sm">
<Eye className="h-4 w-4" />
{t("readOnly")}
</div>
@@ -10,7 +10,6 @@ import { useAuthStore } from "@/stores/use-auth-store";
*/
export function useChatSessions(agentId: string) {
const ws = useWs();
const userId = useAuthStore((s) => s.userId);
const connected = useAuthStore((s) => s.connected);
const [sessions, setSessions] = useState<SessionInfo[]>([]);
const [loading, setLoading] = useState(true);
@@ -23,7 +22,7 @@ export function useChatSessions(agentId: string) {
try {
const res = await ws.call<{ sessions: SessionInfo[] }>(
Methods.SESSIONS_LIST,
{ agentId },
{ agentId, channel: "ws" },
);
const sorted = (res.sessions ?? []).sort(
(a: SessionInfo, b: SessionInfo) =>
@@ -42,9 +41,9 @@ export function useChatSessions(agentId: string) {
}, [loadSessions]);
const buildNewSessionKey = useCallback(() => {
const ts = Date.now().toString(36);
return `agent:${agentId}:ws-${userId}-${ts}`;
}, [agentId, userId]);
const convId = crypto.randomUUID();
return `agent:${agentId}:ws:direct:${convId}`;
}, [agentId]);
return {
sessions,