mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-12-28 07:33:45 +00:00
chore: implement ui
This commit is contained in:
parent
13a7ea07a8
commit
10f19069c6
@ -24,7 +24,8 @@ abstract class AIRepository {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function(String text) processAssistMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
});
|
||||
@ -40,18 +41,17 @@ class AppFlowyAIService implements AIRepository {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function(String text) processAssistMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
}) async {
|
||||
final stream = AppFlowyCompletionStream(
|
||||
onStart: onStart,
|
||||
onProcess: onProcess,
|
||||
processMessage: processMessage,
|
||||
processAssistMessage: processAssistMessage,
|
||||
processError: onError,
|
||||
onEnd: onEnd,
|
||||
onError: onError,
|
||||
onComment: (String text) async {
|
||||
Log.info('Comment: $text');
|
||||
},
|
||||
);
|
||||
|
||||
final records = history.map((record) => record.toPB()).toList();
|
||||
@ -82,26 +82,26 @@ class AppFlowyAIService implements AIRepository {
|
||||
abstract class CompletionStream {
|
||||
CompletionStream({
|
||||
required this.onStart,
|
||||
required this.onProcess,
|
||||
required this.onComment,
|
||||
required this.processMessage,
|
||||
required this.processAssistMessage,
|
||||
required this.processError,
|
||||
required this.onEnd,
|
||||
required this.onError,
|
||||
});
|
||||
|
||||
final Future<void> Function() onStart;
|
||||
final Future<void> Function(String text) onProcess;
|
||||
final Future<void> Function(String text) onComment;
|
||||
final Future<void> Function(String text) processMessage;
|
||||
final Future<void> Function(String text) processAssistMessage;
|
||||
final void Function(AIError error) processError;
|
||||
final Future<void> Function() onEnd;
|
||||
final void Function(AIError error) onError;
|
||||
}
|
||||
|
||||
class AppFlowyCompletionStream extends CompletionStream {
|
||||
AppFlowyCompletionStream({
|
||||
required super.onStart,
|
||||
required super.onProcess,
|
||||
required super.onComment,
|
||||
required super.processMessage,
|
||||
required super.processAssistMessage,
|
||||
required super.processError,
|
||||
required super.onEnd,
|
||||
required super.onError,
|
||||
}) {
|
||||
_startListening();
|
||||
}
|
||||
@ -116,7 +116,7 @@ class AppFlowyCompletionStream extends CompletionStream {
|
||||
_subscription = _controller.stream.listen(
|
||||
(event) async {
|
||||
if (event == "AI_RESPONSE_LIMIT") {
|
||||
onError(
|
||||
processError(
|
||||
AIError(
|
||||
message: LocaleKeys.ai_textLimitReachedDescription.tr(),
|
||||
code: AIErrorCode.aiResponseLimitExceeded,
|
||||
@ -125,7 +125,7 @@ class AppFlowyCompletionStream extends CompletionStream {
|
||||
}
|
||||
|
||||
if (event == "AI_IMAGE_RESPONSE_LIMIT") {
|
||||
onError(
|
||||
processError(
|
||||
AIError(
|
||||
message: LocaleKeys.ai_imageLimitReachedDescription.tr(),
|
||||
code: AIErrorCode.aiImageResponseLimitExceeded,
|
||||
@ -135,7 +135,7 @@ class AppFlowyCompletionStream extends CompletionStream {
|
||||
|
||||
if (event.startsWith("AI_MAX_REQUIRED:")) {
|
||||
final msg = event.substring(16);
|
||||
onError(
|
||||
processError(
|
||||
AIError(
|
||||
message: msg,
|
||||
code: AIErrorCode.other,
|
||||
@ -148,11 +148,11 @@ class AppFlowyCompletionStream extends CompletionStream {
|
||||
}
|
||||
|
||||
if (event.startsWith("data:")) {
|
||||
await onProcess(event.substring(5));
|
||||
await processMessage(event.substring(5));
|
||||
}
|
||||
|
||||
if (event.startsWith("comment:")) {
|
||||
await onComment(event.substring(8));
|
||||
await processAssistMessage(event.substring(8));
|
||||
}
|
||||
|
||||
if (event.startsWith("finish:")) {
|
||||
@ -160,7 +160,7 @@ class AppFlowyCompletionStream extends CompletionStream {
|
||||
}
|
||||
|
||||
if (event.startsWith("error:")) {
|
||||
onError(
|
||||
processError(
|
||||
AIError(message: event.substring(6), code: AIErrorCode.other),
|
||||
);
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
AiWriterRecord.user(content: prompt),
|
||||
);
|
||||
},
|
||||
onProcess: (text) async {
|
||||
processMessage: (text) async {
|
||||
await _textRobot.appendMarkdownText(
|
||||
text,
|
||||
updateSelection: false,
|
||||
@ -301,14 +301,33 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
onAppendToDocument?.call();
|
||||
},
|
||||
processAssistMessage: (text) async {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
emit(
|
||||
GeneratingAiWriterState(
|
||||
command,
|
||||
taskId: generatingState.taskId,
|
||||
markdownText: generatingState.markdownText + text,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onEnd: () async {
|
||||
await _textRobot.stop(
|
||||
attributes: ApplySuggestionFormatType.replace.attributes,
|
||||
);
|
||||
emit(ReadyAiWriterState(command, isFirstRun: false));
|
||||
records.add(
|
||||
AiWriterRecord.ai(content: _textRobot.markdownText),
|
||||
);
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
await _textRobot.stop(
|
||||
attributes: ApplySuggestionFormatType.replace.attributes,
|
||||
);
|
||||
emit(
|
||||
ReadyAiWriterState(
|
||||
command,
|
||||
isFirstRun: false,
|
||||
markdownText: generatingState.markdownText,
|
||||
),
|
||||
);
|
||||
records.add(
|
||||
AiWriterRecord.ai(content: _textRobot.markdownText),
|
||||
);
|
||||
}
|
||||
},
|
||||
onError: (error) async {
|
||||
emit(ErrorAiWriterState(command, error: error));
|
||||
@ -392,7 +411,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
_textRobot.start(position: position);
|
||||
},
|
||||
onProcess: (text) async {
|
||||
processMessage: (text) async {
|
||||
await _textRobot.appendMarkdownText(
|
||||
text,
|
||||
updateSelection: false,
|
||||
@ -400,12 +419,29 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
onAppendToDocument?.call();
|
||||
},
|
||||
processAssistMessage: (text) async {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
emit(
|
||||
GeneratingAiWriterState(
|
||||
command,
|
||||
taskId: generatingState.taskId,
|
||||
markdownText: generatingState.markdownText + text,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onEnd: () async {
|
||||
if (state case GeneratingAiWriterState _) {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
await _textRobot.stop(
|
||||
attributes: ApplySuggestionFormatType.replace.attributes,
|
||||
);
|
||||
emit(ReadyAiWriterState(command, isFirstRun: false));
|
||||
emit(
|
||||
ReadyAiWriterState(
|
||||
command,
|
||||
isFirstRun: false,
|
||||
markdownText: generatingState.markdownText,
|
||||
),
|
||||
);
|
||||
}
|
||||
records.add(
|
||||
AiWriterRecord.ai(content: _textRobot.markdownText),
|
||||
@ -468,7 +504,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
_textRobot.start(position: position);
|
||||
},
|
||||
onProcess: (text) async {
|
||||
processMessage: (text) async {
|
||||
await _textRobot.appendMarkdownText(
|
||||
text,
|
||||
updateSelection: false,
|
||||
@ -476,8 +512,19 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
onAppendToDocument?.call();
|
||||
},
|
||||
processAssistMessage: (text) async {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
emit(
|
||||
GeneratingAiWriterState(
|
||||
command,
|
||||
taskId: generatingState.taskId,
|
||||
markdownText: generatingState.markdownText + text,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onEnd: () async {
|
||||
if (state is GeneratingAiWriterState) {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
await _textRobot.stop(
|
||||
attributes: ApplySuggestionFormatType.replace.attributes,
|
||||
);
|
||||
@ -485,6 +532,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
ReadyAiWriterState(
|
||||
command,
|
||||
isFirstRun: false,
|
||||
markdownText: generatingState.markdownText,
|
||||
),
|
||||
);
|
||||
records.add(
|
||||
@ -524,7 +572,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
completionType: command.toCompletionType(),
|
||||
history: records,
|
||||
onStart: () async {},
|
||||
onProcess: (text) async {
|
||||
processMessage: (text) async {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
emit(
|
||||
GeneratingAiWriterState(
|
||||
@ -535,6 +583,7 @@ class AiWriterCubit extends Cubit<AiWriterState> {
|
||||
);
|
||||
}
|
||||
},
|
||||
processAssistMessage: (_) async {},
|
||||
onEnd: () async {
|
||||
if (state case final GeneratingAiWriterState generatingState) {
|
||||
emit(
|
||||
|
||||
@ -26,7 +26,7 @@ class _MockAIRepository extends Mock implements AppFlowyAIService {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
}) async {
|
||||
@ -37,7 +37,7 @@ class _MockAIRepository extends Mock implements AppFlowyAIService {
|
||||
final lines = text.split('\n');
|
||||
for (final line in lines) {
|
||||
if (line.isNotEmpty) {
|
||||
await onProcess('$_aiResponse $line\n\n');
|
||||
await processMessage('$_aiResponse $line\n\n');
|
||||
}
|
||||
}
|
||||
await onEnd();
|
||||
@ -57,7 +57,7 @@ class _MockAIRepositoryLess extends Mock implements AppFlowyAIService {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
}) async {
|
||||
@ -66,7 +66,7 @@ class _MockAIRepositoryLess extends Mock implements AppFlowyAIService {
|
||||
Future(() async {
|
||||
await onStart();
|
||||
// only return 1 line.
|
||||
await onProcess('Hello World');
|
||||
await processMessage('Hello World');
|
||||
await onEnd();
|
||||
}),
|
||||
);
|
||||
@ -84,7 +84,7 @@ class _MockAIRepositoryMore extends Mock implements AppFlowyAIService {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
}) async {
|
||||
@ -94,7 +94,7 @@ class _MockAIRepositoryMore extends Mock implements AppFlowyAIService {
|
||||
await onStart();
|
||||
// return 10 lines
|
||||
for (var i = 0; i < 10; i++) {
|
||||
await onProcess('Hello World\n\n');
|
||||
await processMessage('Hello World\n\n');
|
||||
}
|
||||
await onEnd();
|
||||
}),
|
||||
@ -113,7 +113,7 @@ class _MockErrorRepository extends Mock implements AppFlowyAIService {
|
||||
List<AiWriterRecord> history = const [],
|
||||
required CompletionTypePB completionType,
|
||||
required Future<void> Function() onStart,
|
||||
required Future<void> Function(String text) onProcess,
|
||||
required Future<void> Function(String text) processMessage,
|
||||
required Future<void> Function() onEnd,
|
||||
required void Function(AIError error) onError,
|
||||
}) async {
|
||||
|
||||
@ -197,6 +197,7 @@ where
|
||||
.await
|
||||
.map_err(FlowyError::from)?
|
||||
.map_err(FlowyError::from);
|
||||
|
||||
Ok(stream.boxed())
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user