fix(desktop): session persistence — refresh/login/context/empty-content 4-bug fix
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

1. App.tsx: add restoreSession() call on startup to prevent redirect
   to login page after refresh (isRestoring guard + BootstrapScreen)
2. CloneManager: call syncAgents() after loadClones() to restore
   currentAgent and conversation history on app load
3. zclaw-memory: add get_or_create_session() so frontend session UUID
   is persisted directly — kernel no longer creates mismatched IDs
4. openai.rs: assistant message content must be non-empty for
   Kimi/Qwen APIs — replace empty content with meaningful placeholders

Also includes admin-v2 ModelServices unified page (merge providers +
models + API keys into expandable row layout)
This commit is contained in:
iven
2026-03-31 13:38:59 +08:00
parent 3e5d64484e
commit 6cae768401
29 changed files with 1982 additions and 933 deletions

View File

@@ -88,6 +88,20 @@ function App() {
document.title = 'ZCLAW';
}, []);
// Restore SaaS session from OS keyring on startup (before auth gate)
const [isRestoring, setIsRestoring] = useState(true);
useEffect(() => {
const restore = async () => {
try {
await useSaaSStore.getState().restoreSession();
} catch {
// Session restore failed — user will see login page
}
setIsRestoring(false);
};
restore();
}, []);
// Watch for Hands that need approval
useEffect(() => {
const handsNeedingApproval = hands.filter(h => h.status === 'needs_approval');
@@ -345,6 +359,9 @@ function App() {
};
// 登录门禁 — 必须登录才能使用
if (isRestoring) {
return <BootstrapScreen status="Restoring session..." />;
}
if (!isLoggedIn) {
return <LoginPage />;
}

View File

@@ -20,7 +20,11 @@ export function CloneManager() {
useEffect(() => {
if (connected) {
loadClones();
loadClones().then(() => {
// Sync agents in chatStore and restore currentAgent/conversation
const clones = useAgentStore.getState().clones;
useChatStore.getState().syncAgents(clones);
});
}
}, [connected, loadClones]);