Stijnus commited on
Commit
b16aab1
·
1 Parent(s): 49e6c80

Update debug tab to check against fork

Browse files
app/components/settings/debug/DebugTab.tsx CHANGED
@@ -2,68 +2,493 @@ import React, { useCallback, useEffect, useState } from 'react';
2
  import { useSettings } from '~/lib/hooks/useSettings';
3
  import commit from '~/commit.json';
4
 
5
- const versionHash = commit.commit; // Get the version hash from commit.json
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  export default function DebugTab() {
8
  const { providers } = useSettings();
9
- const [activeProviders, setActiveProviders] = useState<string[]>([]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  useEffect(() => {
11
- setActiveProviders(
12
- Object.entries(providers)
13
- .filter(([_key, provider]) => provider.settings.enabled)
14
- .map(([_key, provider]) => provider.name),
15
- );
16
  }, [providers]);
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  const handleCopyToClipboard = useCallback(() => {
19
  const debugInfo = {
20
- OS: navigator.platform,
21
- Browser: navigator.userAgent,
22
- ActiveFeatures: activeProviders,
23
- BaseURLs: {
24
- Ollama: process.env.REACT_APP_OLLAMA_URL,
25
- OpenAI: process.env.REACT_APP_OPENAI_URL,
26
- LMStudio: process.env.REACT_APP_LM_STUDIO_URL,
27
- },
 
 
 
28
  Version: versionHash,
 
29
  };
30
  navigator.clipboard.writeText(JSON.stringify(debugInfo, null, 2)).then(() => {
31
  alert('Debug information copied to clipboard!');
32
  });
33
- }, [providers]);
34
 
35
  return (
36
- <div className="p-4">
37
- <h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Debug Tab</h3>
38
- <button
39
- onClick={handleCopyToClipboard}
40
- className="bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 mb-4 transition-colors duration-200"
41
- >
42
- Copy to Clipboard
43
- </button>
44
-
45
- <h4 className="text-md font-medium text-bolt-elements-textPrimary">System Information</h4>
46
- <p className="text-bolt-elements-textSecondary">OS: {navigator.platform}</p>
47
- <p className="text-bolt-elements-textSecondary">Browser: {navigator.userAgent}</p>
48
-
49
- <h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Active Features</h4>
50
- <ul>
51
- {activeProviders.map((name) => (
52
- <li key={name} className="text-bolt-elements-textSecondary">
53
- {name}
54
- </li>
55
- ))}
56
- </ul>
57
-
58
- <h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Base URLs</h4>
59
- <ul>
60
- <li className="text-bolt-elements-textSecondary">Ollama: {process.env.REACT_APP_OLLAMA_URL}</li>
61
- <li className="text-bolt-elements-textSecondary">OpenAI: {process.env.REACT_APP_OPENAI_URL}</li>
62
- <li className="text-bolt-elements-textSecondary">LM Studio: {process.env.REACT_APP_LM_STUDIO_URL}</li>
63
- </ul>
64
-
65
- <h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Version Information</h4>
66
- <p className="text-bolt-elements-textSecondary">Version Hash: {versionHash}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  </div>
68
  );
69
  }
 
2
  import { useSettings } from '~/lib/hooks/useSettings';
3
  import commit from '~/commit.json';
4
 
5
+ interface ProviderStatus {
6
+ name: string;
7
+ enabled: boolean;
8
+ isLocal: boolean;
9
+ isRunning: boolean | null;
10
+ error?: string;
11
+ lastChecked: Date;
12
+ responseTime?: number;
13
+ url: string | null;
14
+ }
15
+
16
+ interface SystemInfo {
17
+ os: string;
18
+ browser: string;
19
+ screen: string;
20
+ language: string;
21
+ timezone: string;
22
+ memory: string;
23
+ cores: number;
24
+ }
25
+
26
+ interface IProviderConfig {
27
+ name: string;
28
+ settings: {
29
+ enabled: boolean;
30
+ };
31
+ }
32
+
33
+ const LOCAL_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike'];
34
+ const versionHash = commit.commit;
35
+ const GITHUB_URLS = {
36
+ original: 'https://api.github.com/repos/Stijnus/bolt.new-any-llm/commits/main',
37
+ fork: 'https://api.github.com/repos/Stijnus/bolt.new-any-llm/commits/main',
38
+ };
39
+
40
+ function getSystemInfo(): SystemInfo {
41
+ const formatBytes = (bytes: number): string => {
42
+ if (bytes === 0) {
43
+ return '0 Bytes';
44
+ }
45
+
46
+ const k = 1024;
47
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
48
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
49
+
50
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
51
+ };
52
+
53
+ return {
54
+ os: navigator.platform,
55
+ browser: navigator.userAgent.split(' ').slice(-1)[0],
56
+ screen: `${window.screen.width}x${window.screen.height}`,
57
+ language: navigator.language,
58
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
59
+ memory: formatBytes(performance?.memory?.jsHeapSizeLimit || 0),
60
+ cores: navigator.hardwareConcurrency || 0,
61
+ };
62
+ }
63
+
64
+ const checkProviderStatus = async (url: string | null, providerName: string): Promise<ProviderStatus> => {
65
+ if (!url) {
66
+ console.log(`[Debug] No URL provided for ${providerName}`);
67
+ return {
68
+ name: providerName,
69
+ enabled: false,
70
+ isLocal: true,
71
+ isRunning: false,
72
+ error: 'No URL configured',
73
+ lastChecked: new Date(),
74
+ url: null,
75
+ };
76
+ }
77
+
78
+ console.log(`[Debug] Checking status for ${providerName} at ${url}`);
79
+
80
+ const startTime = performance.now();
81
+
82
+ try {
83
+ if (providerName.toLowerCase() === 'ollama') {
84
+ // Special check for Ollama root endpoint
85
+ try {
86
+ console.log(`[Debug] Checking Ollama root endpoint: ${url}`);
87
+
88
+ const controller = new AbortController();
89
+ const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
90
+
91
+ const response = await fetch(url, {
92
+ signal: controller.signal,
93
+ headers: {
94
+ Accept: 'text/plain,application/json',
95
+ },
96
+ });
97
+ clearTimeout(timeoutId);
98
+
99
+ const text = await response.text();
100
+ console.log(`[Debug] Ollama root response:`, text);
101
+
102
+ if (text.includes('Ollama is running')) {
103
+ console.log(`[Debug] Ollama running confirmed via root endpoint`);
104
+ return {
105
+ name: providerName,
106
+ enabled: false,
107
+ isLocal: true,
108
+ isRunning: true,
109
+ lastChecked: new Date(),
110
+ responseTime: performance.now() - startTime,
111
+ url,
112
+ };
113
+ }
114
+ } catch (error) {
115
+ console.log(`[Debug] Ollama root check failed:`, error);
116
+
117
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
118
+
119
+ if (errorMessage.includes('aborted')) {
120
+ return {
121
+ name: providerName,
122
+ enabled: false,
123
+ isLocal: true,
124
+ isRunning: false,
125
+ error: 'Connection timeout',
126
+ lastChecked: new Date(),
127
+ responseTime: performance.now() - startTime,
128
+ url,
129
+ };
130
+ }
131
+ }
132
+ }
133
+
134
+ // Try different endpoints based on provider
135
+ const checkUrls = [`${url}/api/health`, `${url}/v1/models`];
136
+ console.log(`[Debug] Checking additional endpoints:`, checkUrls);
137
+
138
+ const results = await Promise.all(
139
+ checkUrls.map(async (checkUrl) => {
140
+ try {
141
+ console.log(`[Debug] Trying endpoint: ${checkUrl}`);
142
+
143
+ const controller = new AbortController();
144
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
145
+
146
+ const response = await fetch(checkUrl, {
147
+ signal: controller.signal,
148
+ headers: {
149
+ Accept: 'application/json',
150
+ },
151
+ });
152
+ clearTimeout(timeoutId);
153
+
154
+ const ok = response.ok;
155
+ console.log(`[Debug] Endpoint ${checkUrl} response:`, ok);
156
+
157
+ if (ok) {
158
+ try {
159
+ const data = await response.json();
160
+ console.log(`[Debug] Endpoint ${checkUrl} data:`, data);
161
+ } catch {
162
+ console.log(`[Debug] Could not parse JSON from ${checkUrl}`);
163
+ }
164
+ }
165
+
166
+ return ok;
167
+ } catch (error) {
168
+ console.log(`[Debug] Endpoint ${checkUrl} failed:`, error);
169
+ return false;
170
+ }
171
+ }),
172
+ );
173
+
174
+ const isRunning = results.some((result) => result);
175
+ console.log(`[Debug] Final status for ${providerName}:`, isRunning);
176
+
177
+ return {
178
+ name: providerName,
179
+ enabled: false,
180
+ isLocal: true,
181
+ isRunning,
182
+ lastChecked: new Date(),
183
+ responseTime: performance.now() - startTime,
184
+ url,
185
+ };
186
+ } catch (error) {
187
+ console.log(`[Debug] Provider check failed for ${providerName}:`, error);
188
+ return {
189
+ name: providerName,
190
+ enabled: false,
191
+ isLocal: true,
192
+ isRunning: false,
193
+ error: error instanceof Error ? error.message : 'Unknown error',
194
+ lastChecked: new Date(),
195
+ responseTime: performance.now() - startTime,
196
+ url,
197
+ };
198
+ }
199
+ };
200
 
201
  export default function DebugTab() {
202
  const { providers } = useSettings();
203
+ const [activeProviders, setActiveProviders] = useState<ProviderStatus[]>([]);
204
+ const [updateMessage, setUpdateMessage] = useState<string>('');
205
+ const [systemInfo] = useState<SystemInfo>(getSystemInfo());
206
+ const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);
207
+
208
+ const updateProviderStatuses = async () => {
209
+ if (!providers) {
210
+ return;
211
+ }
212
+
213
+ try {
214
+ const entries = Object.entries(providers) as [string, IProviderConfig][];
215
+ const statuses = entries
216
+ .filter(([, provider]) => LOCAL_PROVIDERS.includes(provider.name))
217
+ .map(async ([, provider]) => {
218
+ const envVarName =
219
+ provider.name.toLowerCase() === 'ollama'
220
+ ? 'OLLAMA_API_BASE_URL'
221
+ : provider.name.toLowerCase() === 'lmstudio'
222
+ ? 'LMSTUDIO_API_BASE_URL'
223
+ : `REACT_APP_${provider.name.toUpperCase()}_URL`;
224
+
225
+ // Access environment variables through import.meta.env
226
+ const url = import.meta.env[envVarName] || null;
227
+ console.log(`[Debug] Using URL for ${provider.name}:`, url, `(from ${envVarName})`);
228
+
229
+ const status = await checkProviderStatus(url, provider.name);
230
+
231
+ return {
232
+ ...status,
233
+ enabled: provider.settings.enabled ?? false,
234
+ };
235
+ });
236
+
237
+ Promise.all(statuses).then(setActiveProviders);
238
+ } catch (error) {
239
+ console.error('[Debug] Failed to update provider statuses:', error);
240
+ }
241
+ };
242
+
243
  useEffect(() => {
244
+ updateProviderStatuses();
245
+
246
+ const interval = setInterval(updateProviderStatuses, 30000);
247
+
248
+ return () => clearInterval(interval);
249
  }, [providers]);
250
 
251
+ const handleCheckForUpdate = useCallback(async () => {
252
+ if (isCheckingUpdate) {
253
+ return;
254
+ }
255
+
256
+ try {
257
+ setIsCheckingUpdate(true);
258
+ setUpdateMessage('Checking for updates...');
259
+
260
+ const [originalResponse, forkResponse] = await Promise.all([
261
+ fetch(GITHUB_URLS.original),
262
+ fetch(GITHUB_URLS.fork),
263
+ ]);
264
+
265
+ if (!originalResponse.ok || !forkResponse.ok) {
266
+ throw new Error('Failed to fetch repository information');
267
+ }
268
+
269
+ const [originalData, forkData] = await Promise.all([
270
+ originalResponse.json() as Promise<{ sha: string }>,
271
+ forkResponse.json() as Promise<{ sha: string }>,
272
+ ]);
273
+
274
+ const originalCommitHash = originalData.sha;
275
+ const forkCommitHash = forkData.sha;
276
+ const isForked = versionHash === forkCommitHash && forkCommitHash !== originalCommitHash;
277
+
278
+ if (originalCommitHash !== versionHash) {
279
+ setUpdateMessage(
280
+ `Update available from original repository!\n` +
281
+ `Current: ${versionHash.slice(0, 7)}${isForked ? ' (forked)' : ''}\n` +
282
+ `Latest: ${originalCommitHash.slice(0, 7)}`,
283
+ );
284
+ } else {
285
+ setUpdateMessage('You are on the latest version from the original repository');
286
+ }
287
+ } catch (error) {
288
+ setUpdateMessage('Failed to check for updates');
289
+ console.error('[Debug] Failed to check for updates:', error);
290
+ } finally {
291
+ setIsCheckingUpdate(false);
292
+ }
293
+ }, [isCheckingUpdate]);
294
+
295
  const handleCopyToClipboard = useCallback(() => {
296
  const debugInfo = {
297
+ System: systemInfo,
298
+ Providers: activeProviders.map((provider) => ({
299
+ name: provider.name,
300
+ enabled: provider.enabled,
301
+ isLocal: provider.isLocal,
302
+ running: provider.isRunning,
303
+ error: provider.error,
304
+ lastChecked: provider.lastChecked,
305
+ responseTime: provider.responseTime,
306
+ url: provider.url,
307
+ })),
308
  Version: versionHash,
309
+ Timestamp: new Date().toISOString(),
310
  };
311
  navigator.clipboard.writeText(JSON.stringify(debugInfo, null, 2)).then(() => {
312
  alert('Debug information copied to clipboard!');
313
  });
314
+ }, [activeProviders, systemInfo]);
315
 
316
  return (
317
+ <div className="p-4 space-y-6">
318
+ <div className="flex items-center justify-between">
319
+ <h3 className="text-lg font-medium text-bolt-elements-textPrimary">Debug Information</h3>
320
+ <div className="flex gap-2">
321
+ <button
322
+ onClick={handleCopyToClipboard}
323
+ className="bg-bolt-elements-button-primary-background rounded-lg px-4 py-2 transition-colors duration-200 hover:bg-bolt-elements-button-primary-backgroundHover text-bolt-elements-button-primary-text"
324
+ >
325
+ Copy Debug Info
326
+ </button>
327
+ <button
328
+ onClick={handleCheckForUpdate}
329
+ disabled={isCheckingUpdate}
330
+ className={`bg-bolt-elements-button-primary-background rounded-lg px-4 py-2 transition-colors duration-200
331
+ ${!isCheckingUpdate ? 'hover:bg-bolt-elements-button-primary-backgroundHover' : 'opacity-75 cursor-not-allowed'}
332
+ text-bolt-elements-button-primary-text`}
333
+ >
334
+ {isCheckingUpdate ? 'Checking...' : 'Check for Updates'}
335
+ </button>
336
+ </div>
337
+ </div>
338
+
339
+ {updateMessage && (
340
+ <div
341
+ className={`bg-bolt-elements-surface rounded-lg p-3 ${
342
+ updateMessage.includes('Update available') ? 'border-l-4 border-yellow-400' : ''
343
+ }`}
344
+ >
345
+ <p className="text-bolt-elements-textSecondary whitespace-pre-line">{updateMessage}</p>
346
+ {updateMessage.includes('Update available') && (
347
+ <div className="mt-3 text-sm">
348
+ <p className="font-medium text-bolt-elements-textPrimary">To update:</p>
349
+ <ol className="list-decimal ml-4 mt-1 text-bolt-elements-textSecondary">
350
+ <li>
351
+ Pull the latest changes:{' '}
352
+ <code className="bg-bolt-elements-surface-hover px-1 rounded">git pull upstream main</code>
353
+ </li>
354
+ <li>
355
+ Install any new dependencies:{' '}
356
+ <code className="bg-bolt-elements-surface-hover px-1 rounded">npm install</code>
357
+ </li>
358
+ <li>Restart the application</li>
359
+ </ol>
360
+ </div>
361
+ )}
362
+ </div>
363
+ )}
364
+
365
+ <section className="space-y-4">
366
+ <div>
367
+ <h4 className="text-md font-medium text-bolt-elements-textPrimary mb-2">System Information</h4>
368
+ <div className="bg-bolt-elements-surface rounded-lg p-4">
369
+ <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
370
+ <div>
371
+ <p className="text-xs text-bolt-elements-textSecondary">Operating System</p>
372
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.os}</p>
373
+ </div>
374
+ <div>
375
+ <p className="text-xs text-bolt-elements-textSecondary">Browser</p>
376
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.browser}</p>
377
+ </div>
378
+ <div>
379
+ <p className="text-xs text-bolt-elements-textSecondary">Screen Resolution</p>
380
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.screen}</p>
381
+ </div>
382
+ <div>
383
+ <p className="text-xs text-bolt-elements-textSecondary">Language</p>
384
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.language}</p>
385
+ </div>
386
+ <div>
387
+ <p className="text-xs text-bolt-elements-textSecondary">Timezone</p>
388
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.timezone}</p>
389
+ </div>
390
+ <div>
391
+ <p className="text-xs text-bolt-elements-textSecondary">CPU Cores</p>
392
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{systemInfo.cores}</p>
393
+ </div>
394
+ </div>
395
+ <div className="mt-3 pt-3 border-t border-bolt-elements-surface-hover">
396
+ <p className="text-xs text-bolt-elements-textSecondary">Version</p>
397
+ <p className="text-sm font-medium text-bolt-elements-textPrimary font-mono">
398
+ {versionHash.slice(0, 7)}
399
+ <span className="ml-2 text-xs text-bolt-elements-textSecondary">
400
+ ({new Date().toLocaleDateString()})
401
+ </span>
402
+ </p>
403
+ </div>
404
+ </div>
405
+ </div>
406
+
407
+ <div>
408
+ <h4 className="text-md font-medium text-bolt-elements-textPrimary mb-2">Local LLM Status</h4>
409
+ <div className="bg-bolt-elements-surface rounded-lg">
410
+ <div className="grid grid-cols-1 divide-y">
411
+ {activeProviders.map((provider) => (
412
+ <div key={provider.name} className="p-3 flex flex-col space-y-2">
413
+ <div className="flex items-center justify-between">
414
+ <div className="flex items-center gap-3">
415
+ <div className="flex-shrink-0">
416
+ <div
417
+ className={`w-2 h-2 rounded-full ${
418
+ !provider.enabled ? 'bg-gray-300' : provider.isRunning ? 'bg-green-400' : 'bg-red-400'
419
+ }`}
420
+ />
421
+ </div>
422
+ <div>
423
+ <p className="text-sm font-medium text-bolt-elements-textPrimary">{provider.name}</p>
424
+ {provider.url && (
425
+ <p className="text-xs text-bolt-elements-textSecondary truncate max-w-[300px]">
426
+ {provider.url}
427
+ </p>
428
+ )}
429
+ </div>
430
+ </div>
431
+ <div className="flex items-center gap-2">
432
+ <span
433
+ className={`px-2 py-0.5 text-xs rounded-full ${
434
+ provider.enabled ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
435
+ }`}
436
+ >
437
+ {provider.enabled ? 'Enabled' : 'Disabled'}
438
+ </span>
439
+ {provider.enabled && (
440
+ <span
441
+ className={`px-2 py-0.5 text-xs rounded-full ${
442
+ provider.isRunning ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
443
+ }`}
444
+ >
445
+ {provider.isRunning ? 'Running' : 'Not Running'}
446
+ </span>
447
+ )}
448
+ </div>
449
+ </div>
450
+
451
+ <div className="pl-5 flex flex-col space-y-1 text-xs">
452
+ {/* Status Details */}
453
+ <div className="flex flex-wrap gap-2">
454
+ <span className="text-bolt-elements-textSecondary">
455
+ Last checked: {new Date(provider.lastChecked).toLocaleTimeString()}
456
+ </span>
457
+ {provider.responseTime && (
458
+ <span className="text-bolt-elements-textSecondary">
459
+ Response time: {Math.round(provider.responseTime)}ms
460
+ </span>
461
+ )}
462
+ </div>
463
+
464
+ {/* Error Message */}
465
+ {provider.error && (
466
+ <div className="mt-1 text-red-600 bg-red-50 rounded-md p-2">
467
+ <span className="font-medium">Error:</span> {provider.error}
468
+ </div>
469
+ )}
470
+
471
+ {/* Connection Info */}
472
+ {provider.url && (
473
+ <div className="text-bolt-elements-textSecondary">
474
+ <span className="font-medium">Endpoints checked:</span>
475
+ <ul className="list-disc list-inside pl-2 mt-1">
476
+ <li>{provider.url} (root)</li>
477
+ <li>{provider.url}/api/health</li>
478
+ <li>{provider.url}/v1/models</li>
479
+ </ul>
480
+ </div>
481
+ )}
482
+ </div>
483
+ </div>
484
+ ))}
485
+ {activeProviders.length === 0 && (
486
+ <div className="p-4 text-center text-bolt-elements-textSecondary">No local LLMs configured</div>
487
+ )}
488
+ </div>
489
+ </div>
490
+ </div>
491
+ </section>
492
  </div>
