Skip to content

Commit 346d6d2

Browse files
Basic functionality
Signed-off-by: Matías Insaurralde <[email protected]>
1 parent f0eb252 commit 346d6d2

File tree

4 files changed

+224
-28
lines changed

4 files changed

+224
-28
lines changed

src/main/main.ts

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,45 +48,92 @@ const connectIPC = () => {
4848
ipcClient.setEncoding('utf8');
4949

5050
ipcClient.connect(CROWDLLAMA_SOCKET_PATH, () => {
51-
console.log('Connected to Go backend socket (persistent)');
51+
console.log('🟢 [MAIN] Connected to Go backend socket (persistent)');
5252
});
5353

54-
ipcClient.on('data', (data: string) => {
54+
ipcClient.on('data', (data: string) => {
55+
console.log('🔵 [MAIN] Raw data received from backend:', data);
56+
console.log('🔵 [MAIN] Data length:', data.length);
57+
console.log('🔵 [MAIN] Data type:', typeof data);
58+
console.log('🔵 [MAIN] Buffer before adding:', ipcClientBuffer);
5559
ipcClientBuffer += data;
60+
console.log('🔵 [MAIN] Buffer after adding:', ipcClientBuffer);
61+
console.log('🔵 [MAIN] Buffer length:', ipcClientBuffer.length);
62+
63+
// Try to parse the entire buffer as a single JSON message first
64+
if (ipcClientBuffer.trim()) {
65+
try {
66+
const parsed = JSON.parse(ipcClientBuffer.trim());
67+
console.log('🔵 [MAIN] Parsed single JSON message from backend:', parsed);
68+
69+
// Route incoming messages to renderer process
70+
if (mainWindow && !mainWindow.isDestroyed()) {
71+
console.log('🔵 [MAIN] Forwarding to renderer:', parsed);
72+
mainWindow.webContents.send('backend-message', parsed);
73+
} else {
74+
console.log('🔴 [MAIN] Main window not available for forwarding');
75+
}
76+
77+
// Clear the buffer after successful parsing
78+
ipcClientBuffer = '';
79+
console.log('🔵 [MAIN] Cleared buffer after parsing');
80+
return;
81+
} catch (err) {
82+
console.log('🔵 [MAIN] Not a single JSON message, trying newline-delimited parsing');
83+
}
84+
}
85+
86+
// Fallback to newline-delimited parsing
5687
let index;
5788
while ((index = ipcClientBuffer.indexOf('\n')) !== -1) {
89+
console.log('🔵 [MAIN] Found newline at index:', index);
5890
const message = ipcClientBuffer.slice(0, index);
5991
ipcClientBuffer = ipcClientBuffer.slice(index + 1);
92+
console.log('🔵 [MAIN] Processing message chunk:', message);
93+
console.log('🔵 [MAIN] Message chunk length:', message.length);
94+
console.log('🔵 [MAIN] Message chunk trimmed:', message.trim());
95+
console.log('🔵 [MAIN] Remaining buffer:', ipcClientBuffer);
96+
6097
if (message.trim()) {
6198
try {
6299
const parsed = JSON.parse(message);
63-
console.log('Received from backend:', parsed);
64-
// TODO: handle parsed message (route to renderer, etc)
100+
console.log('🔵 [MAIN] Parsed message from backend:', parsed);
101+
102+
// Route incoming messages to renderer process
103+
if (mainWindow && !mainWindow.isDestroyed()) {
104+
console.log('🔵 [MAIN] Forwarding to renderer:', parsed);
105+
mainWindow.webContents.send('backend-message', parsed);
106+
} else {
107+
console.log('🔴 [MAIN] Main window not available for forwarding');
108+
}
65109
} catch (err) {
66-
console.log('Failed to parse backend message:', message);
110+
console.log('🔴 [MAIN] Failed to parse backend message:', message, err);
67111
}
112+
} else {
113+
console.log('🔵 [MAIN] Empty message chunk, skipping');
68114
}
69115
}
70116
});
71117

72118
ipcClient.on('error', (err: any) => {
73-
console.log('IPC socket error:', err.message);
119+
console.log('🔴 [MAIN] IPC socket error:', err.message);
74120
// Optionally, try to reconnect or clean up
75121
ipcClient = null;
76122
});
77123

78124
ipcClient.on('close', () => {
79-
console.log('IPC socket closed');
125+
console.log('🔴 [MAIN] IPC socket closed');
80126
ipcClient = null;
81127
});
82128
};
83129

84130
// Send a message over the persistent IPC connection
85131
const sendIPCMessage = (msg: object) => {
86132
if (ipcClient && !ipcClient.destroyed) {
133+
console.log('🟡 [MAIN] Sending to backend:', msg);
87134
ipcClient.write(JSON.stringify(msg) + '\n');
88135
} else {
89-
console.log('IPC client not connected, cannot send message');
136+
console.log('🔴 [MAIN] IPC client not connected, cannot send message');
90137
}
91138
};
92139

@@ -258,6 +305,37 @@ ipcMain.handle('ping-backend', async () => {
258305
}
259306
});
260307

308+
// New IPC handlers for initialize and prompt messages
309+
ipcMain.handle('initialize-backend', async (event, mode: 'worker' | 'consumer') => {
310+
console.log('🟡 [MAIN] Received initialize-backend request:', { mode });
311+
try {
312+
sendIPCMessage({ type: 'initialize', mode });
313+
console.log('🟡 [MAIN] Initialize message sent successfully');
314+
return { success: true, message: 'Initialize message sent successfully' };
315+
} catch (error) {
316+
console.error('🔴 [MAIN] Error sending initialize message:', error);
317+
return {
318+
success: false,
319+
message: error instanceof Error ? error.message : 'Unknown error',
320+
};
321+
}
322+
});
323+
324+
ipcMain.handle('send-prompt', async (event, prompt: string, model: string) => {
325+
console.log('🟡 [MAIN] Received send-prompt request:', { prompt, model });
326+
try {
327+
sendIPCMessage({ type: 'prompt', prompt, model });
328+
console.log('🟡 [MAIN] Prompt message sent successfully');
329+
return { success: true, message: 'Prompt sent successfully' };
330+
} catch (error) {
331+
console.error('🔴 [MAIN] Error sending prompt:', error);
332+
return {
333+
success: false,
334+
message: error instanceof Error ? error.message : 'Unknown error',
335+
};
336+
}
337+
});
338+
261339
if (process.env.NODE_ENV === 'production') {
262340
const sourceMapSupport = require('source-map-support');
263341
sourceMapSupport.install();

src/main/preload.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export type Channels =
77
| 'start-backend'
88
| 'stop-backend'
99
| 'get-backend-status'
10-
| 'ping-backend';
10+
| 'ping-backend'
11+
| 'initialize-backend'
12+
| 'send-prompt'
13+
| 'backend-message';
1114

1215
const electronHandler = {
1316
ipcRenderer: {
@@ -40,6 +43,20 @@ const electronHandler = {
4043
async pingBackend() {
4144
return ipcRenderer.invoke('ping-backend');
4245
},
46+
async initializeBackend(mode: 'worker' | 'consumer') {
47+
return ipcRenderer.invoke('initialize-backend', mode);
48+
},
49+
async sendPrompt(prompt: string, model: string) {
50+
return ipcRenderer.invoke('send-prompt', prompt, model);
51+
},
52+
onBackendMessage(callback: (message: any) => void) {
53+
const subscription = (_event: IpcRendererEvent, message: any) => callback(message);
54+
ipcRenderer.on('backend-message', subscription);
55+
56+
return () => {
57+
ipcRenderer.removeListener('backend-message', subscription);
58+
};
59+
},
4360
},
4461
};
4562

src/renderer/App.tsx

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useState } from 'react';
21
import { MemoryRouter as Router, Routes, Route, useNavigate } from 'react-router-dom';
32
import BaseLayout from './components/Layout/BaseLayout';
43
import ChatView from './components/Chat/ChatView';
@@ -16,29 +15,33 @@ interface Message {
1615
}
1716

1817
function ChatPage() {
19-
const [messages, setMessages] = useState<Message[]>([]);
20-
const { isConnected, peerCount } = useAppContext();
18+
const { isConnected, peerCount, sendPrompt, networkStatusText, messages, addMessage } = useAppContext();
2119

22-
const handleSendMessage = (message: string) => {
20+
const handleSendMessage = async (message: string) => {
2321
const userMessage: Message = {
2422
id: Date.now().toString(),
2523
type: 'user',
2624
content: message,
2725
timestamp: new Date().toISOString(),
2826
};
2927

30-
setMessages((prev) => [...prev, userMessage]);
28+
addMessage(userMessage);
3129

32-
// Simulate AI response (in real app, this would come from backend)
33-
setTimeout(() => {
34-
const aiMessage: Message = {
30+
// Send prompt to backend
31+
try {
32+
await sendPrompt(message, 'tinyllama'); // Default model
33+
// The response will be handled by the backend message listener in AppContext
34+
} catch (error) {
35+
console.error('Failed to send prompt:', error);
36+
// Show error message
37+
const errorMessage: Message = {
3538
id: (Date.now() + 1).toString(),
3639
type: 'ai',
37-
content: `I received your message: "${message}". This is a simulated response. In the real application, this would come from your AI backend.`,
40+
content: 'Sorry, there was an error sending your message. Please try again.',
3841
timestamp: new Date().toISOString(),
3942
};
40-
setMessages((prev) => [...prev, aiMessage]);
41-
}, 1000);
43+
addMessage(errorMessage);
44+
}
4245
};
4346

4447
const handleHistoryClick = () => {
@@ -57,6 +60,7 @@ function ChatPage() {
5760
<BaseLayout
5861
isConnected={isConnected}
5962
peerCount={peerCount}
63+
networkStatusText={networkStatusText}
6064
onHistoryClick={handleHistoryClick}
6165
onSettingsClick={handleSettingsClick}
6266
onUserClick={handleUserClick}
@@ -68,21 +72,35 @@ function ChatPage() {
6872

6973
function WelcomePageWrapper() {
7074
const navigate = useNavigate();
71-
72-
const handleShareCompute = () => {
73-
console.log('Navigating to share-compute');
74-
navigate('/share-compute');
75+
const { initializeBackend, networkStatusText } = useAppContext();
76+
77+
const handleShareCompute = async () => {
78+
console.log('Initializing as worker');
79+
try {
80+
await initializeBackend('worker');
81+
console.log('Navigating to share-compute');
82+
navigate('/share-compute');
83+
} catch (error) {
84+
console.error('Failed to initialize as worker:', error);
85+
}
7586
};
7687

77-
const handleUseNetwork = () => {
78-
console.log('Navigating to chat');
79-
navigate('/chat');
88+
const handleUseNetwork = async () => {
89+
console.log('Initializing as consumer');
90+
try {
91+
await initializeBackend('consumer');
92+
console.log('Navigating to chat');
93+
navigate('/chat');
94+
} catch (error) {
95+
console.error('Failed to initialize as consumer:', error);
96+
}
8097
};
8198

8299
return (
83100
<BaseLayout
84101
isConnected
85102
peerCount={100}
103+
networkStatusText={networkStatusText}
86104
onHistoryClick={() => console.log('History clicked')}
87105
onSettingsClick={() => console.log('Settings clicked')}
88106
onUserClick={() => console.log('User clicked')}
@@ -97,6 +115,7 @@ function WelcomePageWrapper() {
97115

98116
function ShareComputePageWrapper() {
99117
const navigate = useNavigate();
118+
const { networkStatusText } = useAppContext();
100119

101120
const handleStartSharing = () => {
102121
console.log('Starting to share, navigating to chat');
@@ -112,6 +131,7 @@ function ShareComputePageWrapper() {
112131
<BaseLayout
113132
isConnected
114133
peerCount={100}
134+
networkStatusText={networkStatusText}
115135
onHistoryClick={() => console.log('History clicked')}
116136
onSettingsClick={() => console.log('Settings clicked')}
117137
onUserClick={() => console.log('User clicked')}

0 commit comments

Comments
 (0)