refactor: all logging
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:yaml/yaml.dart' as yaml;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import '../../../core/utils/tool_calls_parser.dart';
|
||||
@@ -15,6 +14,12 @@ import '../services/reviewer_mode_service.dart';
|
||||
import '../../../shared/services/tasks/task_queue.dart';
|
||||
import '../../tools/providers/tools_providers.dart';
|
||||
import 'dart:async';
|
||||
import '../../../core/utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'chat/providers');
|
||||
}
|
||||
|
||||
const bool kSocketVerboseLogging = false;
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart' as foundation;
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import '../../../core/services/api_service.dart';
|
||||
import '../../../core/providers/app_providers.dart';
|
||||
import '../../../core/utils/debug_logger.dart';
|
||||
|
||||
class FileAttachmentService {
|
||||
final ApiService _apiService;
|
||||
@@ -139,7 +139,11 @@ class FileAttachmentService {
|
||||
final compressedBase64 = base64Encode(compressedBytes);
|
||||
return 'data:image/png;base64,$compressedBase64';
|
||||
} catch (e) {
|
||||
foundation.debugPrint('DEBUG: Image compression failed: $e');
|
||||
DebugLogger.error(
|
||||
'compress-failed',
|
||||
scope: 'attachments/image',
|
||||
error: e,
|
||||
);
|
||||
return imageDataUrl; // Return original if compression fails
|
||||
}
|
||||
}
|
||||
@@ -152,8 +156,10 @@ class FileAttachmentService {
|
||||
int? maxHeight,
|
||||
}) async {
|
||||
try {
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Converting image to data URL: ${imageFile.path}',
|
||||
DebugLogger.log(
|
||||
'convert-start',
|
||||
scope: 'attachments/image',
|
||||
data: {'path': imageFile.path},
|
||||
);
|
||||
|
||||
// Read the file as bytes
|
||||
@@ -180,25 +186,33 @@ class FileAttachmentService {
|
||||
dataUrl = await compressImage(dataUrl, maxWidth, maxHeight);
|
||||
}
|
||||
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Image converted to data URL with MIME type: $mimeType',
|
||||
DebugLogger.log(
|
||||
'convert-done',
|
||||
scope: 'attachments/image',
|
||||
data: {'mime': mimeType},
|
||||
);
|
||||
return dataUrl;
|
||||
} catch (e) {
|
||||
foundation.debugPrint('DEBUG: Failed to convert image to data URL: $e');
|
||||
DebugLogger.error('convert-failed', scope: 'attachments/image', error: e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Upload file with progress tracking
|
||||
Stream<FileUploadState> uploadFile(File file) async* {
|
||||
foundation.debugPrint('DEBUG: Starting file upload for: ${file.path}');
|
||||
DebugLogger.log(
|
||||
'upload-start',
|
||||
scope: 'attachments/file',
|
||||
data: {'path': file.path},
|
||||
);
|
||||
try {
|
||||
final fileName = path.basename(file.path);
|
||||
final fileSize = await file.length();
|
||||
|
||||
foundation.debugPrint(
|
||||
'DEBUG: File details - Name: $fileName, Size: $fileSize bytes',
|
||||
DebugLogger.log(
|
||||
'file-details',
|
||||
scope: 'attachments/file',
|
||||
data: {'name': fileName, 'bytes': fileSize},
|
||||
);
|
||||
|
||||
yield FileUploadState(
|
||||
@@ -220,10 +234,12 @@ class FileAttachmentService {
|
||||
].contains(ext.substring(1));
|
||||
|
||||
// Upload ALL files (including images) to server for consistency with web client
|
||||
foundation.debugPrint('DEBUG: Uploading file to server...');
|
||||
DebugLogger.log('upload-progress', scope: 'attachments/file');
|
||||
final fileId = await _apiService.uploadFile(file.path, fileName);
|
||||
foundation.debugPrint(
|
||||
'DEBUG: File uploaded successfully with ID: $fileId',
|
||||
DebugLogger.log(
|
||||
'upload-complete',
|
||||
scope: 'attachments/file',
|
||||
data: {'fileId': fileId},
|
||||
);
|
||||
|
||||
yield FileUploadState(
|
||||
@@ -236,7 +252,7 @@ class FileAttachmentService {
|
||||
isImage: isImage,
|
||||
);
|
||||
} catch (e) {
|
||||
foundation.debugPrint('DEBUG: File upload failed: $e');
|
||||
DebugLogger.error('upload-failed', scope: 'attachments/file', error: e);
|
||||
final fileName = path.basename(file.path);
|
||||
final fileSize = await file.length();
|
||||
|
||||
@@ -421,7 +437,11 @@ class MockFileAttachmentService {
|
||||
|
||||
// Mock upload file with progress tracking
|
||||
Stream<FileUploadState> uploadFile(File file) async* {
|
||||
foundation.debugPrint('DEBUG: Mock file upload for: ${file.path}');
|
||||
DebugLogger.log(
|
||||
'mock-upload',
|
||||
scope: 'attachments/mock',
|
||||
data: {'path': file.path},
|
||||
);
|
||||
|
||||
final fileName = path.basename(file.path);
|
||||
final fileSize = await file.length();
|
||||
@@ -457,7 +477,7 @@ class MockFileAttachmentService {
|
||||
fileId: 'mock_file_${DateTime.now().millisecondsSinceEpoch}',
|
||||
);
|
||||
|
||||
foundation.debugPrint('DEBUG: Mock file upload completed');
|
||||
DebugLogger.log('mock-complete', scope: 'attachments/mock');
|
||||
}
|
||||
|
||||
Future<List<String>> uploadFiles(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide debugPrint;
|
||||
import 'package:conduit/l10n/app_localizations.dart';
|
||||
import '../../../core/widgets/error_boundary.dart';
|
||||
import '../../../shared/widgets/optimized_list.dart';
|
||||
@@ -48,6 +48,11 @@ import '../../../shared/widgets/model_avatar.dart';
|
||||
import '../../../core/services/platform_service.dart' as ps;
|
||||
import 'package:flutter/gestures.dart' show DragStartBehavior;
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'chat/page');
|
||||
}
|
||||
|
||||
class ChatPage extends ConsumerStatefulWidget {
|
||||
const ChatPage({super.key});
|
||||
|
||||
@@ -105,11 +110,15 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
// Check if a model is already selected
|
||||
final selectedModel = ref.read(selectedModelProvider);
|
||||
if (selectedModel != null) {
|
||||
DebugLogger.log('Model already selected: ${selectedModel.name}');
|
||||
DebugLogger.log(
|
||||
'selected',
|
||||
scope: 'chat/model',
|
||||
data: {'name': selectedModel.name},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLogger.log('No model selected, attempting auto-selection');
|
||||
DebugLogger.log('auto-select-start', scope: 'chat/model');
|
||||
|
||||
try {
|
||||
// First ensure models are loaded
|
||||
@@ -119,14 +128,18 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
if (modelsAsync.hasValue) {
|
||||
models = modelsAsync.value!;
|
||||
} else {
|
||||
DebugLogger.log('Models not loaded yet, fetching...');
|
||||
DebugLogger.log('models-fetch', scope: 'chat/model');
|
||||
models = await ref.read(modelsProvider.future);
|
||||
}
|
||||
|
||||
DebugLogger.log('Found ${models.length} models available');
|
||||
DebugLogger.log(
|
||||
'models-count',
|
||||
scope: 'chat/model',
|
||||
data: {'count': models.length},
|
||||
);
|
||||
|
||||
if (models.isEmpty) {
|
||||
DebugLogger.log('No models available for selection');
|
||||
DebugLogger.warning('models-empty', scope: 'chat/model');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,18 +147,24 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
try {
|
||||
final Model? model = await ref.read(defaultModelProvider.future);
|
||||
if (model != null) {
|
||||
DebugLogger.log('Model auto-selected via provider: ${model.name}');
|
||||
DebugLogger.log(
|
||||
'auto-select',
|
||||
scope: 'chat/model',
|
||||
data: {'name': model.name},
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
DebugLogger.log(
|
||||
'Default provider failed, selecting first model directly',
|
||||
);
|
||||
DebugLogger.warning('provider-fallback', scope: 'chat/model');
|
||||
// Fallback: select the first available model
|
||||
ref.read(selectedModelProvider.notifier).set(models.first);
|
||||
DebugLogger.log('Fallback model selected: ${models.first.name}');
|
||||
DebugLogger.log(
|
||||
'fallback',
|
||||
scope: 'chat/model',
|
||||
data: {'name': models.first.name},
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
DebugLogger.error('Failed to auto-select model', e);
|
||||
DebugLogger.error('auto-select-failed', scope: 'chat/model', error: e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,20 +173,28 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
// Check if onboarding has been seen
|
||||
final storage = ref.read(optimizedStorageServiceProvider);
|
||||
final seen = await storage.getOnboardingSeen();
|
||||
DebugLogger.log('Chat page - Onboarding seen status: $seen');
|
||||
DebugLogger.log(
|
||||
'onboarding-status',
|
||||
scope: 'chat/onboarding',
|
||||
data: {'seen': seen},
|
||||
);
|
||||
|
||||
if (!seen && mounted) {
|
||||
// Small delay to ensure navigation has settled
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
if (!mounted) return;
|
||||
|
||||
DebugLogger.log('Showing onboarding from chat page');
|
||||
DebugLogger.log('onboarding-show', scope: 'chat/onboarding');
|
||||
_showOnboarding();
|
||||
await storage.setOnboardingSeen(true);
|
||||
DebugLogger.log('Onboarding marked as seen');
|
||||
DebugLogger.log('onboarding-marked', scope: 'chat/onboarding');
|
||||
}
|
||||
} catch (e) {
|
||||
DebugLogger.error('Error checking onboarding status', e);
|
||||
DebugLogger.error(
|
||||
'onboarding-status-failed',
|
||||
scope: 'chat/onboarding',
|
||||
error: e,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +226,9 @@ class _ChatPageState extends ConsumerState<ChatPage> {
|
||||
final activeConversation = ref.read(activeConversationProvider);
|
||||
if (activeConversation != null) {
|
||||
DebugLogger.log(
|
||||
'Conversation already active: ${activeConversation.title}',
|
||||
'active',
|
||||
scope: 'chat/demo',
|
||||
data: {'title': activeConversation.title},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide debugPrint;
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart' show listEquals;
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -20,6 +20,12 @@ import 'package:conduit/shared/widgets/chat_action_button.dart';
|
||||
import '../../../shared/widgets/model_avatar.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import '../providers/chat_providers.dart' show sendMessage;
|
||||
import '../../../core/utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'chat/assistant');
|
||||
}
|
||||
|
||||
class AssistantMessageWidget extends ConsumerStatefulWidget {
|
||||
final dynamic message;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide debugPrint;
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
@@ -12,6 +12,12 @@ import '../../../shared/theme/theme_extensions.dart';
|
||||
import 'package:conduit/l10n/app_localizations.dart';
|
||||
import '../../../core/providers/app_providers.dart';
|
||||
import '../../auth/providers/unified_auth_providers.dart';
|
||||
import '../../../core/utils/debug_logger.dart';
|
||||
|
||||
void debugPrint(String? message, {int? wrapWidth}) {
|
||||
if (message == null) return;
|
||||
DebugLogger.fromLegacy(message, scope: 'chat/image-attachment');
|
||||
}
|
||||
|
||||
// Simple global cache to prevent reloading
|
||||
final _globalImageCache = <String, String>{};
|
||||
|
||||
Reference in New Issue
Block a user