Skip to content

Commit e5b37d1

Browse files
support logs
1 parent 3b602f2 commit e5b37d1

4 files changed

Lines changed: 62 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
dist
33
module
4+
logs

client/pulse-chat.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ async function sendMessage(text) {
219219
_context.emit('chat:message-sent', {
220220
conversationId: conv.id,
221221
contactName: conv.name,
222+
sender: 'user',
222223
text: text.trim()
223224
});
224225
}
@@ -252,6 +253,7 @@ async function sendMessage(text) {
252253
_context.emit('chat:message-received', {
253254
conversationId: conv.id,
254255
contactName: conv.name,
256+
sender: conv.name,
255257
text: data.response
256258
});
257259
}

client/standalone.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
11
import { init } from './pulse-chat.js';
22

3+
const SIM_ID = 'pulse-chat';
4+
const logBuffer = [];
5+
let flushTimer = null;
6+
7+
function flushLogs() {
8+
const entries = logBuffer.splice(0);
9+
flushTimer = null;
10+
if (entries.length === 0) return;
11+
fetch('/api/log', {
12+
method: 'POST',
13+
headers: { 'Content-Type': 'application/json' },
14+
body: JSON.stringify({ entries })
15+
}).catch(err => console.error('Failed to flush logs:', err));
16+
}
17+
18+
function pushLog(entry) {
19+
logBuffer.push({ ...entry, ts: new Date().toISOString() });
20+
if (!flushTimer) flushTimer = setTimeout(flushLogs, 1000);
21+
}
22+
23+
const context = {
24+
config: { id: SIM_ID, basePath: '' },
25+
emit: (eventType, payload = {}) => {
26+
pushLog({ simId: SIM_ID, dir: 'event', type: eventType, payload });
27+
}
28+
};
29+
330
if (document.readyState === 'loading') {
4-
document.addEventListener('DOMContentLoaded', () => init({}));
31+
document.addEventListener('DOMContentLoaded', () => init(context));
532
} else {
6-
init({});
33+
init(context);
734
}

server.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const OPENAI_BASE_URL = (process.env.OPENAI_BASE_URL || 'https://api.openai.com/
2626

2727
const wsClients = new Set();
2828

29+
const LOG_DIR = path.join(__dirname, 'logs');
30+
const LOG_FILE = path.join(LOG_DIR, 'events.jsonl');
31+
if (!fs.existsSync(LOG_DIR)) fs.mkdirSync(LOG_DIR, { recursive: true });
32+
2933
const mimeTypes = {
3034
'.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css',
3135
'.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg',
@@ -137,7 +141,33 @@ function generateFallbackResponse(persona) {
137141
return responses[Math.floor(Math.random() * responses.length)];
138142
}
139143

144+
async function handleLogRequest(req, res) {
145+
try {
146+
const data = await readBody(req);
147+
const entries = data.entries;
148+
if (!Array.isArray(entries) || entries.length === 0) {
149+
res.writeHead(400, { 'Content-Type': 'application/json' });
150+
res.end(JSON.stringify({ error: 'entries array is required' }));
151+
return;
152+
}
153+
const lines = entries.map(e => JSON.stringify(e)).join('\n') + '\n';
154+
fs.appendFile(LOG_FILE, lines, (err) => {
155+
if (err) console.error('Failed to write log:', err);
156+
});
157+
res.writeHead(200, { 'Content-Type': 'application/json' });
158+
res.end(JSON.stringify({ ok: true, count: entries.length }));
159+
} catch (error) {
160+
res.writeHead(400, { 'Content-Type': 'application/json' });
161+
res.end(JSON.stringify({ error: 'Invalid JSON' }));
162+
}
163+
}
164+
140165
function handlePostRequest(req, res, parsedUrl) {
166+
if (parsedUrl.pathname === '/api/log') {
167+
handleLogRequest(req, res);
168+
return;
169+
}
170+
141171
if (parsedUrl.pathname === '/api/chat') {
142172
handleChatRequest(req, res);
143173
return;

0 commit comments

Comments
 (0)