|
@@ -1,4 +1,5 @@
|
|
import 'dart:convert';
|
|
import 'dart:convert';
|
|
|
|
+
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/service/openai_client.dart';
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/service/openai_client.dart';
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/util/learn_more_action.dart';
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/util/learn_more_action.dart';
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/discard_dialog.dart';
|
|
import 'package:appflowy/plugins/document/presentation/plugins/openai/widgets/discard_dialog.dart';
|
|
@@ -20,8 +21,6 @@ import '../util/editor_extension.dart';
|
|
|
|
|
|
const String kAutoCompletionInputType = 'auto_completion_input';
|
|
const String kAutoCompletionInputType = 'auto_completion_input';
|
|
const String kAutoCompletionInputString = 'auto_completion_input_string';
|
|
const String kAutoCompletionInputString = 'auto_completion_input_string';
|
|
-const String kAutoCompletionGenerationCount =
|
|
|
|
- 'auto_completion_generation_count';
|
|
|
|
const String kAutoCompletionInputStartSelection =
|
|
const String kAutoCompletionInputStartSelection =
|
|
'auto_completion_input_start_selection';
|
|
'auto_completion_input_start_selection';
|
|
|
|
|
|
@@ -125,8 +124,7 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
}
|
|
}
|
|
|
|
|
|
Widget _buildAutoGeneratorPanel(BuildContext context) {
|
|
Widget _buildAutoGeneratorPanel(BuildContext context) {
|
|
- if (text.isEmpty &&
|
|
|
|
- widget.node.attributes[kAutoCompletionGenerationCount] < 1) {
|
|
|
|
|
|
+ if (text.isEmpty) {
|
|
return Column(
|
|
return Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
children: [
|
|
@@ -206,15 +204,6 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
- Future<void> _updateGenerationCount() async {
|
|
|
|
- final transaction = widget.editorState.transaction;
|
|
|
|
- transaction.updateNode(widget.node, {
|
|
|
|
- kAutoCompletionGenerationCount:
|
|
|
|
- widget.node.attributes[kAutoCompletionGenerationCount] + 1
|
|
|
|
- });
|
|
|
|
- await widget.editorState.apply(transaction);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
Widget _buildFooterWidget(BuildContext context) {
|
|
Widget _buildFooterWidget(BuildContext context) {
|
|
return Row(
|
|
return Row(
|
|
children: [
|
|
children: [
|
|
@@ -223,11 +212,6 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
onPressed: () => _onExit(),
|
|
onPressed: () => _onExit(),
|
|
),
|
|
),
|
|
const Space(10, 0),
|
|
const Space(10, 0),
|
|
- SecondaryTextButton(
|
|
|
|
- LocaleKeys.document_plugins_autoGeneratorRewrite.tr(),
|
|
|
|
- onPressed: () => _onRewrite(),
|
|
|
|
- ),
|
|
|
|
- const Space(10, 0),
|
|
|
|
SecondaryTextButton(
|
|
SecondaryTextButton(
|
|
LocaleKeys.button_discard.tr(),
|
|
LocaleKeys.button_discard.tr(),
|
|
onPressed: () => _onDiscard(),
|
|
onPressed: () => _onDiscard(),
|
|
@@ -288,64 +272,6 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
await _showError(error.message);
|
|
await _showError(error.message);
|
|
},
|
|
},
|
|
);
|
|
);
|
|
- await _updateGenerationCount();
|
|
|
|
- }, (error) async {
|
|
|
|
- loading.stop();
|
|
|
|
- await _showError(
|
|
|
|
- LocaleKeys.document_plugins_autoGeneratorCantGetOpenAIKey.tr(),
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- Future<void> _onRewrite() async {
|
|
|
|
- String previousOutput = _getPreviousOutput()!;
|
|
|
|
- final loading = Loading(context);
|
|
|
|
- loading.start();
|
|
|
|
- // clear previous response
|
|
|
|
- final selection =
|
|
|
|
- widget.node.attributes[kAutoCompletionInputStartSelection];
|
|
|
|
- if (selection != null) {
|
|
|
|
- final start = Selection.fromJson(json.decode(selection)).start.path;
|
|
|
|
- final end = widget.node.previous?.path;
|
|
|
|
- if (end != null) {
|
|
|
|
- final transaction = widget.editorState.transaction;
|
|
|
|
- transaction.deleteNodesAtPath(
|
|
|
|
- start,
|
|
|
|
- end.last - start.last + 1,
|
|
|
|
- );
|
|
|
|
- await widget.editorState.apply(transaction);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // generate new response
|
|
|
|
- final result = await UserBackendService.getCurrentUserProfile();
|
|
|
|
- result.fold((userProfile) async {
|
|
|
|
- final openAIRepository = HttpOpenAIRepository(
|
|
|
|
- client: http.Client(),
|
|
|
|
- apiKey: userProfile.openaiKey,
|
|
|
|
- );
|
|
|
|
- await openAIRepository.getStreamedCompletions(
|
|
|
|
- prompt: _rewritePrompt(previousOutput),
|
|
|
|
- onStart: () async {
|
|
|
|
- loading.stop();
|
|
|
|
- await _makeSurePreviousNodeIsEmptyTextNode();
|
|
|
|
- },
|
|
|
|
- onProcess: (response) async {
|
|
|
|
- if (response.choices.isNotEmpty) {
|
|
|
|
- final text = response.choices.first.text;
|
|
|
|
- await widget.editorState.autoInsertText(
|
|
|
|
- text,
|
|
|
|
- inputType: TextRobotInputType.word,
|
|
|
|
- delay: Duration.zero,
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- onEnd: () async {},
|
|
|
|
- onError: (error) async {
|
|
|
|
- loading.stop();
|
|
|
|
- await _showError(error.message);
|
|
|
|
- },
|
|
|
|
- );
|
|
|
|
- await _updateGenerationCount();
|
|
|
|
}, (error) async {
|
|
}, (error) async {
|
|
loading.stop();
|
|
loading.stop();
|
|
await _showError(
|
|
await _showError(
|
|
@@ -354,31 +280,6 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- String? _getPreviousOutput() {
|
|
|
|
- final selection =
|
|
|
|
- widget.node.attributes[kAutoCompletionInputStartSelection];
|
|
|
|
- if (selection != null) {
|
|
|
|
- final start = Selection.fromJson(json.decode(selection)).start.path;
|
|
|
|
- final end = widget.node.previous?.path;
|
|
|
|
- if (end != null) {
|
|
|
|
- String lastOutput = "";
|
|
|
|
- for (var i = start.last; i < end.last - start.last + 2; i++) {
|
|
|
|
- TextNode? textNode =
|
|
|
|
- widget.editorState.document.nodeAtPath([i]) as TextNode?;
|
|
|
|
- lastOutput = "$lastOutput ${textNode!.toPlainText()}";
|
|
|
|
- }
|
|
|
|
- return lastOutput.trim();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- String _rewritePrompt(String previousOutput) {
|
|
|
|
- String prompt =
|
|
|
|
- 'I am not satisfied with your previous response($previousOutput) to the query ($text) please write another one';
|
|
|
|
- return prompt;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
Future<void> _onDiscard() async {
|
|
Future<void> _onDiscard() async {
|
|
final selection =
|
|
final selection =
|
|
widget.node.attributes[kAutoCompletionInputStartSelection];
|
|
widget.node.attributes[kAutoCompletionInputStartSelection];
|
|
@@ -392,7 +293,6 @@ class _AutoCompletionInputState extends State<_AutoCompletionInput> {
|
|
end.last - start.last + 1,
|
|
end.last - start.last + 1,
|
|
);
|
|
);
|
|
await widget.editorState.apply(transaction);
|
|
await widget.editorState.apply(transaction);
|
|
- await _makeSurePreviousNodeIsEmptyTextNode();
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_onExit();
|
|
_onExit();
|