Spaces:
Running
Running
joseph njoroge kariuki commited on
Commit ·
2c53226
1
Parent(s): af72f78
style: optimize topbar, chat container and sub-pages for fluid flexbox layout and mobile viewport sizes; fix superpacks process logger on crash
Browse files- frontend/src/app-personal-business/chat/ChatContainer.jsx +1 -1
- frontend/src/app-personal-business/layout/AppShell.jsx +1 -1
- frontend/src/app-personal-business/layout/TopBar.jsx +8 -5
- frontend/src/app-personal-business/pages/FilesPage.jsx +1 -1
- frontend/src/app-personal-business/pages/GoalsPage.jsx +1 -1
- frontend/src/app-personal-business/pages/MemoryPage.jsx +1 -1
- frontend/src/app-personal-business/pages/ProjectsPage.jsx +1 -1
- frontend/src/app-personal-business/pages/SettingsPage.jsx +1 -1
- senti/backend/api/main.py +14 -0
- senti/start_superpacks.py +19 -3
frontend/src/app-personal-business/chat/ChatContainer.jsx
CHANGED
|
@@ -89,7 +89,7 @@ export default function ChatContainer() {
|
|
| 89 |
}
|
| 90 |
|
| 91 |
return (
|
| 92 |
-
<div className="
|
| 93 |
|
| 94 |
{/* Context bar */}
|
| 95 |
<div className={`
|
|
|
|
| 89 |
}
|
| 90 |
|
| 91 |
return (
|
| 92 |
+
<div className="flex-1 min-h-0 relative flex flex-col overflow-hidden">
|
| 93 |
|
| 94 |
{/* Context bar */}
|
| 95 |
<div className={`
|
frontend/src/app-personal-business/layout/AppShell.jsx
CHANGED
|
@@ -33,7 +33,7 @@ export default function AppShell({ children }) {
|
|
| 33 |
<Sidebar collapsed={sidebarCollapsed} />
|
| 34 |
|
| 35 |
{/* Main Content Area */}
|
| 36 |
-
<main className={`md:ml-80 h-screen flex flex-col relative transition-all duration-300 z-10 ${sidebarCollapsed ? 'md:ml-0' : ''}`}>
|
| 37 |
<TopBar onToggleSidebar={() => setSidebarCollapsed(!sidebarCollapsed)} />
|
| 38 |
{children}
|
| 39 |
</main>
|
|
|
|
| 33 |
<Sidebar collapsed={sidebarCollapsed} />
|
| 34 |
|
| 35 |
{/* Main Content Area */}
|
| 36 |
+
<main className={`md:ml-80 h-screen pb-16 md:pb-0 flex flex-col relative transition-all duration-300 z-10 ${sidebarCollapsed ? 'md:ml-0' : ''}`}>
|
| 37 |
<TopBar onToggleSidebar={() => setSidebarCollapsed(!sidebarCollapsed)} />
|
| 38 |
{children}
|
| 39 |
</main>
|
frontend/src/app-personal-business/layout/TopBar.jsx
CHANGED
|
@@ -4,16 +4,19 @@ export default function TopBar({ onToggleSidebar }) {
|
|
| 4 |
const { tier, setTier } = useTierStore()
|
| 5 |
|
| 6 |
return (
|
| 7 |
-
<header className="
|
| 8 |
<div className="flex items-center gap-3">
|
| 9 |
<button onClick={onToggleSidebar} className="text-senti-on-surface-variant">
|
| 10 |
<span className="material-symbols-outlined">menu</span>
|
| 11 |
</button>
|
| 12 |
<div>
|
| 13 |
-
<h2 className={`font-display text-xl font-bold tracking-tight ${tier === 'business' ? 'text-senti-blue-400' : 'text-senti-primary'}`}>
|
| 14 |
-
{tier === 'business' ? 'Corporate Intelligence' : 'AI Wealth Intelligence'}
|
|
|
|
| 15 |
</h2>
|
| 16 |
-
<p className="text-[10px] text-senti-on-surface-variant uppercase tracking-tighter font-bold">
|
|
|
|
|
|
|
| 17 |
</div>
|
| 18 |
</div>
|
| 19 |
|
|
@@ -40,7 +43,7 @@ export default function TopBar({ onToggleSidebar }) {
|
|
| 40 |
</div>
|
| 41 |
|
| 42 |
<div className="flex items-center gap-2">
|
| 43 |
-
<button className="p-2 rounded-full hover:bg-senti-primary-container/10 transition-colors duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] btn-press">
|
| 44 |
<span className="material-symbols-outlined text-senti-primary">share</span>
|
| 45 |
</button>
|
| 46 |
<button className="p-2 rounded-full hover:bg-senti-primary-container/10 transition-colors duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] btn-press">
|
|
|
|
| 4 |
const { tier, setTier } = useTierStore()
|
| 5 |
|
| 6 |
return (
|
| 7 |
+
<header className="w-full flex-shrink-0 z-40 flex justify-between items-center px-4 h-16 bg-white/5 backdrop-blur-2xl border-b border-white/10 shadow-sm">
|
| 8 |
<div className="flex items-center gap-3">
|
| 9 |
<button onClick={onToggleSidebar} className="text-senti-on-surface-variant">
|
| 10 |
<span className="material-symbols-outlined">menu</span>
|
| 11 |
</button>
|
| 12 |
<div>
|
| 13 |
+
<h2 className={`font-display text-base md:text-xl font-bold tracking-tight ${tier === 'business' ? 'text-senti-blue-400' : 'text-senti-primary'}`}>
|
| 14 |
+
<span className="hidden md:inline">{tier === 'business' ? 'Corporate Intelligence' : 'AI Wealth Intelligence'}</span>
|
| 15 |
+
<span className="inline md:hidden">{tier === 'business' ? 'Senti Biz' : 'Senti AI'}</span>
|
| 16 |
</h2>
|
| 17 |
+
<p className="text-[9px] md:text-[10px] text-senti-on-surface-variant uppercase tracking-tighter font-bold">
|
| 18 |
+
Senti Model 4.5 • <span className="hidden sm:inline">Ultra-Secure • </span>{tier === 'business' ? 'Biz' : 'Personal'}
|
| 19 |
+
</p>
|
| 20 |
</div>
|
| 21 |
</div>
|
| 22 |
|
|
|
|
| 43 |
</div>
|
| 44 |
|
| 45 |
<div className="flex items-center gap-2">
|
| 46 |
+
<button className="hidden md:flex p-2 rounded-full hover:bg-senti-primary-container/10 transition-colors duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] btn-press">
|
| 47 |
<span className="material-symbols-outlined text-senti-primary">share</span>
|
| 48 |
</button>
|
| 49 |
<button className="p-2 rounded-full hover:bg-senti-primary-container/10 transition-colors duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] btn-press">
|
frontend/src/app-personal-business/pages/FilesPage.jsx
CHANGED
|
@@ -88,7 +88,7 @@ export default function FilesPage() {
|
|
| 88 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 89 |
|
| 90 |
return (
|
| 91 |
-
<div className="p-6 md:p-8 max-w-5xl mx-auto space-y-8
|
| 92 |
|
| 93 |
{/* Header */}
|
| 94 |
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
|
|
|
| 88 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 89 |
|
| 90 |
return (
|
| 91 |
+
<div className="flex-1 min-h-0 overflow-y-auto p-6 md:p-8 max-w-5xl mx-auto space-y-8 pb-24 chat-scroll">
|
| 92 |
|
| 93 |
{/* Header */}
|
| 94 |
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
frontend/src/app-personal-business/pages/GoalsPage.jsx
CHANGED
|
@@ -95,7 +95,7 @@ export default function GoalsPage() {
|
|
| 95 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 96 |
|
| 97 |
return (
|
| 98 |
-
<div className="p-6 md:p-8 max-w-5xl mx-auto space-y-8
|
| 99 |
|
| 100 |
{/* Header */}
|
| 101 |
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
|
|
|
| 95 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 96 |
|
| 97 |
return (
|
| 98 |
+
<div className="flex-1 min-h-0 overflow-y-auto p-6 md:p-8 max-w-5xl mx-auto space-y-8 pb-24 chat-scroll">
|
| 99 |
|
| 100 |
{/* Header */}
|
| 101 |
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
frontend/src/app-personal-business/pages/MemoryPage.jsx
CHANGED
|
@@ -64,7 +64,7 @@ export default function MemoryPage() {
|
|
| 64 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 65 |
|
| 66 |
return (
|
| 67 |
-
<div className="p-6 md:p-8 max-w-5xl mx-auto space-y-8
|
| 68 |
|
| 69 |
{/* Header */}
|
| 70 |
<div className="flex items-center justify-between">
|
|
|
|
| 64 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 65 |
|
| 66 |
return (
|
| 67 |
+
<div className="flex-1 min-h-0 overflow-y-auto p-6 md:p-8 max-w-5xl mx-auto space-y-8 pb-24 chat-scroll">
|
| 68 |
|
| 69 |
{/* Header */}
|
| 70 |
<div className="flex items-center justify-between">
|
frontend/src/app-personal-business/pages/ProjectsPage.jsx
CHANGED
|
@@ -99,7 +99,7 @@ export default function ProjectsPage() {
|
|
| 99 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 100 |
|
| 101 |
return (
|
| 102 |
-
<div className="p-6 md:p-8 max-w-5xl mx-auto space-y-8
|
| 103 |
|
| 104 |
{/* Header */}
|
| 105 |
<div className="flex items-center justify-between">
|
|
|
|
| 99 |
const cardRadius = isBiz ? 'rounded-senti-business' : 'rounded-senti-personal'
|
| 100 |
|
| 101 |
return (
|
| 102 |
+
<div className="flex-1 min-h-0 overflow-y-auto p-6 md:p-8 max-w-5xl mx-auto space-y-8 pb-24 chat-scroll">
|
| 103 |
|
| 104 |
{/* Header */}
|
| 105 |
<div className="flex items-center justify-between">
|
frontend/src/app-personal-business/pages/SettingsPage.jsx
CHANGED
|
@@ -85,7 +85,7 @@ export default function SettingsPage() {
|
|
| 85 |
const tierBadgeText = isInst ? 'Institutional Tier' : (isBiz ? 'Enterprise Tier' : 'Premium Tier')
|
| 86 |
|
| 87 |
return (
|
| 88 |
-
<div className="p-6 md:p-8 max-w-5xl mx-auto space-y-8
|
| 89 |
|
| 90 |
{/* Header */}
|
| 91 |
<div className="flex items-center gap-3 mb-2">
|
|
|
|
| 85 |
const tierBadgeText = isInst ? 'Institutional Tier' : (isBiz ? 'Enterprise Tier' : 'Premium Tier')
|
| 86 |
|
| 87 |
return (
|
| 88 |
+
<div className="flex-1 min-h-0 overflow-y-auto p-6 md:p-8 max-w-5xl mx-auto space-y-8 pb-24 chat-scroll">
|
| 89 |
|
| 90 |
{/* Header */}
|
| 91 |
<div className="flex items-center gap-3 mb-2">
|
senti/backend/api/main.py
CHANGED
|
@@ -695,6 +695,20 @@ async def reset_pin(body: ResetPinRequest, db: SessionLocal = Depends(get_db)):
|
|
| 695 |
db.commit()
|
| 696 |
return {"message": "PIN reset successfully. You can now log in."}
|
| 697 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 698 |
# --- FOUR MODES FRAMEWORK ---
|
| 699 |
class ResponseMode(Enum):
|
| 700 |
ADVISOR = "advisor"
|
|
|
|
| 695 |
db.commit()
|
| 696 |
return {"message": "PIN reset successfully. You can now log in."}
|
| 697 |
|
| 698 |
+
@api_router.get("/admin/superpack-logs/{name}", tags=["admin"])
|
| 699 |
+
async def get_superpack_log(name: str):
|
| 700 |
+
import os
|
| 701 |
+
safe_name = "".join(c for c in name if c.isalnum() or c == "_")
|
| 702 |
+
log_path = f"/tmp/superpack_{safe_name}.log"
|
| 703 |
+
if not os.path.exists(log_path):
|
| 704 |
+
return {"error": "Log file not found", "path": log_path}
|
| 705 |
+
try:
|
| 706 |
+
with open(log_path, "r", encoding="utf-8", errors="ignore") as f:
|
| 707 |
+
content = f.read()
|
| 708 |
+
return {"name": safe_name, "log": content[-10000:]}
|
| 709 |
+
except Exception as e:
|
| 710 |
+
return {"error": str(e)}
|
| 711 |
+
|
| 712 |
# --- FOUR MODES FRAMEWORK ---
|
| 713 |
class ResponseMode(Enum):
|
| 714 |
ADVISOR = "advisor"
|
senti/start_superpacks.py
CHANGED
|
@@ -23,8 +23,9 @@ superpacks = {
|
|
| 23 |
}
|
| 24 |
|
| 25 |
processes = []
|
|
|
|
| 26 |
|
| 27 |
-
# Ensure /tmp exists
|
| 28 |
os.makedirs("/tmp", exist_ok=True)
|
| 29 |
|
| 30 |
# Base directory is the parent of senti/
|
|
@@ -47,6 +48,7 @@ for name, port in superpacks.items():
|
|
| 47 |
cwd=base_dir
|
| 48 |
)
|
| 49 |
processes.append(p)
|
|
|
|
| 50 |
except Exception as e:
|
| 51 |
print(f"[SUPERPACKS] Failed to start {name}: {e}")
|
| 52 |
else:
|
|
@@ -58,11 +60,25 @@ print(f"[SUPERPACKS] Started {len(processes)} superpacks in background.")
|
|
| 58 |
try:
|
| 59 |
while True:
|
| 60 |
time.sleep(10)
|
| 61 |
-
|
| 62 |
for p in processes:
|
| 63 |
if p.poll() is not None:
|
| 64 |
# Process ended
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
except KeyboardInterrupt:
|
| 67 |
print("[SUPERPACKS] Terminating processes...")
|
| 68 |
for p in processes:
|
|
|
|
| 23 |
}
|
| 24 |
|
| 25 |
processes = []
|
| 26 |
+
process_info = {} # p -> (name, log_path)
|
| 27 |
|
| 28 |
+
# Ensure /tmp exists
|
| 29 |
os.makedirs("/tmp", exist_ok=True)
|
| 30 |
|
| 31 |
# Base directory is the parent of senti/
|
|
|
|
| 48 |
cwd=base_dir
|
| 49 |
)
|
| 50 |
processes.append(p)
|
| 51 |
+
process_info[p] = (name, log_path)
|
| 52 |
except Exception as e:
|
| 53 |
print(f"[SUPERPACKS] Failed to start {name}: {e}")
|
| 54 |
else:
|
|
|
|
| 60 |
try:
|
| 61 |
while True:
|
| 62 |
time.sleep(10)
|
| 63 |
+
active_processes = []
|
| 64 |
for p in processes:
|
| 65 |
if p.poll() is not None:
|
| 66 |
# Process ended
|
| 67 |
+
name, log_path = process_info.get(p, ("Unknown", ""))
|
| 68 |
+
print(f"[SUPERPACKS] WARNING: {name} (PID {p.pid}) terminated with exit code {p.returncode}")
|
| 69 |
+
if log_path and os.path.exists(log_path):
|
| 70 |
+
print(f"--- {name} stdout/stderr log last 20 lines: ---")
|
| 71 |
+
try:
|
| 72 |
+
with open(log_path, "r", encoding="utf-8", errors="ignore") as lf:
|
| 73 |
+
lines = lf.readlines()
|
| 74 |
+
for line in lines[-20:]:
|
| 75 |
+
print(f" {line.rstrip()}")
|
| 76 |
+
except Exception as le:
|
| 77 |
+
print(f" Failed to read log: {le}")
|
| 78 |
+
print("------------------------------------------")
|
| 79 |
+
else:
|
| 80 |
+
active_processes.append(p)
|
| 81 |
+
processes = active_processes
|
| 82 |
except KeyboardInterrupt:
|
| 83 |
print("[SUPERPACKS] Terminating processes...")
|
| 84 |
for p in processes:
|