fix: socket issues
This commit is contained in:
@@ -14,6 +14,8 @@ import '../../../core/services/persistent_streaming_service.dart';
|
|||||||
import '../../../core/utils/debug_logger.dart';
|
import '../../../core/utils/debug_logger.dart';
|
||||||
import '../services/reviewer_mode_service.dart';
|
import '../services/reviewer_mode_service.dart';
|
||||||
|
|
||||||
|
const bool kSocketVerboseLogging = false;
|
||||||
|
|
||||||
// Chat messages for current conversation
|
// Chat messages for current conversation
|
||||||
final chatMessagesProvider =
|
final chatMessagesProvider =
|
||||||
StateNotifierProvider<ChatMessagesNotifier, List<ChatMessage>>((ref) {
|
StateNotifierProvider<ChatMessagesNotifier, List<ChatMessage>>((ref) {
|
||||||
@@ -1092,8 +1094,15 @@ Future<void> _sendMessageInternal(
|
|||||||
final fn = call['function'];
|
final fn = call['function'];
|
||||||
final name = (fn is Map && fn['name'] is String) ? fn['name'] as String : null;
|
final name = (fn is Map && fn['name'] is String) ? fn['name'] as String : null;
|
||||||
if (name is String && name.isNotEmpty) {
|
if (name is String && name.isNotEmpty) {
|
||||||
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
final msgs = ref.read(chatMessagesProvider);
|
||||||
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
final exists = (msgs.isNotEmpty) && RegExp(
|
||||||
|
r'<details\s+type=\"tool_calls\"[^>]*\bname=\"' + RegExp.escape(name) + r'\"',
|
||||||
|
multiLine: true,
|
||||||
|
).hasMatch(msgs.last.content);
|
||||||
|
if (!exists) {
|
||||||
|
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
||||||
|
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1114,8 +1123,15 @@ Future<void> _sendMessageInternal(
|
|||||||
final fn = call['function'];
|
final fn = call['function'];
|
||||||
final name = (fn is Map && fn['name'] is String) ? fn['name'] as String : null;
|
final name = (fn is Map && fn['name'] is String) ? fn['name'] as String : null;
|
||||||
if (name is String && name.isNotEmpty) {
|
if (name is String && name.isNotEmpty) {
|
||||||
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
final msgs = ref.read(chatMessagesProvider);
|
||||||
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
final exists = (msgs.isNotEmpty) && RegExp(
|
||||||
|
r'<details\s+type=\"tool_calls\"[^>]*\bname=\"' + RegExp.escape(name) + r'\"',
|
||||||
|
multiLine: true,
|
||||||
|
).hasMatch(msgs.last.content);
|
||||||
|
if (!exists) {
|
||||||
|
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
||||||
|
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1158,6 +1174,25 @@ Future<void> _sendMessageInternal(
|
|||||||
// Stop listening to further socket events for this session.
|
// Stop listening to further socket events for this session.
|
||||||
try { socketService.offChatEvents(); } catch (_) {}
|
try { socketService.offChatEvents(); } catch (_) {}
|
||||||
|
|
||||||
|
// Notify server that chat is completed (mirrors web client)
|
||||||
|
try {
|
||||||
|
final apiSvc = ref.read(apiServiceProvider);
|
||||||
|
final chatId = activeConversation?.id ?? '';
|
||||||
|
if (apiSvc != null && chatId.isNotEmpty) {
|
||||||
|
unawaited(apiSvc
|
||||||
|
.sendChatCompleted(
|
||||||
|
chatId: chatId,
|
||||||
|
messageId: assistantMessageId,
|
||||||
|
messages: const [],
|
||||||
|
model: selectedModel.id,
|
||||||
|
modelItem: modelItem,
|
||||||
|
sessionId: sessionId,
|
||||||
|
)
|
||||||
|
.timeout(const Duration(seconds: 3))
|
||||||
|
.catchError((_) {}));
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
// If no content was rendered yet, fetch final assistant message from server
|
// If no content was rendered yet, fetch final assistant message from server
|
||||||
final msgs = ref.read(chatMessagesProvider);
|
final msgs = ref.read(chatMessagesProvider);
|
||||||
if (msgs.isNotEmpty && msgs.last.role == 'assistant') {
|
if (msgs.isNotEmpty && msgs.last.role == 'assistant') {
|
||||||
@@ -1253,6 +1288,16 @@ Future<void> _sendMessageInternal(
|
|||||||
if (s == '[DONE]' || s == 'DONE') {
|
if (s == '[DONE]' || s == 'DONE') {
|
||||||
socketService.offEvent(channel);
|
socketService.offEvent(channel);
|
||||||
// Channel completed
|
// Channel completed
|
||||||
|
try {
|
||||||
|
unawaited(api.sendChatCompleted(
|
||||||
|
chatId: activeConversation?.id ?? '',
|
||||||
|
messageId: assistantMessageId,
|
||||||
|
messages: const [],
|
||||||
|
model: selectedModel.id,
|
||||||
|
modelItem: modelItem,
|
||||||
|
sessionId: sessionId,
|
||||||
|
));
|
||||||
|
} catch (_) {}
|
||||||
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1260,6 +1305,16 @@ Future<void> _sendMessageInternal(
|
|||||||
final dataStr = s.substring(5).trim();
|
final dataStr = s.substring(5).trim();
|
||||||
if (dataStr == '[DONE]') {
|
if (dataStr == '[DONE]') {
|
||||||
socketService.offEvent(channel);
|
socketService.offEvent(channel);
|
||||||
|
try {
|
||||||
|
unawaited(api.sendChatCompleted(
|
||||||
|
chatId: activeConversation?.id ?? '',
|
||||||
|
messageId: assistantMessageId,
|
||||||
|
messages: const [],
|
||||||
|
model: selectedModel.id,
|
||||||
|
modelItem: modelItem,
|
||||||
|
sessionId: sessionId,
|
||||||
|
));
|
||||||
|
} catch (_) {}
|
||||||
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1279,7 +1334,9 @@ Future<void> _sendMessageInternal(
|
|||||||
}
|
}
|
||||||
// Surface tool_calls status
|
// Surface tool_calls status
|
||||||
if (delta.containsKey('tool_calls')) {
|
if (delta.containsKey('tool_calls')) {
|
||||||
DebugLogger.stream('Socket [' + channel + '] delta.tool_calls detected');
|
if (kSocketVerboseLogging) {
|
||||||
|
DebugLogger.stream('Socket [' + channel + '] delta.tool_calls detected');
|
||||||
|
}
|
||||||
final tc = delta['tool_calls'];
|
final tc = delta['tool_calls'];
|
||||||
if (tc is List) {
|
if (tc is List) {
|
||||||
for (final call in tc) {
|
for (final call in tc) {
|
||||||
@@ -1289,8 +1346,15 @@ Future<void> _sendMessageInternal(
|
|||||||
? fn['name'] as String
|
? fn['name'] as String
|
||||||
: null;
|
: null;
|
||||||
if (name is String && name.isNotEmpty) {
|
if (name is String && name.isNotEmpty) {
|
||||||
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
final msgs = ref.read(chatMessagesProvider);
|
||||||
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
final exists = (msgs.isNotEmpty) && RegExp(
|
||||||
|
r'<details\\s+type=\"tool_calls\"[^>]*\\bname=\"' + RegExp.escape(name) + r'\"',
|
||||||
|
multiLine: true,
|
||||||
|
).hasMatch(msgs.last.content);
|
||||||
|
if (!exists) {
|
||||||
|
final status = '\n<details type="tool_calls" done="false" name="$name"><summary>Executing...</summary>\n</details>\n';
|
||||||
|
ref.read(chatMessagesProvider.notifier).appendToLastMessage(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1384,16 @@ Future<void> _sendMessageInternal(
|
|||||||
final done = line['done'] == true;
|
final done = line['done'] == true;
|
||||||
if (done) {
|
if (done) {
|
||||||
socketService.offEvent(channel);
|
socketService.offEvent(channel);
|
||||||
|
try {
|
||||||
|
unawaited(api.sendChatCompleted(
|
||||||
|
chatId: activeConversation?.id ?? '',
|
||||||
|
messageId: assistantMessageId,
|
||||||
|
messages: const [],
|
||||||
|
model: selectedModel.id,
|
||||||
|
modelItem: modelItem,
|
||||||
|
sessionId: sessionId,
|
||||||
|
));
|
||||||
|
} catch (_) {}
|
||||||
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
ref.read(chatMessagesProvider.notifier).finishStreaming();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user