fluxy-bot 0.1.41 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/src/App.tsx +2 -1
- package/client/src/components/BuildOverlay.tsx +8 -4
- package/client/src/components/Layout/DashboardLayout.tsx +1 -1
- package/client/src/hooks/useChat.ts +58 -47
- package/dist/assets/{index-CQQ1WiY2.js → index-Bu1DE8L8.js} +22 -22
- package/dist/assets/index-C6m9dj97.css +1 -0
- package/dist/index.html +2 -2
- package/dist/sw.js +1 -1
- package/package.json +1 -1
- package/supervisor/index.ts +5 -2
- package/dist/assets/index-gfMKLDbJ.css +0 -1
package/client/src/App.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import DashboardPage from './components/Dashboard/DashboardPage';
|
|
|
7
7
|
import ChatView from './components/Chat/ChatView';
|
|
8
8
|
import FluxyFab from './components/FluxyFab';
|
|
9
9
|
import BuildOverlay from './components/BuildOverlay';
|
|
10
|
+
|
|
10
11
|
import OnboardWizard from './components/Onboard/OnboardWizard';
|
|
11
12
|
import {
|
|
12
13
|
Sheet,
|
|
@@ -71,6 +72,7 @@ export default function App() {
|
|
|
71
72
|
<>
|
|
72
73
|
<ErrorBoundary fallback={<DashboardError />}>
|
|
73
74
|
<DashboardLayout onOpenOnboard={() => setShowOnboard(true)}>
|
|
75
|
+
<BuildOverlay ws={ws} />
|
|
74
76
|
<DashboardPage />
|
|
75
77
|
</DashboardLayout>
|
|
76
78
|
</ErrorBoundary>
|
|
@@ -117,7 +119,6 @@ export default function App() {
|
|
|
117
119
|
</SheetContent>
|
|
118
120
|
</Sheet>
|
|
119
121
|
|
|
120
|
-
<BuildOverlay ws={ws} />
|
|
121
122
|
<FluxyFab onClick={() => setChatOpen((o) => !o)} />
|
|
122
123
|
|
|
123
124
|
{/* Onboarding wizard overlay */}
|
|
@@ -20,9 +20,13 @@ export default function BuildOverlay({ ws }: Props) {
|
|
|
20
20
|
setCopied(false);
|
|
21
21
|
}),
|
|
22
22
|
ws.on('build:complete', () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
// Wait for API to be healthy before reloading (worker may be restarting)
|
|
24
|
+
const checkAndReload = () => {
|
|
25
|
+
fetch('/api/health')
|
|
26
|
+
.then((r) => { if (r.ok) window.location.reload(); else setTimeout(checkAndReload, 500); })
|
|
27
|
+
.catch(() => setTimeout(checkAndReload, 500));
|
|
28
|
+
};
|
|
29
|
+
checkAndReload();
|
|
26
30
|
}),
|
|
27
31
|
ws.on('build:error', (data: { error: string }) => {
|
|
28
32
|
setState('error');
|
|
@@ -43,7 +47,7 @@ export default function BuildOverlay({ ws }: Props) {
|
|
|
43
47
|
};
|
|
44
48
|
|
|
45
49
|
return (
|
|
46
|
-
<div className="
|
|
50
|
+
<div className="absolute inset-0 z-50 bg-black/80 backdrop-blur-sm flex items-center justify-center p-6">
|
|
47
51
|
{state === 'building' && (
|
|
48
52
|
<div className="text-center">
|
|
49
53
|
<div className="inline-block h-8 w-8 animate-spin rounded-full border-2 border-white/20 border-t-white mb-4" />
|
|
@@ -17,7 +17,7 @@ export default function DashboardLayout({ children, onOpenOnboard }: Props) {
|
|
|
17
17
|
<Sidebar />
|
|
18
18
|
</div>
|
|
19
19
|
{/* Main content */}
|
|
20
|
-
<main className="flex-1 overflow-y-auto p-4 md:p-6">{children}</main>
|
|
20
|
+
<main className="relative flex-1 overflow-y-auto p-4 md:p-6">{children}</main>
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
);
|
|
@@ -52,56 +52,67 @@ export function useChat(ws: WsClient | null) {
|
|
|
52
52
|
.catch(() => {});
|
|
53
53
|
}, []);
|
|
54
54
|
|
|
55
|
-
// Load messages when conversationId is set
|
|
55
|
+
// Load messages when conversationId is set (with retry for worker restarts)
|
|
56
56
|
useEffect(() => {
|
|
57
57
|
if (!conversationId) return;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
58
|
+
let cancelled = false;
|
|
59
|
+
let retries = 0;
|
|
60
|
+
|
|
61
|
+
const loadMessages = () => {
|
|
62
|
+
fetch(`/api/conversations/${conversationId}`)
|
|
63
|
+
.then((r) => {
|
|
64
|
+
if (!r.ok) throw new Error('not found');
|
|
65
|
+
return r.json();
|
|
66
|
+
})
|
|
67
|
+
.then((data) => {
|
|
68
|
+
if (cancelled) return;
|
|
69
|
+
if (data.messages?.length) {
|
|
70
|
+
setMessages(
|
|
71
|
+
data.messages
|
|
72
|
+
.filter((m: any) => m.role === 'user' || m.role === 'assistant')
|
|
73
|
+
.map((m: any) => {
|
|
74
|
+
let audioData: string | undefined;
|
|
75
|
+
if (m.audio_data) {
|
|
76
|
+
if (m.audio_data.startsWith('data:')) {
|
|
77
|
+
audioData = m.audio_data;
|
|
78
|
+
} else if (m.audio_data.includes('/')) {
|
|
79
|
+
audioData = `/api/files/${m.audio_data}`;
|
|
80
|
+
} else {
|
|
81
|
+
audioData = `data:audio/webm;base64,${m.audio_data}`;
|
|
82
|
+
}
|
|
78
83
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
84
|
+
|
|
85
|
+
let attachments: StoredAttachment[] | undefined;
|
|
86
|
+
if (m.attachments) {
|
|
87
|
+
try {
|
|
88
|
+
attachments = JSON.parse(m.attachments);
|
|
89
|
+
} catch { /* ignore malformed */ }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
id: m.id,
|
|
94
|
+
role: m.role,
|
|
95
|
+
content: m.content,
|
|
96
|
+
timestamp: m.created_at,
|
|
97
|
+
audioData,
|
|
98
|
+
hasAttachments: !!(attachments && attachments.length > 0),
|
|
99
|
+
attachments,
|
|
100
|
+
};
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch(() => {
|
|
106
|
+
// Worker may be restarting — retry a few times
|
|
107
|
+
if (!cancelled && retries < 5) {
|
|
108
|
+
retries++;
|
|
109
|
+
setTimeout(loadMessages, 1000);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
loadMessages();
|
|
115
|
+
return () => { cancelled = true; };
|
|
105
116
|
}, [conversationId]);
|
|
106
117
|
|
|
107
118
|
// Persist conversationId to DB when it changes
|