refactor: streamline conversation delta stream handling
- Replaced direct stream access in the `regenerateMessage` and `_sendMessageInternal` methods with a new helper function `_conversationDeltaStream` for better encapsulation and reusability. - Improved the management of chat and channel event streams by utilizing the new helper function, enhancing code clarity and maintainability. - Removed the previous `conversationDeltaEventsProvider` as it is no longer necessary with the new implementation, simplifying the provider structure.
This commit is contained in:
@@ -462,27 +462,8 @@ class ConversationDeltaStream extends _$ConversationDeltaStream {
|
|||||||
_socketSubscription?.dispose();
|
_socketSubscription?.dispose();
|
||||||
_socketSubscription = null;
|
_socketSubscription = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides direct access to the underlying stream.
|
|
||||||
/// Note: This getter is necessary for compatibility with StreamProvider.
|
|
||||||
/// While Riverpod 3 discourages public getters on Notifiers, this is a
|
|
||||||
/// pragmatic exception for stream delegation patterns.
|
|
||||||
// ignore: avoid_public_notifier_properties
|
|
||||||
Stream<ConversationDelta> get stream =>
|
|
||||||
_controller?.stream ?? const Stream<ConversationDelta>.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final conversationDeltaEventsProvider =
|
|
||||||
StreamProvider.family<ConversationDelta, ConversationDeltaRequest>((
|
|
||||||
ref,
|
|
||||||
request,
|
|
||||||
) {
|
|
||||||
final notifier = ref.watch(
|
|
||||||
conversationDeltaStreamProvider(request).notifier,
|
|
||||||
);
|
|
||||||
return notifier.stream;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Attachment upload queue provider
|
// Attachment upload queue provider
|
||||||
final attachmentUploadQueueProvider = Provider<AttachmentUploadQueue?>((ref) {
|
final attachmentUploadQueueProvider = Provider<AttachmentUploadQueue?>((ref) {
|
||||||
final api = ref.watch(apiServiceProvider);
|
final api = ref.watch(apiServiceProvider);
|
||||||
|
|||||||
@@ -1331,29 +1331,23 @@ Future<void> regenerateMessage(
|
|||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
final chatEventsStream = ref
|
final chatEventsHandle = _conversationDeltaStream(
|
||||||
.read(
|
ref,
|
||||||
conversationDeltaStreamProvider(
|
|
||||||
ConversationDeltaRequest.chat(
|
ConversationDeltaRequest.chat(
|
||||||
conversationId: activeConversation.id,
|
conversationId: activeConversation.id,
|
||||||
sessionId: effectiveSessionId,
|
sessionId: effectiveSessionId,
|
||||||
requireFocus: false,
|
requireFocus: false,
|
||||||
),
|
),
|
||||||
).notifier,
|
);
|
||||||
)
|
|
||||||
.stream;
|
|
||||||
|
|
||||||
final channelEventsStream = ref
|
final channelEventsHandle = _conversationDeltaStream(
|
||||||
.read(
|
ref,
|
||||||
conversationDeltaStreamProvider(
|
|
||||||
ConversationDeltaRequest.channel(
|
ConversationDeltaRequest.channel(
|
||||||
conversationId: activeConversation.id,
|
conversationId: activeConversation.id,
|
||||||
sessionId: effectiveSessionId,
|
sessionId: effectiveSessionId,
|
||||||
requireFocus: false,
|
requireFocus: false,
|
||||||
),
|
),
|
||||||
).notifier,
|
);
|
||||||
)
|
|
||||||
.stream;
|
|
||||||
|
|
||||||
final activeStream = attachUnifiedChunkedStreaming(
|
final activeStream = attachUnifiedChunkedStreaming(
|
||||||
stream: stream,
|
stream: stream,
|
||||||
@@ -1365,8 +1359,8 @@ Future<void> regenerateMessage(
|
|||||||
activeConversationId: activeConversation.id,
|
activeConversationId: activeConversation.id,
|
||||||
api: api,
|
api: api,
|
||||||
socketService: socketService,
|
socketService: socketService,
|
||||||
chatEvents: chatEventsStream,
|
chatEvents: chatEventsHandle.stream,
|
||||||
channelEvents: channelEventsStream,
|
channelEvents: channelEventsHandle.stream,
|
||||||
appendToLastMessage: (c) =>
|
appendToLastMessage: (c) =>
|
||||||
ref.read(chatMessagesProvider.notifier).appendToLastMessage(c),
|
ref.read(chatMessagesProvider.notifier).appendToLastMessage(c),
|
||||||
replaceLastMessageContent: (c) =>
|
replaceLastMessageContent: (c) =>
|
||||||
@@ -1417,10 +1411,11 @@ Future<void> regenerateMessage(
|
|||||||
);
|
);
|
||||||
ref.read(chatMessagesProvider.notifier)
|
ref.read(chatMessagesProvider.notifier)
|
||||||
..setMessageStream(activeStream.controller)
|
..setMessageStream(activeStream.controller)
|
||||||
..setSocketSubscriptions(
|
..setSocketSubscriptions([
|
||||||
activeStream.socketSubscriptions,
|
...activeStream.socketSubscriptions,
|
||||||
onDispose: activeStream.disposeWatchdog,
|
chatEventsHandle.dispose,
|
||||||
);
|
channelEventsHandle.dispose,
|
||||||
|
], onDispose: activeStream.disposeWatchdog);
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -1456,6 +1451,44 @@ Future<void> sendMessageWithContainer(
|
|||||||
await _sendMessageInternal(container, message, attachments, toolIds);
|
await _sendMessageInternal(container, message, attachments, toolIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
({Stream<ConversationDelta> stream, void Function() dispose})
|
||||||
|
_conversationDeltaStream(dynamic ref, ConversationDeltaRequest request) {
|
||||||
|
final controller = StreamController<ConversationDelta>.broadcast();
|
||||||
|
var isDisposed = false;
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
if (isDisposed) return;
|
||||||
|
isDisposed = true;
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
final subscription = ref.listen<AsyncValue<ConversationDelta>>(
|
||||||
|
conversationDeltaStreamProvider(request),
|
||||||
|
(previous, next) {
|
||||||
|
if (next is AsyncData<ConversationDelta>) {
|
||||||
|
if (!controller.isClosed) controller.add(next.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (next is AsyncError<ConversationDelta>) {
|
||||||
|
if (!controller.isClosed) {
|
||||||
|
controller.addError(next.error, next.stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fireImmediately: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
if (isDisposed) return;
|
||||||
|
subscription.close();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.onCancel = dispose;
|
||||||
|
|
||||||
|
return (stream: controller.stream, dispose: dispose);
|
||||||
|
}
|
||||||
|
|
||||||
// Internal send message implementation
|
// Internal send message implementation
|
||||||
Future<void> _sendMessageInternal(
|
Future<void> _sendMessageInternal(
|
||||||
dynamic ref,
|
dynamic ref,
|
||||||
@@ -1901,29 +1934,23 @@ Future<void> _sendMessageInternal(
|
|||||||
});
|
});
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
final chatEventsStream = ref
|
final chatEventsHandle = _conversationDeltaStream(
|
||||||
.read(
|
ref,
|
||||||
conversationDeltaStreamProvider(
|
|
||||||
ConversationDeltaRequest.chat(
|
ConversationDeltaRequest.chat(
|
||||||
conversationId: activeConversation?.id,
|
conversationId: activeConversation?.id,
|
||||||
sessionId: effectiveSessionId,
|
sessionId: effectiveSessionId,
|
||||||
requireFocus: false,
|
requireFocus: false,
|
||||||
),
|
),
|
||||||
).notifier,
|
);
|
||||||
)
|
|
||||||
.stream;
|
|
||||||
|
|
||||||
final channelEventsStream = ref
|
final channelEventsHandle = _conversationDeltaStream(
|
||||||
.read(
|
ref,
|
||||||
conversationDeltaStreamProvider(
|
|
||||||
ConversationDeltaRequest.channel(
|
ConversationDeltaRequest.channel(
|
||||||
conversationId: activeConversation?.id,
|
conversationId: activeConversation?.id,
|
||||||
sessionId: effectiveSessionId,
|
sessionId: effectiveSessionId,
|
||||||
requireFocus: false,
|
requireFocus: false,
|
||||||
),
|
),
|
||||||
).notifier,
|
);
|
||||||
)
|
|
||||||
.stream;
|
|
||||||
|
|
||||||
final activeStream = attachUnifiedChunkedStreaming(
|
final activeStream = attachUnifiedChunkedStreaming(
|
||||||
stream: stream,
|
stream: stream,
|
||||||
@@ -1935,8 +1962,8 @@ Future<void> _sendMessageInternal(
|
|||||||
activeConversationId: activeConversation?.id,
|
activeConversationId: activeConversation?.id,
|
||||||
api: api,
|
api: api,
|
||||||
socketService: socketService,
|
socketService: socketService,
|
||||||
chatEvents: chatEventsStream,
|
chatEvents: chatEventsHandle.stream,
|
||||||
channelEvents: channelEventsStream,
|
channelEvents: channelEventsHandle.stream,
|
||||||
appendToLastMessage: (c) =>
|
appendToLastMessage: (c) =>
|
||||||
ref.read(chatMessagesProvider.notifier).appendToLastMessage(c),
|
ref.read(chatMessagesProvider.notifier).appendToLastMessage(c),
|
||||||
replaceLastMessageContent: (c) =>
|
replaceLastMessageContent: (c) =>
|
||||||
@@ -1988,10 +2015,11 @@ Future<void> _sendMessageInternal(
|
|||||||
|
|
||||||
ref.read(chatMessagesProvider.notifier)
|
ref.read(chatMessagesProvider.notifier)
|
||||||
..setMessageStream(activeStream.controller)
|
..setMessageStream(activeStream.controller)
|
||||||
..setSocketSubscriptions(
|
..setSocketSubscriptions([
|
||||||
activeStream.socketSubscriptions,
|
...activeStream.socketSubscriptions,
|
||||||
onDispose: activeStream.disposeWatchdog,
|
chatEventsHandle.dispose,
|
||||||
);
|
channelEventsHandle.dispose,
|
||||||
|
], onDispose: activeStream.disposeWatchdog);
|
||||||
return;
|
return;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Handle error - remove the assistant message placeholder
|
// Handle error - remove the assistant message placeholder
|
||||||
|
|||||||
Reference in New Issue
Block a user