493
  );
494
  }
app/components/settings/event-logs/EventLogsTab.tsx CHANGED
@@ -32,10 +32,30 @@ export default function EventLogsTab() {
32
  }, []);
33
 
34
  useEffect(() => {
35
- // Add some initial logs for testing
36
- logStore.logSystem('System started', { version: '1.0.0' });
37
- logStore.logWarning('High memory usage detected', { memoryUsage: '85%' });
38
- logStore.logError('Failed to connect to provider', new Error('Connection timeout'), { provider: 'OpenAI' });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }, []);
40
 
41
  useEffect(() => {
 
32
  }, []);
33
 
34
  useEffect(() => {
35
+ // System info logs
36
+ logStore.logSystem('Application initialized', {
37
+ version: process.env.NEXT_PUBLIC_APP_VERSION,
38
+ environment: process.env.NODE_ENV,
39
+ });
40
+
41
+ // Debug logs for system state
42
+ logStore.logDebug('System configuration loaded', {
43
+ runtime: 'Next.js',
44
+ features: ['AI Chat', 'Event Logging'],
45
+ });
46
+
47
+ // Warning logs for potential issues
48
+ logStore.logWarning('Resource usage threshold approaching', {
49
+ memoryUsage: '75%',
50
+ cpuLoad: '60%',
51
+ });
52
+
53
+ // Error logs with detailed context
54
+ logStore.logError('API connection failed', new Error('Connection timeout'), {
55
+ endpoint: '/api/chat',
56
+ retryCount: 3,
57
+ lastAttempt: new Date().toISOString(),
58
+ });
59
  }, []);
60
 
61
  useEffect(() => {
app/types/global.d.ts CHANGED
@@ -3,3 +3,11 @@ interface Window {
3
  webkitSpeechRecognition: typeof SpeechRecognition;
4
  SpeechRecognition: typeof SpeechRecognition;
5
  }
 
 
 
 
 
 
 
 
 
3
  webkitSpeechRecognition: typeof SpeechRecognition;
4
  SpeechRecognition: typeof SpeechRecognition;
5
  }
6
+
7
+ interface Performance {
8
+ memory?: {
9
+ jsHeapSizeLimit: number;
10
+ totalJSHeapSize: number;
11
+ usedJSHeapSize: number;
12
+ };
13
+ }