mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: openai and stabilityai integration (#3439)
* chore: create trait * test: add tests * chore: remove log * chore: disable log
This commit is contained in:
parent
37a5054ebd
commit
6ba7fc0317
@ -34,7 +34,7 @@ class TransactionAdapter {
|
||||
final DocumentService documentService;
|
||||
final String documentId;
|
||||
|
||||
final bool _enableDebug = true;
|
||||
final bool _enableDebug = false;
|
||||
|
||||
Future<void> apply(Transaction transaction, EditorState editorState) async {
|
||||
final stopwatch = Stopwatch()..start();
|
||||
|
@ -150,7 +150,6 @@ Future<AppTheme> appTheme(String themeName) async {
|
||||
try {
|
||||
return await AppTheme.fromName(themeName);
|
||||
} catch (e) {
|
||||
Log.error(e);
|
||||
return AppTheme.fallback;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:appflowy_backend/dispatch/dispatch.dart';
|
||||
@ -17,10 +16,7 @@ class UserBackendService {
|
||||
|
||||
static Future<Either<FlowyError, UserProfilePB>>
|
||||
getCurrentUserProfile() async {
|
||||
final result = await UserEventGetUserProfile().send().then((value) {
|
||||
value.fold((l) => null, (r) => Log.info(r));
|
||||
return value;
|
||||
});
|
||||
final result = await UserEventGetUserProfile().send();
|
||||
return result.swap();
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ class SplashScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _handleUnauthenticated(BuildContext context, Unauthenticated result) {
|
||||
Log.debug(
|
||||
Log.trace(
|
||||
'_handleUnauthenticated -> Supabase is enabled: $isSupabaseEnabled',
|
||||
);
|
||||
// if the env is not configured, we will skip to the 'skip login screen'.
|
||||
|
@ -21,6 +21,7 @@ class Log {
|
||||
printEmojis: true, // Print an emoji for each log message
|
||||
printTime: false // Should each log print contain a timestamp
|
||||
),
|
||||
level: kDebugMode ? Level.verbose : Level.info,
|
||||
);
|
||||
}
|
||||
|
||||
|
185
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
185
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -172,6 +172,38 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "async-convert"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d416feee97712e43152cd42874de162b8f9b77295b1c85e5d92725cc8310bae"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-openai"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7150fb5d9cc4eb0184af43ce75a89620dc3747d3c816e8b0ba200682d0155c05"
|
||||
dependencies = [
|
||||
"async-convert",
|
||||
"backoff",
|
||||
"base64 0.21.2",
|
||||
"derive_builder",
|
||||
"futures",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"reqwest-eventsource",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.5"
|
||||
@ -250,6 +282,20 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backoff"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"getrandom 0.2.10",
|
||||
"instant",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.67"
|
||||
@ -362,7 +408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
|
||||
dependencies = [
|
||||
"borsh-derive",
|
||||
"hashbrown 0.12.3",
|
||||
"hashbrown 0.13.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1215,14 +1261,38 @@ dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"darling_macro 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
"darling_core 0.20.1",
|
||||
"darling_macro 0.20.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1239,13 +1309,24 @@ dependencies = [
|
||||
"syn 2.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_core 0.20.1",
|
||||
"quote",
|
||||
"syn 2.0.29",
|
||||
]
|
||||
@ -1274,6 +1355,37 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
|
||||
dependencies = [
|
||||
"darling 0.14.4",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
@ -1364,6 +1476,12 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "dotenv"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||
|
||||
[[package]]
|
||||
name = "dotenvy"
|
||||
version = "0.15.7"
|
||||
@ -1482,6 +1600,17 @@ version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "eventsource-stream"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"nom 7.1.3",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "faccess"
|
||||
version = "0.2.4"
|
||||
@ -1573,17 +1702,14 @@ dependencies = [
|
||||
name = "flowy-ai"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flowy-derive",
|
||||
"flowy-error",
|
||||
"flowy-notification",
|
||||
"lib-dispatch",
|
||||
"anyhow",
|
||||
"async-openai",
|
||||
"dotenv",
|
||||
"lib-infra",
|
||||
"protobuf",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum_macros 0.21.1",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2160,6 +2286,12 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.28"
|
||||
@ -4515,6 +4647,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -4533,6 +4666,22 @@ dependencies = [
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest-eventsource"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f03f570355882dd8d15acc3a313841e6e90eddbc76a93c748fd82cc13ba9f51"
|
||||
dependencies = [
|
||||
"eventsource-stream",
|
||||
"futures-core",
|
||||
"futures-timer",
|
||||
"mime",
|
||||
"nom 7.1.3",
|
||||
"pin-project-lite",
|
||||
"reqwest",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
@ -4661,6 +4810,18 @@ dependencies = [
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
@ -4911,7 +5072,7 @@ version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"darling 0.20.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.29",
|
||||
|
192
frontend/rust-lib/Cargo.lock
generated
192
frontend/rust-lib/Cargo.lock
generated
@ -152,6 +152,38 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-convert"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d416feee97712e43152cd42874de162b8f9b77295b1c85e5d92725cc8310bae"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-openai"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7150fb5d9cc4eb0184af43ce75a89620dc3747d3c816e8b0ba200682d0155c05"
|
||||
dependencies = [
|
||||
"async-convert",
|
||||
"backoff",
|
||||
"base64 0.21.3",
|
||||
"derive_builder",
|
||||
"futures",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"reqwest-eventsource",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-stream"
|
||||
version = "0.3.5"
|
||||
@ -257,6 +289,20 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backoff"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"getrandom 0.2.10",
|
||||
"instant",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
@ -375,7 +421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b"
|
||||
dependencies = [
|
||||
"borsh-derive",
|
||||
"hashbrown 0.12.3",
|
||||
"hashbrown 0.13.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1048,6 +1094,41 @@ dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dart-ffi"
|
||||
version = "0.1.0"
|
||||
@ -1104,6 +1185,37 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deunicode"
|
||||
version = "0.4.4"
|
||||
@ -1248,6 +1360,17 @@ version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "eventsource-stream"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"nom 7.1.3",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "faccess"
|
||||
version = "0.2.4"
|
||||
@ -1321,17 +1444,14 @@ dependencies = [
|
||||
name = "flowy-ai"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flowy-derive",
|
||||
"flowy-error",
|
||||
"flowy-notification",
|
||||
"lib-dispatch",
|
||||
"anyhow",
|
||||
"async-openai",
|
||||
"dotenv",
|
||||
"lib-infra",
|
||||
"protobuf",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum_macros 0.21.1",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1971,6 +2091,12 @@ version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.28"
|
||||
@ -2340,6 +2466,12 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@ -2403,6 +2535,15 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.8.0"
|
||||
@ -3737,6 +3878,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3755,6 +3897,22 @@ dependencies = [
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest-eventsource"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f03f570355882dd8d15acc3a313841e6e90eddbc76a93c748fd82cc13ba9f51"
|
||||
dependencies = [
|
||||
"eventsource-stream",
|
||||
"futures-core",
|
||||
"futures-timer",
|
||||
"mime",
|
||||
"nom 7.1.3",
|
||||
"pin-project-lite",
|
||||
"reqwest",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
@ -3871,6 +4029,18 @@ dependencies = [
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-native-certs"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||
dependencies = [
|
||||
"openssl-probe",
|
||||
"rustls-pemfile",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.3"
|
||||
@ -4323,6 +4493,12 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.25.0"
|
||||
|
@ -6,15 +6,11 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
flowy-derive = { path = "../../../shared-lib/flowy-derive" }
|
||||
flowy-notification = { path = "../flowy-notification" }
|
||||
flowy-error = { path = "../flowy-error", features = ["impl_from_serde", "impl_from_dispatch_error"] }
|
||||
lib-dispatch = { path = "../lib-dispatch" }
|
||||
lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
|
||||
protobuf = {version = "2.28.0"}
|
||||
bytes = { version = "1.4" }
|
||||
strum_macros = "0.21"
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
anyhow = "1.0.75"
|
||||
lib-infra = { path = "../../../shared-lib/lib-infra" }
|
||||
async-openai = "0.14.2"
|
||||
tokio = { version = "1.12", features = ["rt", "sync"] }
|
||||
dotenv = "0.15.0"
|
16
frontend/rust-lib/flowy-ai/src/config.rs
Normal file
16
frontend/rust-lib/flowy-ai/src/config.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use anyhow::{anyhow, Error};
|
||||
|
||||
pub struct OpenAISetting {
|
||||
pub openai_api_key: String,
|
||||
}
|
||||
|
||||
const OPENAI_API_KEY: &str = "OPENAI_API_KEY";
|
||||
|
||||
impl OpenAISetting {
|
||||
pub fn from_env() -> Result<Self, Error> {
|
||||
let openai_api_key =
|
||||
std::env::var(OPENAI_API_KEY).map_err(|_| anyhow!("Missing OPENAI_API_KEY"))?;
|
||||
|
||||
Ok(Self { openai_api_key })
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
use flowy_error::ErrorCode;
|
||||
|
||||
/*
|
||||
model="text-davinci-003",
|
||||
prompt="Write a tagline for an ice cream shop."
|
||||
*/
|
||||
#[derive(Default)]
|
||||
pub struct TextCompletionPayloadPB {
|
||||
pub request_id: String,
|
||||
|
||||
// Model: Either text-davinci-003 or gpt-3.5-turbo
|
||||
pub model: String,
|
||||
|
||||
// Prompt to query gpt
|
||||
pub prompt: String,
|
||||
|
||||
// User open_ai_key for authentication
|
||||
pub open_ai_key: String,
|
||||
}
|
||||
|
||||
pub struct TextCompletionParams {
|
||||
pub request_id: String,
|
||||
pub model: String,
|
||||
pub prompt: String,
|
||||
pub open_ai_key: String,
|
||||
}
|
||||
|
||||
impl TryInto<TextCompletionParams> for TextCompletionPayloadPB {
|
||||
type Error = ErrorCode;
|
||||
fn try_into(self) -> Result<TextCompletionParams, Self::Error> {
|
||||
Ok(TextCompletionParams {
|
||||
request_id: self.request_id,
|
||||
model: self.model,
|
||||
prompt: self.prompt,
|
||||
open_ai_key: self.open_ai_key,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"id": "chatcmpl-123",
|
||||
"object": "chat.completion",
|
||||
"created": 1677652288,
|
||||
"model": "gpt-3.5-turbo-0613",
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": "\n\nHello there, how may I assist you today?",
|
||||
},
|
||||
"finish_reason": "stop"
|
||||
}],
|
||||
"usage": {
|
||||
"prompt_tokens": 9,
|
||||
"completion_tokens": 12,
|
||||
"total_tokens": 21
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
#[derive(Default)]
|
||||
pub struct TextCompletionDataPB {
|
||||
pub request_id: String,
|
||||
|
||||
pub model: String,
|
||||
|
||||
pub index: i32,
|
||||
|
||||
pub content: String,
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
use crate::entities::{TextCompletionDataPB, TextCompletionParams, TextCompletionPayloadPB};
|
||||
use flowy_error::FlowyError;
|
||||
use lib_dispatch::prelude::{data_result_ok, AFPluginData, DataResult};
|
||||
use reqwest;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Message {
|
||||
role: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct RequestBody {
|
||||
model: String,
|
||||
messages: Vec<Message>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ResponseChoice {
|
||||
index: i32,
|
||||
message: Message,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ApiResponse {
|
||||
choices: Vec<ResponseChoice>,
|
||||
}
|
||||
|
||||
pub(crate) async fn request_text_completion(
|
||||
data: AFPluginData<TextCompletionPayloadPB>,
|
||||
) -> DataResult<TextCompletionDataPB, FlowyError> {
|
||||
// Set up the request body
|
||||
let body = RequestBody {
|
||||
model: "gpt-3.5-turbo".to_string(),
|
||||
messages: vec![
|
||||
Message {
|
||||
role: "system".to_string(),
|
||||
content: "You are a helpful assistant.".to_string(),
|
||||
},
|
||||
Message {
|
||||
role: "user".to_string(),
|
||||
content: data.prompt.to_string(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Make the API call
|
||||
let client = reqwest::Client::new();
|
||||
let response: ApiResponse = client
|
||||
.post("https://api.openai.com/v1/chat/completions")
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Authorization", format!("Bearer {}", data.open_ai_key))
|
||||
.json(&body)
|
||||
.send()
|
||||
.await?
|
||||
.json()
|
||||
.await?;
|
||||
|
||||
// Extract index and content
|
||||
let _choice = &response.choices[0];
|
||||
|
||||
let params: TextCompletionParams = data.into_inner().try_into()?;
|
||||
|
||||
data_result_ok(TextCompletionDataPB {
|
||||
request_id: params.request_id,
|
||||
model: params.model,
|
||||
index: response.choices[0].index,
|
||||
content: response.choices[0].message.content.to_string(),
|
||||
})
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||
use lib_dispatch::prelude::AFPlugin;
|
||||
use strum_macros::Display;
|
||||
|
||||
use crate::event_handler::request_text_completion;
|
||||
|
||||
pub fn init() -> AFPlugin {
|
||||
AFPlugin::new()
|
||||
.name(env!("CARGO_PKG_NAME"))
|
||||
.event(OpenAIEvent::RequestTextCompletion, request_text_completion)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Display, ProtoBuf_Enum, Flowy_Event)]
|
||||
#[event_err = "FlowyError"]
|
||||
pub enum OpenAIEvent {
|
||||
#[event(input = "TextCompletionPayloadPB", output = "TextCompletionDataPB")]
|
||||
RequestTextCompletion = 0,
|
||||
}
|
@ -1,4 +1,2 @@
|
||||
// pub mod entities;
|
||||
// pub mod event_handler;
|
||||
// pub mod event_map;
|
||||
// pub mod notification;
|
||||
pub mod config;
|
||||
pub mod text;
|
||||
|
@ -1,21 +0,0 @@
|
||||
use flowy_derive::ProtoBuf_Enum;
|
||||
use flowy_notification::NotificationBuilder;
|
||||
|
||||
const OPEN_AI_NOTIFICATION: &str = "OpenAI";
|
||||
|
||||
#[derive(ProtoBuf_Enum, Debug, Default)]
|
||||
pub(crate) enum OpenAINotification {
|
||||
#[default]
|
||||
Unknown = 0,
|
||||
}
|
||||
|
||||
impl std::convert::From<OpenAINotification> for i32 {
|
||||
fn from(notification: OpenAINotification) -> Self {
|
||||
notification as i32
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn send_notification(id: &str, ty: OpenAINotification) -> NotificationBuilder {
|
||||
NotificationBuilder::new(id, ty, OPEN_AI_NOTIFICATION)
|
||||
}
|
1
frontend/rust-lib/flowy-ai/src/text/entities.rs
Normal file
1
frontend/rust-lib/flowy-ai/src/text/entities.rs
Normal file
@ -0,0 +1 @@
|
||||
|
14
frontend/rust-lib/flowy-ai/src/text/mod.rs
Normal file
14
frontend/rust-lib/flowy-ai/src/text/mod.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use anyhow::Error;
|
||||
use lib_infra::async_trait::async_trait;
|
||||
|
||||
mod entities;
|
||||
pub mod open_ai;
|
||||
pub mod stability_ai;
|
||||
|
||||
#[async_trait]
|
||||
pub trait TextCompletion: Send + Sync {
|
||||
type Input: Send + 'static;
|
||||
type Output;
|
||||
|
||||
async fn text_completion(&self, params: Self::Input) -> Result<Self::Output, Error>;
|
||||
}
|
30
frontend/rust-lib/flowy-ai/src/text/open_ai.rs
Normal file
30
frontend/rust-lib/flowy-ai/src/text/open_ai.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::text::TextCompletion;
|
||||
use anyhow::Error;
|
||||
use async_openai::config::OpenAIConfig;
|
||||
use async_openai::types::{CreateCompletionRequest, CreateCompletionResponse};
|
||||
use async_openai::Client;
|
||||
use lib_infra::async_trait::async_trait;
|
||||
|
||||
pub struct OpenAITextCompletion {
|
||||
client: Client<OpenAIConfig>,
|
||||
}
|
||||
|
||||
impl OpenAITextCompletion {
|
||||
pub fn new(api_key: &str) -> Self {
|
||||
// https://docs.rs/async-openai/latest/async_openai/struct.Completions.html
|
||||
let config = OpenAIConfig::new().with_api_key(api_key);
|
||||
let client = Client::with_config(config);
|
||||
Self { client }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl TextCompletion for OpenAITextCompletion {
|
||||
type Input = CreateCompletionRequest;
|
||||
type Output = CreateCompletionResponse;
|
||||
|
||||
async fn text_completion(&self, params: Self::Input) -> Result<Self::Output, Error> {
|
||||
let response = self.client.completions().create(params).await?;
|
||||
Ok(response)
|
||||
}
|
||||
}
|
15
frontend/rust-lib/flowy-ai/src/text/stability_ai.rs
Normal file
15
frontend/rust-lib/flowy-ai/src/text/stability_ai.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use crate::text::TextCompletion;
|
||||
use anyhow::Error;
|
||||
use lib_infra::async_trait::async_trait;
|
||||
|
||||
pub struct StabilityAITextCompletion {}
|
||||
|
||||
#[async_trait]
|
||||
impl TextCompletion for StabilityAITextCompletion {
|
||||
type Input = ();
|
||||
type Output = ();
|
||||
|
||||
async fn text_completion(&self, _params: Self::Input) -> Result<Self::Output, Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
2
frontend/rust-lib/flowy-ai/tests/main.rs
Normal file
2
frontend/rust-lib/flowy-ai/tests/main.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod text;
|
||||
mod util;
|
18
frontend/rust-lib/flowy-ai/tests/text/completion_test.rs
Normal file
18
frontend/rust-lib/flowy-ai/tests/text/completion_test.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::util::get_openai_config;
|
||||
use async_openai::types::CreateCompletionRequestArgs;
|
||||
use flowy_ai::text::open_ai::OpenAITextCompletion;
|
||||
use flowy_ai::text::TextCompletion;
|
||||
|
||||
#[tokio::test]
|
||||
async fn text_completion_test() {
|
||||
if let Some(config) = get_openai_config() {
|
||||
let client = OpenAITextCompletion::new(&config.openai_api_key);
|
||||
let params = CreateCompletionRequestArgs::default()
|
||||
.model("text-davinci-003")
|
||||
.prompt("Write a rust function to calculate the sum of two numbers")
|
||||
.build()
|
||||
.unwrap();
|
||||
let resp = client.text_completion(params).await.unwrap();
|
||||
dbg!("{:?}", resp);
|
||||
}
|
||||
}
|
1
frontend/rust-lib/flowy-ai/tests/text/mod.rs
Normal file
1
frontend/rust-lib/flowy-ai/tests/text/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
mod completion_test;
|
8
frontend/rust-lib/flowy-ai/tests/util/mod.rs
Normal file
8
frontend/rust-lib/flowy-ai/tests/util/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use flowy_ai::config::OpenAISetting;
|
||||
|
||||
// To run the OpenAI test, you need to create a .env file in the flowy-ai folder.
|
||||
// Use the format: OPENAI_API_KEY=your_api_key
|
||||
pub fn get_openai_config() -> Option<OpenAISetting> {
|
||||
dotenv::from_filename(".env").ok()?;
|
||||
OpenAISetting::from_env().ok()
|
||||
}
|
@ -24,7 +24,7 @@ impl BoxAny {
|
||||
|
||||
pub fn unbox_or_error<T>(self) -> Result<T>
|
||||
where
|
||||
T: Default + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
match self.0.downcast::<T>() {
|
||||
Ok(value) => Ok(*value),
|
||||
@ -38,7 +38,7 @@ impl BoxAny {
|
||||
|
||||
pub fn unbox_or_none<T>(self) -> Option<T>
|
||||
where
|
||||
T: Default + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
match self.0.downcast::<T>() {
|
||||
Ok(value) => Some(*value),
|
||||
|
Loading…
Reference in New Issue
Block a user