cleanup: convert AI debug console.log to logger utility
Replaced 18+ console.log statements in AI-related files with logger.debug/warn/error calls. This ensures debug output only appears in development mode, keeping production logs clean. Files updated: - frontend-modern/src/api/ai.ts (15 statements) - frontend-modern/src/components/AI/AIChat.tsx (4 statements)
This commit is contained in:
parent
2def8dee09
commit
a83a92c9c2
2 changed files with 23 additions and 25 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import { apiFetchJSON, apiFetch } from '@/utils/apiClient';
|
import { apiFetchJSON, apiFetch } from '@/utils/apiClient';
|
||||||
|
import { logger } from '@/utils/logger';
|
||||||
import type {
|
import type {
|
||||||
AISettings,
|
AISettings,
|
||||||
AISettingsUpdateRequest,
|
AISettingsUpdateRequest,
|
||||||
|
|
@ -58,10 +59,7 @@ export class AIAPI {
|
||||||
...(request.target_host ? { target_host: request.target_host } : {}),
|
...(request.target_host ? { target_host: request.target_host } : {}),
|
||||||
};
|
};
|
||||||
const body = JSON.stringify(sanitizedRequest);
|
const body = JSON.stringify(sanitizedRequest);
|
||||||
console.log('[AI] runCommand request:', request);
|
logger.debug('[AI] runCommand', { request: sanitizedRequest, bodyLength: body.length });
|
||||||
console.log('[AI] runCommand sanitized:', sanitizedRequest);
|
|
||||||
console.log('[AI] runCommand body:', body);
|
|
||||||
console.log('[AI] runCommand body length:', body.length);
|
|
||||||
return apiFetchJSON(`${this.baseUrl}/ai/run-command`, {
|
return apiFetchJSON(`${this.baseUrl}/ai/run-command`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body,
|
body,
|
||||||
|
|
@ -88,7 +86,7 @@ export class AIAPI {
|
||||||
onEvent: (event: AIStreamEvent) => void,
|
onEvent: (event: AIStreamEvent) => void,
|
||||||
signal?: AbortSignal
|
signal?: AbortSignal
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
console.log('[AI] Starting alert investigation:', request);
|
logger.debug('[AI] Starting alert investigation', request);
|
||||||
|
|
||||||
const response = await apiFetch(`${this.baseUrl}/ai/investigate-alert`, {
|
const response = await apiFetch(`${this.baseUrl}/ai/investigate-alert`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -174,7 +172,7 @@ export class AIAPI {
|
||||||
onEvent: (event: AIStreamEvent) => void,
|
onEvent: (event: AIStreamEvent) => void,
|
||||||
signal?: AbortSignal
|
signal?: AbortSignal
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
console.log('[AI SSE] Starting streaming request:', request);
|
logger.debug('[AI SSE] Starting streaming request', request);
|
||||||
|
|
||||||
const response = await apiFetch(`${this.baseUrl}/ai/execute/stream`, {
|
const response = await apiFetch(`${this.baseUrl}/ai/execute/stream`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -186,17 +184,17 @@ export class AIAPI {
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('[AI SSE] Response status:', response.status, response.headers.get('content-type'));
|
logger.debug('[AI SSE] Response status', { status: response.status, contentType: response.headers.get('content-type') });
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
console.error('[AI SSE] Request failed:', text);
|
logger.error('[AI SSE] Request failed', text);
|
||||||
throw new Error(text || `Request failed with status ${response.status}`);
|
throw new Error(text || `Request failed with status ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const reader = response.body?.getReader();
|
const reader = response.body?.getReader();
|
||||||
if (!reader) {
|
if (!reader) {
|
||||||
console.error('[AI SSE] No response body');
|
logger.error('[AI SSE] No response body');
|
||||||
throw new Error('No response body');
|
throw new Error('No response body');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,13 +207,13 @@ export class AIAPI {
|
||||||
// Timeout to detect stalled streams (5 minutes - Opus models can take a long time)
|
// Timeout to detect stalled streams (5 minutes - Opus models can take a long time)
|
||||||
const STREAM_TIMEOUT_MS = 300000;
|
const STREAM_TIMEOUT_MS = 300000;
|
||||||
|
|
||||||
console.log('[AI SSE] Starting to read stream...');
|
logger.debug('[AI SSE] Starting to read stream');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
// Check for stream timeout
|
// Check for stream timeout
|
||||||
if (Date.now() - lastEventTime > STREAM_TIMEOUT_MS) {
|
if (Date.now() - lastEventTime > STREAM_TIMEOUT_MS) {
|
||||||
console.warn('[AI SSE] Stream timeout - no data for', STREAM_TIMEOUT_MS / 1000, 'seconds');
|
logger.warn('[AI SSE] Stream timeout', { seconds: STREAM_TIMEOUT_MS / 1000 });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,7 +228,7 @@ export class AIAPI {
|
||||||
result = await Promise.race([readPromise, timeoutPromise]);
|
result = await Promise.race([readPromise, timeoutPromise]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if ((e as Error).message === 'Read timeout') {
|
if ((e as Error).message === 'Read timeout') {
|
||||||
console.warn('[AI SSE] Read timeout, ending stream');
|
logger.warn('[AI SSE] Read timeout, ending stream');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
|
@ -238,7 +236,7 @@ export class AIAPI {
|
||||||
|
|
||||||
const { done, value } = result;
|
const { done, value } = result;
|
||||||
if (done) {
|
if (done) {
|
||||||
console.log('[AI SSE] Stream ended normally');
|
logger.debug('[AI SSE] Stream ended normally');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,7 +245,7 @@ export class AIAPI {
|
||||||
|
|
||||||
// Log chunk info only if it's not just a heartbeat
|
// Log chunk info only if it's not just a heartbeat
|
||||||
if (!chunk.includes(': heartbeat')) {
|
if (!chunk.includes(': heartbeat')) {
|
||||||
console.log('[AI SSE] Received chunk:', chunk.length, 'bytes');
|
logger.debug('[AI SSE] Received chunk', { bytes: chunk.length });
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer += chunk;
|
buffer += chunk;
|
||||||
|
|
@ -262,7 +260,7 @@ export class AIAPI {
|
||||||
// Skip empty messages and heartbeat comments
|
// Skip empty messages and heartbeat comments
|
||||||
if (!message.trim() || message.trim().startsWith(':')) {
|
if (!message.trim() || message.trim().startsWith(':')) {
|
||||||
if (message.includes('heartbeat')) {
|
if (message.includes('heartbeat')) {
|
||||||
console.debug('[AI SSE] Received heartbeat');
|
logger.debug('[AI SSE] Received heartbeat');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +273,7 @@ export class AIAPI {
|
||||||
if (!jsonStr.trim()) continue;
|
if (!jsonStr.trim()) continue;
|
||||||
|
|
||||||
const data = JSON.parse(jsonStr);
|
const data = JSON.parse(jsonStr);
|
||||||
console.log('[AI SSE] Parsed event:', data.type, data);
|
logger.debug('[AI SSE] Parsed event', { type: data.type, data });
|
||||||
|
|
||||||
// Track completion events
|
// Track completion events
|
||||||
if (data.type === 'complete') {
|
if (data.type === 'complete') {
|
||||||
|
|
@ -287,7 +285,7 @@ export class AIAPI {
|
||||||
|
|
||||||
onEvent(data as AIStreamEvent);
|
onEvent(data as AIStreamEvent);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[AI SSE] Failed to parse event:', e, line);
|
logger.error('[AI SSE] Failed to parse event', { error: e, line });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -299,26 +297,26 @@ export class AIAPI {
|
||||||
const jsonStr = buffer.slice(6);
|
const jsonStr = buffer.slice(6);
|
||||||
if (jsonStr.trim()) {
|
if (jsonStr.trim()) {
|
||||||
const data = JSON.parse(jsonStr);
|
const data = JSON.parse(jsonStr);
|
||||||
console.log('[AI SSE] Parsed final buffered event:', data.type);
|
logger.debug('[AI SSE] Parsed final buffered event', { type: data.type });
|
||||||
onEvent(data as AIStreamEvent);
|
onEvent(data as AIStreamEvent);
|
||||||
if (data.type === 'complete') receivedComplete = true;
|
if (data.type === 'complete') receivedComplete = true;
|
||||||
if (data.type === 'done') receivedDone = true;
|
if (data.type === 'done') receivedDone = true;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('[AI SSE] Could not parse remaining buffer:', buffer.substring(0, 100));
|
logger.warn('[AI SSE] Could not parse remaining buffer', { preview: buffer.substring(0, 100) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we ended without receiving a done event, send a synthetic one
|
// If we ended without receiving a done event, send a synthetic one
|
||||||
// This ensures the UI properly clears the streaming state
|
// This ensures the UI properly clears the streaming state
|
||||||
if (!receivedDone) {
|
if (!receivedDone) {
|
||||||
console.warn('[AI SSE] Stream ended without done event, sending synthetic done');
|
logger.warn('[AI SSE] Stream ended without done event, sending synthetic done');
|
||||||
onEvent({ type: 'done', data: undefined });
|
onEvent({ type: 'done', data: undefined });
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
reader.releaseLock();
|
reader.releaseLock();
|
||||||
console.log('[AI SSE] Reader released, receivedComplete:', receivedComplete, 'receivedDone:', receivedDone);
|
logger.debug('[AI SSE] Reader released', { receivedComplete, receivedDone });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||||
const safetyCheckInterval = setInterval(() => {
|
const safetyCheckInterval = setInterval(() => {
|
||||||
const timeSinceLastEvent = Date.now() - lastEventTime;
|
const timeSinceLastEvent = Date.now() - lastEventTime;
|
||||||
if (timeSinceLastEvent > SAFETY_TIMEOUT_MS) {
|
if (timeSinceLastEvent > SAFETY_TIMEOUT_MS) {
|
||||||
console.warn('[AIChat] Safety timeout - forcing stream completion after', SAFETY_TIMEOUT_MS / 1000, 'seconds of inactivity');
|
logger.warn('[AIChat] Safety timeout - forcing stream completion', { seconds: SAFETY_TIMEOUT_MS / 1000 });
|
||||||
clearInterval(safetyCheckInterval);
|
clearInterval(safetyCheckInterval);
|
||||||
setMessages((prev) =>
|
setMessages((prev) =>
|
||||||
prev.map((msg) =>
|
prev.map((msg) =>
|
||||||
|
|
@ -365,7 +365,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||||
},
|
},
|
||||||
(event: AIStreamEvent) => {
|
(event: AIStreamEvent) => {
|
||||||
lastEventTime = Date.now(); // Update last event time
|
lastEventTime = Date.now(); // Update last event time
|
||||||
console.log('[AIChat] Received event:', event.type, event);
|
logger.debug('[AIChat] Received event', { type: event.type, event });
|
||||||
// Update the streaming message based on event type
|
// Update the streaming message based on event type
|
||||||
setMessages((prev) =>
|
setMessages((prev) =>
|
||||||
prev.map((msg) => {
|
prev.map((msg) => {
|
||||||
|
|
@ -449,7 +449,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||||
case 'processing': {
|
case 'processing': {
|
||||||
// Show processing status for multi-iteration calls
|
// Show processing status for multi-iteration calls
|
||||||
const status = event.data as string;
|
const status = event.data as string;
|
||||||
console.log('[AIChat] Processing:', status);
|
logger.debug('[AIChat] Processing', status);
|
||||||
// Add as a pending tool for visual feedback
|
// Add as a pending tool for visual feedback
|
||||||
return {
|
return {
|
||||||
...msg,
|
...msg,
|
||||||
|
|
@ -481,7 +481,7 @@ export const AIChat: Component<AIChatProps> = (props) => {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Don't show error for user-initiated abort
|
// Don't show error for user-initiated abort
|
||||||
if (error instanceof Error && error.name === 'AbortError') {
|
if (error instanceof Error && error.name === 'AbortError') {
|
||||||
console.log('[AIChat] Request aborted by user');
|
logger.debug('[AIChat] Request aborted by user');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.error('[AIChat] Execute failed:', error);
|
logger.error('[AIChat] Execute failed:', error);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue