Merge pull request #19 from kerbeus-a/feature/per-agent-identity
feat: per-agent identity and session filtering via VITE env vars
This commit is contained in:
11
.env.example
11
.env.example
@@ -8,3 +8,14 @@ VITE_LOCALE=en
|
|||||||
# Optional: client ID sent in the WebSocket connect frame (default: webchat)
|
# Optional: client ID sent in the WebSocket connect frame (default: webchat)
|
||||||
# Set to "openclaw-control-ui" to use OpenClaw's dangerouslyDisableDeviceAuth bypass
|
# Set to "openclaw-control-ui" to use OpenClaw's dangerouslyDisableDeviceAuth bypass
|
||||||
VITE_CLIENT_ID=webchat
|
VITE_CLIENT_ID=webchat
|
||||||
|
|
||||||
|
# Optional: default session key to open on connect (default: agent:main:main)
|
||||||
|
# Set this when deploying for a specific OpenClaw agent other than main.
|
||||||
|
# Example: VITE_AGENT_SESSION=agent:artem:main
|
||||||
|
VITE_AGENT_SESSION=
|
||||||
|
|
||||||
|
# Optional: filter the session list to only show sessions matching this prefix.
|
||||||
|
# Useful when multiple agents share a single gateway and you want each
|
||||||
|
# PinchChat instance to show only its own sessions.
|
||||||
|
# Example: VITE_AGENT_PREFIX=agent:artem:
|
||||||
|
VITE_AGENT_PREFIX=
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function useGateway() {
|
|||||||
const [status, setStatus] = useState<ConnectionStatus>('disconnected');
|
const [status, setStatus] = useState<ConnectionStatus>('disconnected');
|
||||||
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|
||||||
const [sessions, setSessions] = useState<Session[]>([]);
|
const [sessions, setSessions] = useState<Session[]>([]);
|
||||||
const [activeSession, setActiveSession] = useState('agent:main:main');
|
const [activeSession, setActiveSession] = useState(import.meta.env.VITE_AGENT_SESSION || 'agent:main:main');
|
||||||
const [isGenerating, setIsGenerating] = useState(false);
|
const [isGenerating, setIsGenerating] = useState(false);
|
||||||
const [isLoadingHistory, setIsLoadingHistory] = useState(false);
|
const [isLoadingHistory, setIsLoadingHistory] = useState(false);
|
||||||
const [authenticated, setAuthenticated] = useState<boolean | null>(null); // null = checking
|
const [authenticated, setAuthenticated] = useState<boolean | null>(null); // null = checking
|
||||||
@@ -89,7 +89,7 @@ export function useGateway() {
|
|||||||
|
|
||||||
const loadAgentIdentity = useCallback(async () => {
|
const loadAgentIdentity = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await clientRef.current?.send('agent.identity.get', {});
|
const res = await clientRef.current?.send('agent.identity.get', { sessionKey: activeSessionRef.current });
|
||||||
if (res) {
|
if (res) {
|
||||||
setAgentIdentity({
|
setAgentIdentity({
|
||||||
name: res.name as string | undefined,
|
name: res.name as string | undefined,
|
||||||
@@ -108,15 +108,19 @@ export function useGateway() {
|
|||||||
const res = await clientRef.current?.send('sessions.list', {});
|
const res = await clientRef.current?.send('sessions.list', {});
|
||||||
const sessionList = res?.sessions as Array<Record<string, unknown>> | undefined;
|
const sessionList = res?.sessions as Array<Record<string, unknown>> | undefined;
|
||||||
if (sessionList) {
|
if (sessionList) {
|
||||||
|
const agentPrefix = import.meta.env.VITE_AGENT_PREFIX;
|
||||||
|
const filteredSessionList = agentPrefix
|
||||||
|
? sessionList.filter((s) => ((s.key || s.sessionKey) as string).startsWith(agentPrefix))
|
||||||
|
: sessionList;
|
||||||
const deleted = getDeletedSessions();
|
const deleted = getDeletedSessions();
|
||||||
// Reconcile: remove blacklisted keys for sessions that no longer exist on the gateway
|
// Reconcile: remove blacklisted keys for sessions that no longer exist on the gateway
|
||||||
// (they were successfully deleted, so no need to keep hiding them)
|
// (they were successfully deleted, so no need to keep hiding them)
|
||||||
const activeKeys = new Set(sessionList.map((s) => (s.key || s.sessionKey) as string));
|
const activeKeys = new Set(filteredSessionList.map((s) => (s.key || s.sessionKey) as string));
|
||||||
const reconciled = new Set([...deleted].filter((k) => activeKeys.has(k)));
|
const reconciled = new Set([...deleted].filter((k) => activeKeys.has(k)));
|
||||||
if (reconciled.size !== deleted.size) {
|
if (reconciled.size !== deleted.size) {
|
||||||
localStorage.setItem('pinchchat-deleted-sessions', JSON.stringify([...reconciled]));
|
localStorage.setItem('pinchchat-deleted-sessions', JSON.stringify([...reconciled]));
|
||||||
}
|
}
|
||||||
setSessions(sessionList.filter((s) => !deleted.has((s.key || s.sessionKey) as string)).map((s) => ({
|
setSessions(filteredSessionList.filter((s) => !deleted.has((s.key || s.sessionKey) as string)).map((s) => ({
|
||||||
key: (s.key || s.sessionKey) as string,
|
key: (s.key || s.sessionKey) as string,
|
||||||
label: (s.label || s.key || s.sessionKey) as string,
|
label: (s.label || s.key || s.sessionKey) as string,
|
||||||
messageCount: s.messageCount as number | undefined,
|
messageCount: s.messageCount as number | undefined,
|
||||||
|
|||||||
Reference in New Issue
Block a user