mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: config chat
This commit is contained in:
parent
e4b1108ff0
commit
4c70ad9b9b
67
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
67
frontend/appflowy_tauri/src-tauri/Cargo.lock
generated
@ -172,7 +172,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "app-error"
|
name = "app-error"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -192,7 +192,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-ai-client"
|
name = "appflowy-ai-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -772,7 +772,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api"
|
name = "client-api"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"again",
|
"again",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -787,6 +787,7 @@ dependencies = [
|
|||||||
"collab",
|
"collab",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
"collab-rt-protocol",
|
"collab-rt-protocol",
|
||||||
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.10",
|
||||||
@ -794,6 +795,8 @@ dependencies = [
|
|||||||
"infra",
|
"infra",
|
||||||
"mime",
|
"mime",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"scraper 0.17.1",
|
"scraper 0.17.1",
|
||||||
@ -818,7 +821,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api-entity"
|
name = "client-api-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
@ -830,7 +833,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-websocket"
|
name = "client-websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -1070,7 +1073,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-entity"
|
name = "collab-rt-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -1095,7 +1098,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-protocol"
|
name = "collab-rt-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1291,12 +1294,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.16"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crunchy"
|
name = "crunchy"
|
||||||
@ -1452,10 +1452,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "database-entity"
|
name = "database-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
"appflowy-ai-client",
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
@ -1852,6 +1853,7 @@ dependencies = [
|
|||||||
"flowy-derive",
|
"flowy-derive",
|
||||||
"flowy-error",
|
"flowy-error",
|
||||||
"flowy-notification",
|
"flowy-notification",
|
||||||
|
"flowy-sidecar",
|
||||||
"flowy-sqlite",
|
"flowy-sqlite",
|
||||||
"futures",
|
"futures",
|
||||||
"lib-dispatch",
|
"lib-dispatch",
|
||||||
@ -2315,6 +2317,24 @@ dependencies = [
|
|||||||
"serde_repr",
|
"serde_repr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flowy-sidecar"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lib-infra",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flowy-sqlite"
|
name = "flowy-sqlite"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -2894,7 +2914,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue"
|
name = "gotrue"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -2911,7 +2931,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue-entity"
|
name = "gotrue-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
@ -3343,7 +3363,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "infra"
|
name = "infra"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -3591,6 +3611,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cfg-if",
|
||||||
"chrono",
|
"chrono",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -4211,9 +4232,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.18.0"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oneshot"
|
name = "oneshot"
|
||||||
@ -5685,9 +5706,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.111"
|
version = "1.0.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
|
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa 1.0.6",
|
"itoa 1.0.6",
|
||||||
"ryu",
|
"ryu",
|
||||||
@ -5835,7 +5856,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "shared-entity"
|
name = "shared-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
@ -6842,9 +6863,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.14"
|
version = "0.1.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
|
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -52,7 +52,7 @@ collab-user = { version = "0.2" }
|
|||||||
# Run the script:
|
# Run the script:
|
||||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||||
# ⚠️⚠️⚠️️
|
# ⚠️⚠️⚠️️
|
||||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6262816043efeede8823d7a7ea252083adf407e9" }
|
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9884d93aa2805013f36a79c1757174a0b5063065" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
29
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
29
frontend/appflowy_web/wasm-libs/Cargo.lock
generated
@ -215,7 +215,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "app-error"
|
name = "app-error"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -235,7 +235,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-ai-client"
|
name = "appflowy-ai-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -561,7 +561,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api"
|
name = "client-api"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"again",
|
"again",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -576,6 +576,7 @@ dependencies = [
|
|||||||
"collab",
|
"collab",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
"collab-rt-protocol",
|
"collab-rt-protocol",
|
||||||
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"getrandom 0.2.12",
|
"getrandom 0.2.12",
|
||||||
@ -583,6 +584,8 @@ dependencies = [
|
|||||||
"infra",
|
"infra",
|
||||||
"mime",
|
"mime",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"scraper 0.17.1",
|
"scraper 0.17.1",
|
||||||
@ -607,7 +610,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api-entity"
|
name = "client-api-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
@ -619,7 +622,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-websocket"
|
name = "client-websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -797,7 +800,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-entity"
|
name = "collab-rt-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -822,7 +825,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-protocol"
|
name = "collab-rt-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1036,10 +1039,11 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "database-entity"
|
name = "database-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
"appflowy-ai-client",
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
@ -1919,7 +1923,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue"
|
name = "gotrue"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -1936,7 +1940,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue-entity"
|
name = "gotrue-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
@ -2237,7 +2241,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "infra"
|
name = "infra"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -2378,6 +2382,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -3951,7 +3956,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "shared-entity"
|
name = "shared-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
@ -54,7 +54,7 @@ yrs = "0.18.8"
|
|||||||
# Run the script:
|
# Run the script:
|
||||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||||
# ⚠️⚠️⚠️️
|
# ⚠️⚠️⚠️️
|
||||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6262816043efeede8823d7a7ea252083adf407e9" }
|
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9884d93aa2805013f36a79c1757174a0b5063065" }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 0
|
opt-level = 0
|
||||||
|
56
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
56
frontend/appflowy_web_app/src-tauri/Cargo.lock
generated
@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "app-error"
|
name = "app-error"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -183,7 +183,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-ai-client"
|
name = "appflowy-ai-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -746,7 +746,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api"
|
name = "client-api"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"again",
|
"again",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -761,6 +761,7 @@ dependencies = [
|
|||||||
"collab",
|
"collab",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
"collab-rt-protocol",
|
"collab-rt-protocol",
|
||||||
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"getrandom 0.2.12",
|
"getrandom 0.2.12",
|
||||||
@ -768,6 +769,8 @@ dependencies = [
|
|||||||
"infra",
|
"infra",
|
||||||
"mime",
|
"mime",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"scraper 0.17.1",
|
"scraper 0.17.1",
|
||||||
@ -792,7 +795,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api-entity"
|
name = "client-api-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
@ -804,7 +807,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-websocket"
|
name = "client-websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -1053,7 +1056,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-entity"
|
name = "collab-rt-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -1078,7 +1081,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-protocol"
|
name = "collab-rt-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1281,9 +1284,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.19"
|
version = "0.8.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crunchy"
|
name = "crunchy"
|
||||||
@ -1439,10 +1442,11 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "database-entity"
|
name = "database-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
"appflowy-ai-client",
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
@ -1889,6 +1893,7 @@ dependencies = [
|
|||||||
"flowy-derive",
|
"flowy-derive",
|
||||||
"flowy-error",
|
"flowy-error",
|
||||||
"flowy-notification",
|
"flowy-notification",
|
||||||
|
"flowy-sidecar",
|
||||||
"flowy-sqlite",
|
"flowy-sqlite",
|
||||||
"futures",
|
"futures",
|
||||||
"lib-dispatch",
|
"lib-dispatch",
|
||||||
@ -2352,6 +2357,24 @@ dependencies = [
|
|||||||
"serde_repr",
|
"serde_repr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flowy-sidecar"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lib-infra",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flowy-sqlite"
|
name = "flowy-sqlite"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -2968,7 +2991,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue"
|
name = "gotrue"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -2985,7 +3008,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue-entity"
|
name = "gotrue-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
@ -3422,7 +3445,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "infra"
|
name = "infra"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -3675,6 +3698,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"atomic_refcell",
|
"atomic_refcell",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cfg-if",
|
||||||
"chrono",
|
"chrono",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -5777,9 +5801,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.114"
|
version = "1.0.118"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap 2.2.6",
|
"indexmap 2.2.6",
|
||||||
"itoa 1.0.10",
|
"itoa 1.0.10",
|
||||||
@ -5930,7 +5954,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "shared-entity"
|
name = "shared-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
@ -52,7 +52,7 @@ collab-user = { version = "0.2" }
|
|||||||
# Run the script:
|
# Run the script:
|
||||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||||
# ⚠️⚠️⚠️️
|
# ⚠️⚠️⚠️️
|
||||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6262816043efeede8823d7a7ea252083adf407e9" }
|
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9884d93aa2805013f36a79c1757174a0b5063065" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
38
frontend/rust-lib/Cargo.lock
generated
38
frontend/rust-lib/Cargo.lock
generated
@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "app-error"
|
name = "app-error"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -183,7 +183,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "appflowy-ai-client"
|
name = "appflowy-ai-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -664,7 +664,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api"
|
name = "client-api"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"again",
|
"again",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@ -679,6 +679,7 @@ dependencies = [
|
|||||||
"collab",
|
"collab",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
"collab-rt-protocol",
|
"collab-rt-protocol",
|
||||||
|
"futures",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.10",
|
||||||
@ -686,6 +687,8 @@ dependencies = [
|
|||||||
"infra",
|
"infra",
|
||||||
"mime",
|
"mime",
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"scraper 0.17.1",
|
"scraper 0.17.1",
|
||||||
@ -710,7 +713,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-api-entity"
|
name = "client-api-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
"collab-rt-entity",
|
"collab-rt-entity",
|
||||||
@ -722,7 +725,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "client-websocket"
|
name = "client-websocket"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -931,7 +934,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-entity"
|
name = "collab-rt-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
@ -956,7 +959,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "collab-rt-protocol"
|
name = "collab-rt-protocol"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -1273,10 +1276,11 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "database-entity"
|
name = "database-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
"appflowy-ai-client",
|
||||||
"bincode",
|
"bincode",
|
||||||
"chrono",
|
"chrono",
|
||||||
"collab-entity",
|
"collab-entity",
|
||||||
@ -1662,8 +1666,10 @@ name = "flowy-chat"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allo-isolate",
|
"allo-isolate",
|
||||||
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
|
"dotenv",
|
||||||
"flowy-chat-pub",
|
"flowy-chat-pub",
|
||||||
"flowy-codegen",
|
"flowy-codegen",
|
||||||
"flowy-derive",
|
"flowy-derive",
|
||||||
@ -1675,10 +1681,15 @@ dependencies = [
|
|||||||
"lib-dispatch",
|
"lib-dispatch",
|
||||||
"lib-infra",
|
"lib-infra",
|
||||||
"log",
|
"log",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
"protobuf",
|
"protobuf",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"strum_macros 0.21.1",
|
"strum_macros 0.21.1",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
"uuid",
|
"uuid",
|
||||||
"validator",
|
"validator",
|
||||||
]
|
]
|
||||||
@ -2147,7 +2158,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"dotenv",
|
|
||||||
"lib-infra",
|
"lib-infra",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -2158,8 +2168,6 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
|
||||||
"uuid",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2586,7 +2594,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue"
|
name = "gotrue"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -2603,7 +2611,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gotrue-entity"
|
name = "gotrue-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
@ -2968,7 +2976,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "infra"
|
name = "infra"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -5069,7 +5077,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "shared-entity"
|
name = "shared-entity"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=6262816043efeede8823d7a7ea252083adf407e9#6262816043efeede8823d7a7ea252083adf407e9"
|
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=9884d93aa2805013f36a79c1757174a0b5063065#9884d93aa2805013f36a79c1757174a0b5063065"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"app-error",
|
"app-error",
|
||||||
|
@ -99,8 +99,8 @@ validator = { version = "0.16.1", features = ["derive"] }
|
|||||||
# Run the script.add_workspace_members:
|
# Run the script.add_workspace_members:
|
||||||
# scripts/tool/update_client_api_rev.sh new_rev_id
|
# scripts/tool/update_client_api_rev.sh new_rev_id
|
||||||
# ⚠️⚠️⚠️️
|
# ⚠️⚠️⚠️️
|
||||||
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6262816043efeede8823d7a7ea252083adf407e9" }
|
client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9884d93aa2805013f36a79c1757174a0b5063065" }
|
||||||
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "6262816043efeede8823d7a7ea252083adf407e9" }
|
client-api-entity = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "9884d93aa2805013f36a79c1757174a0b5063065" }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
opt-level = 1
|
||||||
|
@ -5,7 +5,7 @@ use flowy_chat::entities::ChatMessageListPB;
|
|||||||
use flowy_chat::notification::ChatNotification;
|
use flowy_chat::notification::ChatNotification;
|
||||||
|
|
||||||
use flowy_chat_pub::cloud::ChatMessageType;
|
use flowy_chat_pub::cloud::ChatMessageType;
|
||||||
use futures_util::StreamExt;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@ -19,8 +19,8 @@ async fn af_cloud_create_chat_message_test() {
|
|||||||
let chat_id = view.id.clone();
|
let chat_id = view.id.clone();
|
||||||
let chat_service = test.server_provider.get_server().unwrap().chat_service();
|
let chat_service = test.server_provider.get_server().unwrap().chat_service();
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
let mut stream = chat_service
|
let _ = chat_service
|
||||||
.send_chat_message(
|
.save_question(
|
||||||
¤t_workspace.id,
|
¤t_workspace.id,
|
||||||
&chat_id,
|
&chat_id,
|
||||||
&format!("hello world {}", i),
|
&format!("hello world {}", i),
|
||||||
@ -28,9 +28,6 @@ async fn af_cloud_create_chat_message_test() {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
while let Some(message) = stream.next().await {
|
|
||||||
message.unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let rx = test
|
let rx = test
|
||||||
.notification_sender
|
.notification_sender
|
||||||
@ -77,8 +74,8 @@ async fn af_cloud_load_remote_system_message_test() {
|
|||||||
|
|
||||||
let chat_service = test.server_provider.get_server().unwrap().chat_service();
|
let chat_service = test.server_provider.get_server().unwrap().chat_service();
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
let mut stream = chat_service
|
let _ = chat_service
|
||||||
.send_chat_message(
|
.save_question(
|
||||||
¤t_workspace.id,
|
¤t_workspace.id,
|
||||||
&chat_id,
|
&chat_id,
|
||||||
&format!("hello server {}", i),
|
&format!("hello server {}", i),
|
||||||
@ -86,9 +83,6 @@ async fn af_cloud_load_remote_system_message_test() {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
while let Some(message) = stream.next().await {
|
|
||||||
message.unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let rx = test
|
let rx = test
|
||||||
|
@ -20,15 +20,7 @@ pub trait ChatCloudService: Send + Sync + 'static {
|
|||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
) -> FutureResult<(), FlowyError>;
|
) -> FutureResult<(), FlowyError>;
|
||||||
|
|
||||||
async fn send_chat_message(
|
fn save_question(
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
message: &str,
|
|
||||||
message_type: ChatMessageType,
|
|
||||||
) -> Result<ChatMessageStream, FlowyError>;
|
|
||||||
|
|
||||||
fn send_question(
|
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
@ -44,13 +36,20 @@ pub trait ChatCloudService: Send + Sync + 'static {
|
|||||||
question_id: i64,
|
question_id: i64,
|
||||||
) -> FutureResult<ChatMessage, FlowyError>;
|
) -> FutureResult<ChatMessage, FlowyError>;
|
||||||
|
|
||||||
async fn stream_answer(
|
async fn ask_question(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
message_id: i64,
|
message_id: i64,
|
||||||
) -> Result<StreamAnswer, FlowyError>;
|
) -> Result<StreamAnswer, FlowyError>;
|
||||||
|
|
||||||
|
fn generate_answer(
|
||||||
|
&self,
|
||||||
|
workspace_id: &str,
|
||||||
|
chat_id: &str,
|
||||||
|
question_message_id: i64,
|
||||||
|
) -> FutureResult<ChatMessage, FlowyError>;
|
||||||
|
|
||||||
fn get_chat_messages(
|
fn get_chat_messages(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
@ -65,11 +64,4 @@ pub trait ChatCloudService: Send + Sync + 'static {
|
|||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
message_id: i64,
|
message_id: i64,
|
||||||
) -> FutureResult<RepeatedRelatedQuestion, FlowyError>;
|
) -> FutureResult<RepeatedRelatedQuestion, FlowyError>;
|
||||||
|
|
||||||
fn generate_answer(
|
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
question_message_id: i64,
|
|
||||||
) -> FutureResult<ChatMessage, FlowyError>;
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,17 @@ futures.workspace = true
|
|||||||
allo-isolate = { version = "^0.1", features = ["catch-unwind"] }
|
allo-isolate = { version = "^0.1", features = ["catch-unwind"] }
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
flowy-sidecar = { workspace = true }
|
flowy-sidecar = { workspace = true }
|
||||||
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
anyhow = "1.0.86"
|
||||||
|
tokio-stream = "0.1.15"
|
||||||
|
parking_lot.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
uuid.workspace = true
|
||||||
|
tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
flowy-codegen.workspace = true
|
flowy-codegen.workspace = true
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
CHAT_BIN_PATH=
|
CHAT_BIN_PATH=
|
||||||
LOCAL_AI_ROOT_PATH=
|
LOCAL_AI_MODEL_DIR=
|
||||||
LOCAL_AI_CHAT_MODEL_NAME=
|
LOCAL_AI_CHAT_MODEL_NAME=
|
||||||
LOCAL_AI_EMBEDDING_MODEL_NAME=
|
LOCAL_AI_EMBEDDING_MODEL_NAME=
|
@ -93,7 +93,7 @@ impl Chat {
|
|||||||
|
|
||||||
let question = self
|
let question = self
|
||||||
.chat_service
|
.chat_service
|
||||||
.send_question(&workspace_id, &self.chat_id, message, message_type)
|
.save_question(&workspace_id, &self.chat_id, message, message_type)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
error!("Failed to send question: {}", err);
|
error!("Failed to send question: {}", err);
|
||||||
@ -114,7 +114,7 @@ impl Chat {
|
|||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut text_sink = IsolateSink::new(Isolate::new(text_stream_port));
|
let mut text_sink = IsolateSink::new(Isolate::new(text_stream_port));
|
||||||
match cloud_service
|
match cloud_service
|
||||||
.stream_answer(&workspace_id, &chat_id, question_id)
|
.ask_question(&workspace_id, &chat_id, question_id)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(mut stream) => {
|
Ok(mut stream) => {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::local_ai::manager::LocalAISetting;
|
||||||
use flowy_chat_pub::cloud::{
|
use flowy_chat_pub::cloud::{
|
||||||
ChatMessage, RelatedQuestion, RepeatedChatMessage, RepeatedRelatedQuestion,
|
ChatMessage, RelatedQuestion, RepeatedChatMessage, RepeatedRelatedQuestion,
|
||||||
};
|
};
|
||||||
@ -205,3 +206,40 @@ impl From<RepeatedRelatedQuestion> for RepeatedRelatedQuestionPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, ProtoBuf)]
|
||||||
|
pub struct LocalAIChatSettingPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub bin_dir: String,
|
||||||
|
|
||||||
|
#[pb(index = 2)]
|
||||||
|
pub chat_bin: String,
|
||||||
|
|
||||||
|
#[pb(index = 3)]
|
||||||
|
pub chat_model: String,
|
||||||
|
|
||||||
|
#[pb(index = 4)]
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LocalAISetting> for LocalAIChatSettingPB {
|
||||||
|
fn from(value: LocalAISetting) -> Self {
|
||||||
|
LocalAIChatSettingPB {
|
||||||
|
bin_dir: value.chat_bin,
|
||||||
|
chat_bin: value.bin_dir,
|
||||||
|
chat_model: value.chat_model,
|
||||||
|
enabled: value.enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LocalAIChatSettingPB> for LocalAISetting {
|
||||||
|
fn from(value: LocalAIChatSettingPB) -> Self {
|
||||||
|
LocalAISetting {
|
||||||
|
chat_bin: value.bin_dir,
|
||||||
|
bin_dir: value.chat_bin,
|
||||||
|
chat_model: value.chat_model,
|
||||||
|
enabled: value.enabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use flowy_chat_pub::cloud::ChatMessageType;
|
use flowy_chat_pub::cloud::ChatMessageType;
|
||||||
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
@ -110,3 +111,53 @@ pub(crate) async fn stop_stream_handler(
|
|||||||
chat_manager.stop_stream(&data.chat_id).await?;
|
chat_manager.stop_stream(&data.chat_id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
|
pub(crate) async fn get_local_ai_setting_handler(
|
||||||
|
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||||
|
) -> DataResult<LocalAIChatSettingPB, FlowyError> {
|
||||||
|
let chat_manager = upgrade_chat_manager(chat_manager)?;
|
||||||
|
let setting = chat_manager.get_local_ai_setting()?;
|
||||||
|
let pb = setting.into();
|
||||||
|
data_result_ok(pb)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
|
pub(crate) async fn update_local_ai_setting_handler(
|
||||||
|
data: AFPluginData<LocalAIChatSettingPB>,
|
||||||
|
chat_manager: AFPluginState<Weak<ChatManager>>,
|
||||||
|
) -> Result<(), FlowyError> {
|
||||||
|
let data = data.into_inner();
|
||||||
|
let chat_bin_path = Path::new(&data.bin_dir);
|
||||||
|
if !chat_bin_path.exists() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data()
|
||||||
|
.with_context(format!("Chat binary path does not exist: {}", data.bin_dir)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !chat_bin_path.is_file() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data()
|
||||||
|
.with_context(format!("Chat binary path is not a file: {}", data.bin_dir)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if local_model_dir exists and is a directory
|
||||||
|
let local_model_dir = Path::new(&data.chat_bin);
|
||||||
|
if !local_model_dir.exists() {
|
||||||
|
return Err(FlowyError::invalid_data().with_context(format!(
|
||||||
|
"Local model directory does not exist: {}",
|
||||||
|
data.chat_bin
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
if !local_model_dir.is_dir() {
|
||||||
|
return Err(FlowyError::invalid_data().with_context(format!(
|
||||||
|
"Local model directory is not a directory: {}",
|
||||||
|
data.chat_bin
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let chat_manager = upgrade_chat_manager(chat_manager)?;
|
||||||
|
chat_manager.update_local_ai_setting(data.into())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -18,6 +18,11 @@ pub fn init(chat_manager: Weak<ChatManager>) -> AFPlugin {
|
|||||||
.event(ChatEvent::GetRelatedQuestion, get_related_question_handler)
|
.event(ChatEvent::GetRelatedQuestion, get_related_question_handler)
|
||||||
.event(ChatEvent::GetAnswerForQuestion, get_answer_handler)
|
.event(ChatEvent::GetAnswerForQuestion, get_answer_handler)
|
||||||
.event(ChatEvent::StopStream, stop_stream_handler)
|
.event(ChatEvent::StopStream, stop_stream_handler)
|
||||||
|
.event(ChatEvent::GetLocalAISetting, get_local_ai_setting_handler)
|
||||||
|
.event(
|
||||||
|
ChatEvent::UpdateLocalAISetting,
|
||||||
|
update_local_ai_setting_handler,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Hash, ProtoBuf_Enum, Flowy_Event)]
|
||||||
@ -41,4 +46,10 @@ pub enum ChatEvent {
|
|||||||
|
|
||||||
#[event(input = "ChatMessageIdPB", output = "ChatMessagePB")]
|
#[event(input = "ChatMessageIdPB", output = "ChatMessagePB")]
|
||||||
GetAnswerForQuestion = 5,
|
GetAnswerForQuestion = 5,
|
||||||
|
|
||||||
|
#[event(input = "LocalAIChatSettingPB")]
|
||||||
|
UpdateLocalAISetting = 6,
|
||||||
|
|
||||||
|
#[event(output = "LocalAIChatSettingPB")]
|
||||||
|
GetLocalAISetting = 7,
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ pub mod event_map;
|
|||||||
|
|
||||||
mod chat;
|
mod chat;
|
||||||
pub mod entities;
|
pub mod entities;
|
||||||
|
pub mod local_ai;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
pub mod notification;
|
pub mod notification;
|
||||||
mod persistence;
|
mod persistence;
|
||||||
|
116
frontend/rust-lib/flowy-chat/src/local_ai/chat_plugin.rs
Normal file
116
frontend/rust-lib/flowy-chat/src/local_ai/chat_plugin.rs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
use anyhow::anyhow;
|
||||||
|
use flowy_error::FlowyError;
|
||||||
|
use flowy_sidecar::core::parser::ResponseParser;
|
||||||
|
use flowy_sidecar::core::plugin::{Plugin, PluginId};
|
||||||
|
use flowy_sidecar::error::{RemoteError, SidecarError};
|
||||||
|
use serde_json::json;
|
||||||
|
use serde_json::Value as JsonValue;
|
||||||
|
use std::sync::Weak;
|
||||||
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
|
|
||||||
|
pub struct ChatPluginOperation {
|
||||||
|
plugin: Weak<Plugin>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatPluginOperation {
|
||||||
|
pub fn new(plugin: Weak<Plugin>) -> Self {
|
||||||
|
ChatPluginOperation { plugin }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_message(
|
||||||
|
&self,
|
||||||
|
chat_id: &str,
|
||||||
|
_plugin_id: PluginId,
|
||||||
|
message: &str,
|
||||||
|
) -> Result<String, SidecarError> {
|
||||||
|
let plugin = self
|
||||||
|
.plugin
|
||||||
|
.upgrade()
|
||||||
|
.ok_or(SidecarError::Internal(anyhow!("Plugin is dropped")))?;
|
||||||
|
|
||||||
|
let params = json!({"chat_id": chat_id, "method": "answer", "params": {"content": message}});
|
||||||
|
let resp = plugin
|
||||||
|
.async_request::<ChatResponseParser>("handle", ¶ms)
|
||||||
|
.await?;
|
||||||
|
Ok(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn stream_message(
|
||||||
|
&self,
|
||||||
|
chat_id: &str,
|
||||||
|
_plugin_id: PluginId,
|
||||||
|
message: &str,
|
||||||
|
) -> Result<ReceiverStream<Result<String, SidecarError>>, FlowyError> {
|
||||||
|
let plugin = self
|
||||||
|
.plugin
|
||||||
|
.upgrade()
|
||||||
|
.ok_or(FlowyError::internal().with_context("Plugin is dropped"))?;
|
||||||
|
|
||||||
|
let params =
|
||||||
|
json!({"chat_id": chat_id, "method": "stream_answer", "params": {"content": message}});
|
||||||
|
let stream = plugin
|
||||||
|
.stream_request::<ChatStreamResponseParser>("handle", ¶ms)
|
||||||
|
.map_err(|err| FlowyError::internal().with_context(err.to_string()))?;
|
||||||
|
Ok(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_related_questions(
|
||||||
|
&self,
|
||||||
|
chat_id: &str,
|
||||||
|
) -> Result<Vec<serde_json::Value>, SidecarError> {
|
||||||
|
let plugin = self
|
||||||
|
.plugin
|
||||||
|
.upgrade()
|
||||||
|
.ok_or(SidecarError::Internal(anyhow!("Plugin is dropped")))?;
|
||||||
|
|
||||||
|
let params = json!({"chat_id": chat_id, "method": "related_question"});
|
||||||
|
let resp = plugin
|
||||||
|
.async_request::<ChatRelatedQuestionsResponseParser>("handle", ¶ms)
|
||||||
|
.await?;
|
||||||
|
Ok(resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ChatResponseParser;
|
||||||
|
impl ResponseParser for ChatResponseParser {
|
||||||
|
type ValueType = String;
|
||||||
|
|
||||||
|
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
||||||
|
if json.is_object() {
|
||||||
|
if let Some(data) = json.get("data") {
|
||||||
|
if let Some(message) = data.as_str() {
|
||||||
|
return Ok(message.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(RemoteError::ParseResponse(json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ChatStreamResponseParser;
|
||||||
|
impl ResponseParser for ChatStreamResponseParser {
|
||||||
|
type ValueType = String;
|
||||||
|
|
||||||
|
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
||||||
|
if let Some(message) = json.as_str() {
|
||||||
|
return Ok(message.to_string());
|
||||||
|
}
|
||||||
|
return Err(RemoteError::ParseResponse(json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ChatRelatedQuestionsResponseParser;
|
||||||
|
impl ResponseParser for ChatRelatedQuestionsResponseParser {
|
||||||
|
type ValueType = Vec<JsonValue>;
|
||||||
|
|
||||||
|
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
||||||
|
if json.is_object() {
|
||||||
|
if let Some(data) = json.get("data") {
|
||||||
|
if let Some(values) = data.as_array() {
|
||||||
|
return Ok(values.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Err(RemoteError::ParseResponse(json));
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
use crate::core::parser::SimilarityResponseParser;
|
|
||||||
use crate::core::plugin::Plugin;
|
|
||||||
use crate::error::SidecarError;
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use flowy_sidecar::core::parser::ResponseParser;
|
||||||
|
use flowy_sidecar::core::plugin::Plugin;
|
||||||
|
use flowy_sidecar::error::{RemoteError, SidecarError};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use serde_json::Value as JsonValue;
|
||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
pub struct EmbeddingPluginOperation {
|
pub struct EmbeddingPluginOperation {
|
||||||
@ -30,3 +31,20 @@ impl EmbeddingPluginOperation {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SimilarityResponseParser;
|
||||||
|
impl ResponseParser for SimilarityResponseParser {
|
||||||
|
type ValueType = f64;
|
||||||
|
|
||||||
|
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
||||||
|
if json.is_object() {
|
||||||
|
if let Some(data) = json.get("data") {
|
||||||
|
if let Some(score) = data.get("score").and_then(|v| v.as_f64()) {
|
||||||
|
return Ok(score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(RemoteError::ParseResponse(json));
|
||||||
|
}
|
||||||
|
}
|
176
frontend/rust-lib/flowy-chat/src/local_ai/manager.rs
Normal file
176
frontend/rust-lib/flowy-chat/src/local_ai/manager.rs
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
use crate::local_ai::chat_plugin::ChatPluginOperation;
|
||||||
|
use dashmap::DashMap;
|
||||||
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
|
use flowy_sidecar::core::plugin::{PluginId, PluginInfo};
|
||||||
|
use flowy_sidecar::error::SidecarError;
|
||||||
|
use flowy_sidecar::manager::SidecarManager;
|
||||||
|
use log::error;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
|
use tracing::trace;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct LocalAISetting {
|
||||||
|
pub bin_dir: String,
|
||||||
|
pub chat_bin: String,
|
||||||
|
pub chat_model: String,
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalAISetting {
|
||||||
|
pub fn validate(&self) -> FlowyResult<()> {
|
||||||
|
ChatPluginConfig::new(&self.bin_dir, &self.chat_bin, &self.chat_model)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn get_chat_plugin_config(&self) -> FlowyResult<ChatPluginConfig> {
|
||||||
|
let config = ChatPluginConfig::new(&self.bin_dir, &self.chat_bin, &self.chat_model)?;
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LocalAIManager {
|
||||||
|
sidecar_manager: Arc<SidecarManager>,
|
||||||
|
chat_plugin_config: RwLock<Option<ChatPluginConfig>>,
|
||||||
|
plugin_map: DashMap<PathBuf, PluginId>,
|
||||||
|
chat_plugin_id: RwLock<Option<PluginId>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalAIManager {
|
||||||
|
pub fn new(sidecar_manager: Arc<SidecarManager>) -> Self {
|
||||||
|
Self {
|
||||||
|
sidecar_manager,
|
||||||
|
chat_plugin_config: RwLock::new(None),
|
||||||
|
plugin_map: Default::default(),
|
||||||
|
chat_plugin_id: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn stream_chat_message(
|
||||||
|
&self,
|
||||||
|
chat_id: &str,
|
||||||
|
message: &str,
|
||||||
|
) -> FlowyResult<ReceiverStream<anyhow::Result<String, SidecarError>>> {
|
||||||
|
let plugin_id = self
|
||||||
|
.chat_plugin_id
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.ok_or_else(|| FlowyError::internal().with_context("chat plugin not set"))?;
|
||||||
|
|
||||||
|
let plugin = self
|
||||||
|
.sidecar_manager
|
||||||
|
.get_plugin(plugin_id)
|
||||||
|
.await
|
||||||
|
.map_err(|err| FlowyError::internal().with_context(err.to_string()))?;
|
||||||
|
|
||||||
|
let operation = ChatPluginOperation::new(plugin);
|
||||||
|
let stream = operation
|
||||||
|
.stream_message(chat_id, plugin_id, message)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn setup_chat_plugin(&self, config: ChatPluginConfig) -> FlowyResult<()> {
|
||||||
|
// If the chat_bin_path is different, remove the old plugin
|
||||||
|
if let Some(chat_plugin_config) = self.chat_plugin_config.read().await.as_ref() {
|
||||||
|
if chat_plugin_config.chat_bin_path != config.chat_bin_path {
|
||||||
|
trace!("remove old plugin: {:?}", chat_plugin_config.chat_bin_path);
|
||||||
|
if let Some(entry) = self.plugin_map.remove(&chat_plugin_config.chat_bin_path) {
|
||||||
|
if let Err(err) = self.sidecar_manager.remove_plugin(entry.1).await {
|
||||||
|
error!("remove plugin failed: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new plugin
|
||||||
|
let plugin_info = PluginInfo {
|
||||||
|
name: "chat_plugin".to_string(),
|
||||||
|
exec_path: config.chat_bin_path.clone(),
|
||||||
|
};
|
||||||
|
let plugin = self
|
||||||
|
.sidecar_manager
|
||||||
|
.create_plugin(plugin_info)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// init plugin
|
||||||
|
let model_path = config.chat_model_path;
|
||||||
|
self
|
||||||
|
.sidecar_manager
|
||||||
|
.init_plugin(
|
||||||
|
plugin,
|
||||||
|
serde_json::json!({
|
||||||
|
"absolute_chat_model_path": model_path,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.map_err(|err| FlowyError::internal().with_context(err.to_string()))?;
|
||||||
|
|
||||||
|
self.chat_plugin_id.write().await.replace(plugin);
|
||||||
|
self.plugin_map.insert(config.chat_bin_path, plugin);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ChatPluginConfig {
|
||||||
|
bin_dir: PathBuf,
|
||||||
|
chat_bin_path: PathBuf,
|
||||||
|
chat_model_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatPluginConfig {
|
||||||
|
pub fn new(bin_dir: &str, chat_bin: &str, chat_model_name: &str) -> FlowyResult<Self> {
|
||||||
|
// check bin_dir exists and is a directory
|
||||||
|
let bin_dir = PathBuf::from(bin_dir);
|
||||||
|
if !bin_dir.exists() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data().with_context(format!("bin path not exists: {:?}", bin_dir)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !bin_dir.is_dir() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data()
|
||||||
|
.with_context(format!("bin path is not directory: {:?}", bin_dir)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let chat_bin_path = bin_dir.join(chat_bin);
|
||||||
|
if !chat_bin_path.exists() {
|
||||||
|
return Err(FlowyError::invalid_data().with_context(format!(
|
||||||
|
"Chat binary path does not exist: {:?}",
|
||||||
|
chat_bin_path
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
if !chat_bin_path.is_file() {
|
||||||
|
return Err(FlowyError::invalid_data().with_context(format!(
|
||||||
|
"Chat binary path is not a file: {:?}",
|
||||||
|
chat_bin_path
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if local_model_dir exists and is a directory
|
||||||
|
let chat_model_path = bin_dir.join(&chat_model_name);
|
||||||
|
if !chat_model_path.exists() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data()
|
||||||
|
.with_context(format!("Local model does not exist: {:?}", chat_model_path)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !chat_model_path.is_file() {
|
||||||
|
return Err(
|
||||||
|
FlowyError::invalid_data()
|
||||||
|
.with_context(format!("Local model is not a file: {:?}", chat_model_path)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
bin_dir,
|
||||||
|
chat_bin_path,
|
||||||
|
chat_model_path,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,2 +1,4 @@
|
|||||||
pub mod chat_plugin;
|
pub mod chat_plugin;
|
||||||
|
pub mod manager;
|
||||||
|
|
||||||
pub mod embedding_plugin;
|
pub mod embedding_plugin;
|
@ -3,8 +3,8 @@ use crate::entities::{ChatMessageListPB, ChatMessagePB, RepeatedRelatedQuestionP
|
|||||||
use crate::persistence::{insert_chat, ChatTable};
|
use crate::persistence::{insert_chat, ChatTable};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use flowy_chat_pub::cloud::{
|
use flowy_chat_pub::cloud::{
|
||||||
ChatCloudService, ChatMessage, ChatMessageStream, ChatMessageType, MessageCursor,
|
ChatCloudService, ChatMessage, ChatMessageType, MessageCursor, RepeatedChatMessage,
|
||||||
RepeatedChatMessage, RepeatedRelatedQuestion, StreamAnswer,
|
RepeatedRelatedQuestion, StreamAnswer,
|
||||||
};
|
};
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_sidecar::manager::SidecarManager;
|
use flowy_sidecar::manager::SidecarManager;
|
||||||
@ -12,8 +12,13 @@ use flowy_sqlite::DBConnection;
|
|||||||
use lib_infra::future::FutureResult;
|
use lib_infra::future::FutureResult;
|
||||||
use lib_infra::util::timestamp;
|
use lib_infra::util::timestamp;
|
||||||
|
|
||||||
|
use crate::local_ai::manager::{LocalAIManager, LocalAISetting};
|
||||||
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
|
use lib_infra::async_trait::async_trait;
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::trace;
|
use tracing::{error, info, trace};
|
||||||
|
|
||||||
pub trait ChatUserService: Send + Sync + 'static {
|
pub trait ChatUserService: Send + Sync + 'static {
|
||||||
fn user_id(&self) -> Result<i64, FlowyError>;
|
fn user_id(&self) -> Result<i64, FlowyError>;
|
||||||
@ -26,24 +31,56 @@ pub struct ChatManager {
|
|||||||
chat_service: Arc<ChatService>,
|
chat_service: Arc<ChatService>,
|
||||||
user_service: Arc<dyn ChatUserService>,
|
user_service: Arc<dyn ChatUserService>,
|
||||||
chats: Arc<DashMap<String, Arc<Chat>>>,
|
chats: Arc<DashMap<String, Arc<Chat>>>,
|
||||||
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LOCAL_AI_SETTING_KEY: &str = "local_ai_setting";
|
||||||
impl ChatManager {
|
impl ChatManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
cloud_service: Arc<dyn ChatCloudService>,
|
cloud_service: Arc<dyn ChatCloudService>,
|
||||||
user_service: impl ChatUserService,
|
user_service: impl ChatUserService,
|
||||||
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
) -> ChatManager {
|
) -> ChatManager {
|
||||||
|
let local_ai_setting = store_preferences
|
||||||
|
.get_object::<LocalAISetting>(LOCAL_AI_SETTING_KEY)
|
||||||
|
.unwrap_or_default();
|
||||||
let sidecar_manager = Arc::new(SidecarManager::new());
|
let sidecar_manager = Arc::new(SidecarManager::new());
|
||||||
let chat_service = Arc::new(ChatService::new(cloud_service, sidecar_manager));
|
|
||||||
|
// Setup local AI chat plugin
|
||||||
|
let local_ai_manager = Arc::new(LocalAIManager::new(sidecar_manager));
|
||||||
|
setup_local_ai(&local_ai_setting, local_ai_manager.clone());
|
||||||
|
|
||||||
|
//
|
||||||
|
let chat_service = Arc::new(ChatService::new(
|
||||||
|
cloud_service,
|
||||||
|
local_ai_manager,
|
||||||
|
local_ai_setting,
|
||||||
|
));
|
||||||
let user_service = Arc::new(user_service);
|
let user_service = Arc::new(user_service);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
chat_service,
|
chat_service,
|
||||||
user_service,
|
user_service,
|
||||||
chats: Arc::new(DashMap::new()),
|
chats: Arc::new(DashMap::new()),
|
||||||
|
store_preferences,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_local_ai_setting(&self, setting: LocalAISetting) -> FlowyResult<()> {
|
||||||
|
setting.validate()?;
|
||||||
|
|
||||||
|
self
|
||||||
|
.store_preferences
|
||||||
|
.set_object(LOCAL_AI_SETTING_KEY, setting.clone())?;
|
||||||
|
*self.chat_service.local_ai_setting.write() = setting;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_local_ai_setting(&self) -> FlowyResult<LocalAISetting> {
|
||||||
|
let setting = self.chat_service.local_ai_setting.read().clone();
|
||||||
|
Ok(setting)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn open_chat(&self, chat_id: &str) -> Result<(), FlowyError> {
|
pub async fn open_chat(&self, chat_id: &str) -> Result<(), FlowyError> {
|
||||||
trace!("open chat: {}", chat_id);
|
trace!("open chat: {}", chat_id);
|
||||||
self.chats.entry(chat_id.to_string()).or_insert_with(|| {
|
self.chats.entry(chat_id.to_string()).or_insert_with(|| {
|
||||||
@ -186,6 +223,21 @@ impl ChatManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_local_ai(local_ai_setting: &LocalAISetting, local_ai_manager: Arc<LocalAIManager>) {
|
||||||
|
if let Ok(config) = local_ai_setting.get_chat_plugin_config() {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
match local_ai_manager.setup_chat_plugin(config).await {
|
||||||
|
Ok(_) => {
|
||||||
|
info!("Local AI chat plugin setup successfully");
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to setup local AI chat plugin: {:?}", err);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn save_chat(conn: DBConnection, chat_id: &str) -> FlowyResult<()> {
|
fn save_chat(conn: DBConnection, chat_id: &str) -> FlowyResult<()> {
|
||||||
let row = ChatTable {
|
let row = ChatTable {
|
||||||
chat_id: chat_id.to_string(),
|
chat_id: chat_id.to_string(),
|
||||||
@ -203,21 +255,25 @@ fn save_chat(conn: DBConnection, chat_id: &str) -> FlowyResult<()> {
|
|||||||
|
|
||||||
pub struct ChatService {
|
pub struct ChatService {
|
||||||
cloud_service: Arc<dyn ChatCloudService>,
|
cloud_service: Arc<dyn ChatCloudService>,
|
||||||
sidecar_manager: Arc<SidecarManager>,
|
local_ai_manager: Arc<LocalAIManager>,
|
||||||
|
local_ai_setting: Arc<RwLock<LocalAISetting>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatService {
|
impl ChatService {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
cloud_service: Arc<dyn ChatCloudService>,
|
cloud_service: Arc<dyn ChatCloudService>,
|
||||||
sidecar_manager: Arc<SidecarManager>,
|
local_ai_manager: Arc<LocalAIManager>,
|
||||||
|
local_ai_setting: LocalAISetting,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cloud_service,
|
cloud_service,
|
||||||
sidecar_manager,
|
local_ai_manager,
|
||||||
|
local_ai_setting: Arc::new(RwLock::new(local_ai_setting)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
impl ChatCloudService for ChatService {
|
impl ChatCloudService for ChatService {
|
||||||
fn create_chat(
|
fn create_chat(
|
||||||
&self,
|
&self,
|
||||||
@ -228,27 +284,16 @@ impl ChatCloudService for ChatService {
|
|||||||
self.cloud_service.create_chat(uid, workspace_id, chat_id)
|
self.cloud_service.create_chat(uid, workspace_id, chat_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_chat_message(
|
fn save_question(
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
message: &str,
|
|
||||||
message_type: ChatMessageType,
|
|
||||||
) -> Result<ChatMessageStream, FlowyError> {
|
|
||||||
self
|
|
||||||
.cloud_service
|
|
||||||
.send_chat_message(workspace_id, chat_id, message, message_type)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_question(
|
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
message: &str,
|
message: &str,
|
||||||
message_type: ChatMessageType,
|
message_type: ChatMessageType,
|
||||||
) -> FutureResult<ChatMessage, FlowyError> {
|
) -> FutureResult<ChatMessage, FlowyError> {
|
||||||
todo!()
|
self
|
||||||
|
.cloud_service
|
||||||
|
.save_question(workspace_id, chat_id, message, message_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_answer(
|
fn save_answer(
|
||||||
@ -258,16 +303,41 @@ impl ChatCloudService for ChatService {
|
|||||||
message: &str,
|
message: &str,
|
||||||
question_id: i64,
|
question_id: i64,
|
||||||
) -> FutureResult<ChatMessage, FlowyError> {
|
) -> FutureResult<ChatMessage, FlowyError> {
|
||||||
todo!()
|
self
|
||||||
|
.cloud_service
|
||||||
|
.save_answer(workspace_id, chat_id, message, question_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stream_answer(
|
async fn ask_question(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: &str,
|
workspace_id: &str,
|
||||||
_chat_id: &str,
|
chat_id: &str,
|
||||||
_message_id: i64,
|
message_id: i64,
|
||||||
) -> Result<StreamAnswer, FlowyError> {
|
) -> Result<StreamAnswer, FlowyError> {
|
||||||
|
if self.local_ai_setting.read().enabled {
|
||||||
|
// self.local_ai_manager.stream_chat_message(chat_id, "", message_id).await
|
||||||
todo!()
|
todo!()
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
.cloud_service
|
||||||
|
.ask_question(workspace_id, chat_id, message_id)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_answer(
|
||||||
|
&self,
|
||||||
|
workspace_id: &str,
|
||||||
|
chat_id: &str,
|
||||||
|
question_message_id: i64,
|
||||||
|
) -> FutureResult<ChatMessage, FlowyError> {
|
||||||
|
if self.local_ai_setting.read().enabled {
|
||||||
|
todo!()
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
.cloud_service
|
||||||
|
.generate_answer(workspace_id, chat_id, question_message_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_chat_messages(
|
fn get_chat_messages(
|
||||||
@ -277,13 +347,9 @@ impl ChatCloudService for ChatService {
|
|||||||
offset: MessageCursor,
|
offset: MessageCursor,
|
||||||
limit: u64,
|
limit: u64,
|
||||||
) -> FutureResult<RepeatedChatMessage, FlowyError> {
|
) -> FutureResult<RepeatedChatMessage, FlowyError> {
|
||||||
FutureResult::new(async move {
|
self
|
||||||
Ok(RepeatedChatMessage {
|
.cloud_service
|
||||||
messages: vec![],
|
.get_chat_messages(workspace_id, chat_id, offset, limit)
|
||||||
has_more: false,
|
|
||||||
total: 0,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_related_message(
|
fn get_related_message(
|
||||||
@ -292,20 +358,17 @@ impl ChatCloudService for ChatService {
|
|||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
message_id: i64,
|
message_id: i64,
|
||||||
) -> FutureResult<RepeatedRelatedQuestion, FlowyError> {
|
) -> FutureResult<RepeatedRelatedQuestion, FlowyError> {
|
||||||
|
if self.local_ai_setting.read().enabled {
|
||||||
FutureResult::new(async move {
|
FutureResult::new(async move {
|
||||||
Ok(RepeatedRelatedQuestion {
|
Ok(RepeatedRelatedQuestion {
|
||||||
message_id,
|
message_id,
|
||||||
items: vec![],
|
items: vec![],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
|
self
|
||||||
fn generate_answer(
|
.cloud_service
|
||||||
&self,
|
.get_related_message(workspace_id, chat_id, message_id)
|
||||||
workspace_id: &str,
|
}
|
||||||
chat_id: &str,
|
|
||||||
question_message_id: i64,
|
|
||||||
) -> FutureResult<ChatMessage, FlowyError> {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,18 +29,13 @@ async fn stream_local_model_test() {
|
|||||||
let mut resp = test
|
let mut resp = test
|
||||||
.stream_chat_message(&chat_id, plugin_id, "hello world")
|
.stream_chat_message(&chat_id, plugin_id, "hello world")
|
||||||
.await;
|
.await;
|
||||||
let a = resp.next().await.unwrap().unwrap();
|
let mut list = vec![];
|
||||||
eprintln!("chat response: {:?}", a);
|
while let Some(s) = resp.next().await {
|
||||||
|
list.push(s.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let answer = list.join("");
|
||||||
|
eprintln!("chat response: {:?}", answer);
|
||||||
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
|
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
|
||||||
|
|
||||||
// let mut resp = test
|
|
||||||
// .stream_chat_message(&chat_id, plugin_id, "How are you")
|
|
||||||
// .await;
|
|
||||||
// let a = resp.next().await.unwrap().unwrap();
|
|
||||||
// eprintln!("chat response: {:?}", a);
|
|
||||||
// let questions = test.related_question(&chat_id, plugin_id).await;
|
|
||||||
// assert_eq!(questions.len(), 3);
|
|
||||||
// eprintln!("related questions: {:?}", questions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use flowy_sidecar::manager::SidecarManager;
|
use flowy_sidecar::manager::SidecarManager;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use tokio_stream::wrappers::ReceiverStream;
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
use tokio_stream::Stream;
|
|
||||||
|
|
||||||
|
use flowy_chat::local_ai::chat_plugin::ChatPluginOperation;
|
||||||
|
use flowy_chat::local_ai::embedding_plugin::EmbeddingPluginOperation;
|
||||||
use flowy_sidecar::core::plugin::{PluginId, PluginInfo};
|
use flowy_sidecar::core::plugin::{PluginId, PluginInfo};
|
||||||
use flowy_sidecar::error::SidecarError;
|
use flowy_sidecar::error::SidecarError;
|
||||||
use flowy_sidecar::plugins::chat_plugin::ChatPluginOperation;
|
|
||||||
use flowy_sidecar::plugins::embedding_plugin::EmbeddingPluginOperation;
|
|
||||||
use tracing_subscriber::fmt::Subscriber;
|
use tracing_subscriber::fmt::Subscriber;
|
||||||
use tracing_subscriber::util::SubscriberInitExt;
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
@ -120,10 +120,10 @@ impl LocalAITest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct LocalAIConfiguration {
|
pub struct LocalAIConfiguration {
|
||||||
root: String,
|
model_dir: String,
|
||||||
chat_bin_path: String,
|
chat_bin_path: PathBuf,
|
||||||
chat_model_name: String,
|
chat_model_name: String,
|
||||||
embedding_bin_path: String,
|
embedding_bin_path: PathBuf,
|
||||||
embedding_model_name: String,
|
embedding_model_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,15 +133,15 @@ impl LocalAIConfiguration {
|
|||||||
setup_log();
|
setup_log();
|
||||||
|
|
||||||
// load from .env
|
// load from .env
|
||||||
let root = dotenv::var("LOCAL_AI_ROOT_PATH")?;
|
let model_dir = dotenv::var("LOCAL_AI_MODEL_DIR")?;
|
||||||
let chat_bin_path = dotenv::var("CHAT_BIN_PATH")?;
|
let chat_bin_path = PathBuf::from(dotenv::var("CHAT_BIN_PATH")?);
|
||||||
let chat_model_name = dotenv::var("LOCAL_AI_CHAT_MODEL_NAME")?;
|
let chat_model_name = dotenv::var("LOCAL_AI_CHAT_MODEL_NAME")?;
|
||||||
|
|
||||||
let embedding_bin_path = dotenv::var("EMBEDDING_BIN_PATH")?;
|
let embedding_bin_path = PathBuf::from(dotenv::var("EMBEDDING_BIN_PATH")?);
|
||||||
let embedding_model_name = dotenv::var("LOCAL_AI_EMBEDDING_MODEL_NAME")?;
|
let embedding_model_name = dotenv::var("LOCAL_AI_EMBEDDING_MODEL_NAME")?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
root,
|
model_dir,
|
||||||
chat_bin_path,
|
chat_bin_path,
|
||||||
chat_model_name,
|
chat_model_name,
|
||||||
embedding_bin_path,
|
embedding_bin_path,
|
||||||
@ -150,11 +150,11 @@ impl LocalAIConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn chat_model_absolute_path(&self) -> String {
|
pub fn chat_model_absolute_path(&self) -> String {
|
||||||
format!("{}/{}", self.root, self.chat_model_name)
|
format!("{}/{}", self.model_dir, self.chat_model_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn embedding_model_absolute_path(&self) -> String {
|
pub fn embedding_model_absolute_path(&self) -> String {
|
||||||
format!("{}/{}", self.root, self.embedding_model_name)
|
format!("{}/{}", self.model_dir, self.embedding_model_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
|
|
||||||
use flowy_error::{FlowyError, FlowyResult};
|
use flowy_error::{FlowyError, FlowyResult};
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
|
use lib_dispatch::prelude::{data_result_ok, AFPluginData, AFPluginState, DataResult};
|
||||||
|
|
||||||
use crate::entities::{KeyPB, KeyValuePB};
|
use crate::entities::{KeyPB, KeyValuePB};
|
||||||
|
|
||||||
pub(crate) async fn set_key_value_handler(
|
pub(crate) async fn set_key_value_handler(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<KeyValuePB>,
|
data: AFPluginData<KeyValuePB>,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
let data = data.into_inner();
|
let data = data.into_inner();
|
||||||
@ -25,7 +25,7 @@ pub(crate) async fn set_key_value_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_key_value_handler(
|
pub(crate) async fn get_key_value_handler(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<KeyPB>,
|
data: AFPluginData<KeyPB>,
|
||||||
) -> DataResult<KeyValuePB, FlowyError> {
|
) -> DataResult<KeyValuePB, FlowyError> {
|
||||||
match store_preferences.upgrade() {
|
match store_preferences.upgrade() {
|
||||||
@ -42,7 +42,7 @@ pub(crate) async fn get_key_value_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn remove_key_value_handler(
|
pub(crate) async fn remove_key_value_handler(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<KeyPB>,
|
data: AFPluginData<KeyPB>,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
match store_preferences.upgrade() {
|
match store_preferences.upgrade() {
|
||||||
|
@ -3,12 +3,12 @@ use std::sync::Weak;
|
|||||||
use strum_macros::Display;
|
use strum_macros::Display;
|
||||||
|
|
||||||
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
use flowy_derive::{Flowy_Event, ProtoBuf_Enum};
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use lib_dispatch::prelude::AFPlugin;
|
use lib_dispatch::prelude::AFPlugin;
|
||||||
|
|
||||||
use crate::event_handler::*;
|
use crate::event_handler::*;
|
||||||
|
|
||||||
pub fn init(store_preferences: Weak<StorePreferences>) -> AFPlugin {
|
pub fn init(store_preferences: Weak<KVStorePreferences>) -> AFPlugin {
|
||||||
AFPlugin::new()
|
AFPlugin::new()
|
||||||
.name(env!("CARGO_PKG_NAME"))
|
.name(env!("CARGO_PKG_NAME"))
|
||||||
.state(store_preferences)
|
.state(store_preferences)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use flowy_chat::manager::{ChatManager, ChatUserService};
|
use flowy_chat::manager::{ChatManager, ChatUserService};
|
||||||
use flowy_chat_pub::cloud::ChatCloudService;
|
use flowy_chat_pub::cloud::ChatCloudService;
|
||||||
use flowy_error::FlowyError;
|
use flowy_error::FlowyError;
|
||||||
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_sqlite::DBConnection;
|
use flowy_sqlite::DBConnection;
|
||||||
use flowy_user::services::authenticate_user::AuthenticateUser;
|
use flowy_user::services::authenticate_user::AuthenticateUser;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
@ -11,9 +12,14 @@ impl ChatDepsResolver {
|
|||||||
pub fn resolve(
|
pub fn resolve(
|
||||||
authenticate_user: Weak<AuthenticateUser>,
|
authenticate_user: Weak<AuthenticateUser>,
|
||||||
cloud_service: Arc<dyn ChatCloudService>,
|
cloud_service: Arc<dyn ChatCloudService>,
|
||||||
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
) -> Arc<ChatManager> {
|
) -> Arc<ChatManager> {
|
||||||
let user_service = ChatUserServiceImpl(authenticate_user);
|
let user_service = ChatUserServiceImpl(authenticate_user);
|
||||||
Arc::new(ChatManager::new(cloud_service, user_service))
|
Arc::new(ChatManager::new(
|
||||||
|
cloud_service,
|
||||||
|
user_service,
|
||||||
|
store_preferences,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use flowy_folder::view_operation::{
|
|||||||
use flowy_folder::ViewLayout;
|
use flowy_folder::ViewLayout;
|
||||||
use flowy_folder_pub::folder_builder::NestedViewBuilder;
|
use flowy_folder_pub::folder_builder::NestedViewBuilder;
|
||||||
use flowy_search::folder::indexer::FolderIndexManagerImpl;
|
use flowy_search::folder::indexer::FolderIndexManagerImpl;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user::services::authenticate_user::AuthenticateUser;
|
use flowy_user::services::authenticate_user::AuthenticateUser;
|
||||||
use lib_dispatch::prelude::ToBytes;
|
use lib_dispatch::prelude::ToBytes;
|
||||||
use lib_infra::future::FutureResult;
|
use lib_infra::future::FutureResult;
|
||||||
@ -37,7 +37,7 @@ impl FolderDepsResolver {
|
|||||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||||
server_provider: Arc<ServerProvider>,
|
server_provider: Arc<ServerProvider>,
|
||||||
folder_indexer: Arc<FolderIndexManagerImpl>,
|
folder_indexer: Arc<FolderIndexManagerImpl>,
|
||||||
store_preferences: Arc<StorePreferences>,
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
operation_handlers: FolderOperationHandlers,
|
operation_handlers: FolderOperationHandlers,
|
||||||
) -> Arc<FolderManager> {
|
) -> Arc<FolderManager> {
|
||||||
let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl {
|
let user: Arc<dyn FolderUser> = Arc::new(FolderUserImpl {
|
||||||
|
@ -4,7 +4,7 @@ use flowy_database2::DatabaseManager;
|
|||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_folder::manager::FolderManager;
|
use flowy_folder::manager::FolderManager;
|
||||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user::services::authenticate_user::AuthenticateUser;
|
use flowy_user::services::authenticate_user::AuthenticateUser;
|
||||||
use flowy_user::user_manager::UserManager;
|
use flowy_user::user_manager::UserManager;
|
||||||
use flowy_user_pub::workspace_service::UserWorkspaceService;
|
use flowy_user_pub::workspace_service::UserWorkspaceService;
|
||||||
@ -19,7 +19,7 @@ impl UserDepsResolver {
|
|||||||
authenticate_user: Arc<AuthenticateUser>,
|
authenticate_user: Arc<AuthenticateUser>,
|
||||||
collab_builder: Arc<AppFlowyCollabBuilder>,
|
collab_builder: Arc<AppFlowyCollabBuilder>,
|
||||||
server_provider: Arc<ServerProvider>,
|
server_provider: Arc<ServerProvider>,
|
||||||
store_preference: Arc<StorePreferences>,
|
store_preference: Arc<KVStorePreferences>,
|
||||||
database_manager: Arc<DatabaseManager>,
|
database_manager: Arc<DatabaseManager>,
|
||||||
folder_manager: Arc<FolderManager>,
|
folder_manager: Arc<FolderManager>,
|
||||||
) -> Arc<UserManager> {
|
) -> Arc<UserManager> {
|
||||||
|
@ -14,7 +14,7 @@ use flowy_server::{AppFlowyEncryption, AppFlowyServer, EncryptionImpl};
|
|||||||
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
use flowy_server_pub::af_cloud_config::AFCloudConfiguration;
|
||||||
use flowy_server_pub::supabase_config::SupabaseConfiguration;
|
use flowy_server_pub::supabase_config::SupabaseConfiguration;
|
||||||
use flowy_server_pub::AuthenticatorType;
|
use flowy_server_pub::AuthenticatorType;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user_pub::entities::*;
|
use flowy_user_pub::entities::*;
|
||||||
|
|
||||||
use crate::AppFlowyCoreConfig;
|
use crate::AppFlowyCoreConfig;
|
||||||
@ -59,7 +59,7 @@ pub struct ServerProvider {
|
|||||||
providers: RwLock<HashMap<Server, Arc<dyn AppFlowyServer>>>,
|
providers: RwLock<HashMap<Server, Arc<dyn AppFlowyServer>>>,
|
||||||
pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>,
|
pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) store_preferences: Weak<StorePreferences>,
|
pub(crate) store_preferences: Weak<KVStorePreferences>,
|
||||||
pub(crate) user_enable_sync: RwLock<bool>,
|
pub(crate) user_enable_sync: RwLock<bool>,
|
||||||
|
|
||||||
/// The authenticator type of the user.
|
/// The authenticator type of the user.
|
||||||
@ -72,7 +72,7 @@ impl ServerProvider {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
config: AppFlowyCoreConfig,
|
config: AppFlowyCoreConfig,
|
||||||
server: Server,
|
server: Server,
|
||||||
store_preferences: Weak<StorePreferences>,
|
store_preferences: Weak<KVStorePreferences>,
|
||||||
server_user: impl ServerUser + 'static,
|
server_user: impl ServerUser + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let user = Arc::new(server_user);
|
let user = Arc::new(server_user);
|
||||||
|
@ -18,8 +18,7 @@ use collab_integrate::collab_builder::{
|
|||||||
CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType,
|
CollabCloudPluginProvider, CollabPluginProviderContext, CollabPluginProviderType,
|
||||||
};
|
};
|
||||||
use flowy_chat_pub::cloud::{
|
use flowy_chat_pub::cloud::{
|
||||||
ChatCloudService, ChatMessage, ChatMessageStream, MessageCursor, RepeatedChatMessage,
|
ChatCloudService, ChatMessage, MessageCursor, RepeatedChatMessage, StreamAnswer,
|
||||||
StreamAnswer,
|
|
||||||
};
|
};
|
||||||
use flowy_database_pub::cloud::{
|
use flowy_database_pub::cloud::{
|
||||||
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
CollabDocStateByOid, DatabaseCloudService, DatabaseSnapshot, SummaryRowContent,
|
||||||
@ -545,24 +544,7 @@ impl ChatCloudService for ServerProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_chat_message(
|
fn save_question(
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
message: &str,
|
|
||||||
message_type: ChatMessageType,
|
|
||||||
) -> Result<ChatMessageStream, FlowyError> {
|
|
||||||
let workspace_id = workspace_id.to_string();
|
|
||||||
let chat_id = chat_id.to_string();
|
|
||||||
let message = message.to_string();
|
|
||||||
let server = self.get_server()?;
|
|
||||||
server
|
|
||||||
.chat_service()
|
|
||||||
.send_chat_message(&workspace_id, &chat_id, &message, message_type)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_question(
|
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
@ -577,7 +559,7 @@ impl ChatCloudService for ServerProvider {
|
|||||||
FutureResult::new(async move {
|
FutureResult::new(async move {
|
||||||
server?
|
server?
|
||||||
.chat_service()
|
.chat_service()
|
||||||
.send_question(&workspace_id, &chat_id, &message, message_type)
|
.save_question(&workspace_id, &chat_id, &message, message_type)
|
||||||
.await
|
.await
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -601,7 +583,7 @@ impl ChatCloudService for ServerProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stream_answer(
|
async fn ask_question(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
@ -612,7 +594,7 @@ impl ChatCloudService for ServerProvider {
|
|||||||
let server = self.get_server()?;
|
let server = self.get_server()?;
|
||||||
server
|
server
|
||||||
.chat_service()
|
.chat_service()
|
||||||
.stream_answer(&workspace_id, &chat_id, message_id)
|
.ask_question(&workspace_id, &chat_id, message_id)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use flowy_error::{FlowyError, FlowyResult};
|
|||||||
use flowy_folder::manager::FolderManager;
|
use flowy_folder::manager::FolderManager;
|
||||||
use flowy_server::af_cloud::define::ServerUser;
|
use flowy_server::af_cloud::define::ServerUser;
|
||||||
|
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_storage::manager::StorageManager;
|
use flowy_storage::manager::StorageManager;
|
||||||
use flowy_user::services::authenticate_user::AuthenticateUser;
|
use flowy_user::services::authenticate_user::AuthenticateUser;
|
||||||
use flowy_user::services::entities::UserConfig;
|
use flowy_user::services::entities::UserConfig;
|
||||||
@ -57,7 +57,7 @@ pub struct AppFlowyCore {
|
|||||||
pub event_dispatcher: Arc<AFPluginDispatcher>,
|
pub event_dispatcher: Arc<AFPluginDispatcher>,
|
||||||
pub server_provider: Arc<ServerProvider>,
|
pub server_provider: Arc<ServerProvider>,
|
||||||
pub task_dispatcher: Arc<RwLock<TaskDispatcher>>,
|
pub task_dispatcher: Arc<RwLock<TaskDispatcher>>,
|
||||||
pub store_preference: Arc<StorePreferences>,
|
pub store_preference: Arc<KVStorePreferences>,
|
||||||
pub search_manager: Arc<SearchManager>,
|
pub search_manager: Arc<SearchManager>,
|
||||||
pub chat_manager: Arc<ChatManager>,
|
pub chat_manager: Arc<ChatManager>,
|
||||||
pub storage_manager: Arc<StorageManager>,
|
pub storage_manager: Arc<StorageManager>,
|
||||||
@ -102,7 +102,7 @@ impl AppFlowyCore {
|
|||||||
#[instrument(skip(config, runtime))]
|
#[instrument(skip(config, runtime))]
|
||||||
async fn init(config: AppFlowyCoreConfig, runtime: Arc<AFPluginRuntime>) -> Self {
|
async fn init(config: AppFlowyCoreConfig, runtime: Arc<AFPluginRuntime>) -> Self {
|
||||||
// Init the key value database
|
// Init the key value database
|
||||||
let store_preference = Arc::new(StorePreferences::new(&config.storage_path).unwrap());
|
let store_preference = Arc::new(KVStorePreferences::new(&config.storage_path).unwrap());
|
||||||
info!("🔥{:?}", &config);
|
info!("🔥{:?}", &config);
|
||||||
|
|
||||||
let task_scheduler = TaskDispatcher::new(Duration::from_secs(2));
|
let task_scheduler = TaskDispatcher::new(Duration::from_secs(2));
|
||||||
@ -175,8 +175,11 @@ impl AppFlowyCore {
|
|||||||
Arc::downgrade(&storage_manager.storage_service),
|
Arc::downgrade(&storage_manager.storage_service),
|
||||||
);
|
);
|
||||||
|
|
||||||
let chat_manager =
|
let chat_manager = ChatDepsResolver::resolve(
|
||||||
ChatDepsResolver::resolve(Arc::downgrade(&authenticate_user), server_provider.clone());
|
Arc::downgrade(&authenticate_user),
|
||||||
|
server_provider.clone(),
|
||||||
|
store_preference.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Some(Arc::downgrade(
|
let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Some(Arc::downgrade(
|
||||||
&authenticate_user,
|
&authenticate_user,
|
||||||
|
@ -30,7 +30,7 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
|||||||
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
|
use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService};
|
||||||
use flowy_folder_pub::folder_builder::ParentChildViews;
|
use flowy_folder_pub::folder_builder::ParentChildViews;
|
||||||
use flowy_search_pub::entities::FolderIndexManager;
|
use flowy_search_pub::entities::FolderIndexManager;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@ -51,7 +51,7 @@ pub struct FolderManager {
|
|||||||
pub(crate) operation_handlers: FolderOperationHandlers,
|
pub(crate) operation_handlers: FolderOperationHandlers,
|
||||||
pub cloud_service: Arc<dyn FolderCloudService>,
|
pub cloud_service: Arc<dyn FolderCloudService>,
|
||||||
pub(crate) folder_indexer: Arc<dyn FolderIndexManager>,
|
pub(crate) folder_indexer: Arc<dyn FolderIndexManager>,
|
||||||
pub(crate) store_preferences: Arc<StorePreferences>,
|
pub(crate) store_preferences: Arc<KVStorePreferences>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FolderManager {
|
impl FolderManager {
|
||||||
@ -61,7 +61,7 @@ impl FolderManager {
|
|||||||
operation_handlers: FolderOperationHandlers,
|
operation_handlers: FolderOperationHandlers,
|
||||||
cloud_service: Arc<dyn FolderCloudService>,
|
cloud_service: Arc<dyn FolderCloudService>,
|
||||||
folder_indexer: Arc<dyn FolderIndexManager>,
|
folder_indexer: Arc<dyn FolderIndexManager>,
|
||||||
store_preferences: Arc<StorePreferences>,
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
) -> FlowyResult<Self> {
|
) -> FlowyResult<Self> {
|
||||||
let mutex_folder = Arc::new(MutexFolder::default());
|
let mutex_folder = Arc::new(MutexFolder::default());
|
||||||
let manager = Self {
|
let manager = Self {
|
||||||
|
@ -4,9 +4,7 @@ use client_api::entity::{
|
|||||||
CreateAnswerMessageParams, CreateChatMessageParams, CreateChatParams, MessageCursor,
|
CreateAnswerMessageParams, CreateChatMessageParams, CreateChatParams, MessageCursor,
|
||||||
RepeatedChatMessage,
|
RepeatedChatMessage,
|
||||||
};
|
};
|
||||||
use flowy_chat_pub::cloud::{
|
use flowy_chat_pub::cloud::{ChatCloudService, ChatMessage, ChatMessageType, StreamAnswer};
|
||||||
ChatCloudService, ChatMessage, ChatMessageStream, ChatMessageType, StreamAnswer,
|
|
||||||
};
|
|
||||||
use flowy_error::FlowyError;
|
use flowy_error::FlowyError;
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use lib_infra::async_trait::async_trait;
|
use lib_infra::async_trait::async_trait;
|
||||||
@ -46,27 +44,7 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_chat_message(
|
fn save_question(
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
message: &str,
|
|
||||||
message_type: ChatMessageType,
|
|
||||||
) -> Result<ChatMessageStream, FlowyError> {
|
|
||||||
let try_get_client = self.inner.try_get_client();
|
|
||||||
let params = CreateChatMessageParams {
|
|
||||||
content: message.to_string(),
|
|
||||||
message_type,
|
|
||||||
};
|
|
||||||
let stream = try_get_client?
|
|
||||||
.create_chat_qa_message(workspace_id, chat_id, params)
|
|
||||||
.await
|
|
||||||
.map_err(FlowyError::from)?;
|
|
||||||
|
|
||||||
Ok(stream.boxed())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_question(
|
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
@ -83,7 +61,7 @@ where
|
|||||||
|
|
||||||
FutureResult::new(async move {
|
FutureResult::new(async move {
|
||||||
let message = try_get_client?
|
let message = try_get_client?
|
||||||
.create_question(&workspace_id, &chat_id, params)
|
.save_question(&workspace_id, &chat_id, params)
|
||||||
.await
|
.await
|
||||||
.map_err(FlowyError::from)?;
|
.map_err(FlowyError::from)?;
|
||||||
Ok(message)
|
Ok(message)
|
||||||
@ -107,14 +85,14 @@ where
|
|||||||
|
|
||||||
FutureResult::new(async move {
|
FutureResult::new(async move {
|
||||||
let message = try_get_client?
|
let message = try_get_client?
|
||||||
.create_answer(&workspace_id, &chat_id, params)
|
.save_answer(&workspace_id, &chat_id, params)
|
||||||
.await
|
.await
|
||||||
.map_err(FlowyError::from)?;
|
.map_err(FlowyError::from)?;
|
||||||
Ok(message)
|
Ok(message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stream_answer(
|
async fn ask_question(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
chat_id: &str,
|
chat_id: &str,
|
||||||
@ -122,12 +100,31 @@ where
|
|||||||
) -> Result<StreamAnswer, FlowyError> {
|
) -> Result<StreamAnswer, FlowyError> {
|
||||||
let try_get_client = self.inner.try_get_client();
|
let try_get_client = self.inner.try_get_client();
|
||||||
let stream = try_get_client?
|
let stream = try_get_client?
|
||||||
.stream_answer(workspace_id, chat_id, message_id)
|
.ask_question(workspace_id, chat_id, message_id)
|
||||||
.await
|
.await
|
||||||
.map_err(FlowyError::from)?;
|
.map_err(FlowyError::from)?;
|
||||||
Ok(stream.boxed())
|
Ok(stream.boxed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_answer(
|
||||||
|
&self,
|
||||||
|
workspace_id: &str,
|
||||||
|
chat_id: &str,
|
||||||
|
question_message_id: i64,
|
||||||
|
) -> FutureResult<ChatMessage, FlowyError> {
|
||||||
|
let workspace_id = workspace_id.to_string();
|
||||||
|
let chat_id = chat_id.to_string();
|
||||||
|
let try_get_client = self.inner.try_get_client();
|
||||||
|
|
||||||
|
FutureResult::new(async move {
|
||||||
|
let resp = try_get_client?
|
||||||
|
.generate_answer(&workspace_id, &chat_id, question_message_id)
|
||||||
|
.await
|
||||||
|
.map_err(FlowyError::from)?;
|
||||||
|
Ok(resp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn get_chat_messages(
|
fn get_chat_messages(
|
||||||
&self,
|
&self,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
@ -168,23 +165,4 @@ where
|
|||||||
Ok(resp)
|
Ok(resp)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_answer(
|
|
||||||
&self,
|
|
||||||
workspace_id: &str,
|
|
||||||
chat_id: &str,
|
|
||||||
question_message_id: i64,
|
|
||||||
) -> FutureResult<ChatMessage, FlowyError> {
|
|
||||||
let workspace_id = workspace_id.to_string();
|
|
||||||
let chat_id = chat_id.to_string();
|
|
||||||
let try_get_client = self.inner.try_get_client();
|
|
||||||
|
|
||||||
FutureResult::new(async move {
|
|
||||||
let resp = try_get_client?
|
|
||||||
.get_answer(&workspace_id, &chat_id, question_message_id)
|
|
||||||
.await
|
|
||||||
.map_err(FlowyError::from)?;
|
|
||||||
Ok(resp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,7 @@ impl ChatCloudService for DefaultChatCloudServiceImpl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_chat_message(
|
fn save_question(
|
||||||
&self,
|
|
||||||
_workspace_id: &str,
|
|
||||||
_chat_id: &str,
|
|
||||||
_message: &str,
|
|
||||||
_message_type: ChatMessageType,
|
|
||||||
) -> Result<ChatMessageStream, FlowyError> {
|
|
||||||
Err(FlowyError::not_support().with_context("Chat is not supported in local server."))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_question(
|
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: &str,
|
_workspace_id: &str,
|
||||||
_chat_id: &str,
|
_chat_id: &str,
|
||||||
@ -54,7 +44,7 @@ impl ChatCloudService for DefaultChatCloudServiceImpl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stream_answer(
|
async fn ask_question(
|
||||||
&self,
|
&self,
|
||||||
_workspace_id: &str,
|
_workspace_id: &str,
|
||||||
_chat_id: &str,
|
_chat_id: &str,
|
||||||
|
@ -18,9 +18,3 @@ log = "0.4.21"
|
|||||||
parking_lot.workspace = true
|
parking_lot.workspace = true
|
||||||
tokio-stream = "0.1.15"
|
tokio-stream = "0.1.15"
|
||||||
lib-infra.workspace = true
|
lib-infra.workspace = true
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
dotenv = "0.15.0"
|
|
||||||
uuid.workspace = true
|
|
||||||
tracing-subscriber = { version = "0.3.17", features = ["registry", "env-filter", "ansi", "json"] }
|
|
||||||
|
@ -3,7 +3,6 @@ use crate::core::rpc_object::RpcObject;
|
|||||||
use crate::error::{ReadError, RemoteError};
|
use crate::error::{ReadError, RemoteError};
|
||||||
use serde_json::{json, Value as JsonValue};
|
use serde_json::{json, Value as JsonValue};
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use tracing::error;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct MessageReader(String);
|
pub struct MessageReader(String);
|
||||||
@ -61,64 +60,3 @@ pub trait ResponseParser {
|
|||||||
type ValueType: Send + Sync + 'static;
|
type ValueType: Send + Sync + 'static;
|
||||||
fn parse_json(payload: JsonValue) -> Result<Self::ValueType, RemoteError>;
|
fn parse_json(payload: JsonValue) -> Result<Self::ValueType, RemoteError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChatResponseParser;
|
|
||||||
impl ResponseParser for ChatResponseParser {
|
|
||||||
type ValueType = String;
|
|
||||||
|
|
||||||
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
|
||||||
if json.is_object() {
|
|
||||||
if let Some(data) = json.get("data") {
|
|
||||||
if let Some(message) = data.as_str() {
|
|
||||||
return Ok(message.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Err(RemoteError::ParseResponse(json));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ChatStreamResponseParser;
|
|
||||||
impl ResponseParser for ChatStreamResponseParser {
|
|
||||||
type ValueType = String;
|
|
||||||
|
|
||||||
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
|
||||||
if let Some(message) = json.as_str() {
|
|
||||||
return Ok(message.to_string());
|
|
||||||
}
|
|
||||||
return Err(RemoteError::ParseResponse(json));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ChatRelatedQuestionsResponseParser;
|
|
||||||
impl ResponseParser for ChatRelatedQuestionsResponseParser {
|
|
||||||
type ValueType = Vec<JsonValue>;
|
|
||||||
|
|
||||||
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
|
||||||
if json.is_object() {
|
|
||||||
if let Some(data) = json.get("data") {
|
|
||||||
if let Some(values) = data.as_array() {
|
|
||||||
return Ok(values.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Err(RemoteError::ParseResponse(json));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SimilarityResponseParser;
|
|
||||||
impl ResponseParser for SimilarityResponseParser {
|
|
||||||
type ValueType = f64;
|
|
||||||
|
|
||||||
fn parse_json(json: JsonValue) -> Result<Self::ValueType, RemoteError> {
|
|
||||||
if json.is_object() {
|
|
||||||
if let Some(data) = json.get("data") {
|
|
||||||
if let Some(score) = data.get("score").and_then(|v| v.as_f64()) {
|
|
||||||
return Ok(score);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Err(RemoteError::ParseResponse(json));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -8,12 +8,12 @@ use anyhow::anyhow;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{json, Value as JsonValue};
|
use serde_json::{json, Value as JsonValue};
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::process::{Child, Stdio};
|
use std::process::{Child, Stdio};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use tokio_stream::wrappers::ReceiverStream;
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
use tokio_stream::Stream;
|
|
||||||
|
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ impl Plugin {
|
|||||||
|
|
||||||
pub struct PluginInfo {
|
pub struct PluginInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub exec_path: String,
|
pub exec_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn start_plugin_process(
|
pub(crate) async fn start_plugin_process(
|
||||||
|
@ -9,7 +9,7 @@ use std::io::{BufRead, Write};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{error, info, trace};
|
use tracing::{error, trace};
|
||||||
|
|
||||||
const MAX_IDLE_WAIT: Duration = Duration::from_millis(5);
|
const MAX_IDLE_WAIT: Duration = Duration::from_millis(5);
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::core::parser::{Call, RequestId};
|
use crate::core::parser::{Call, RequestId};
|
||||||
use crate::core::rpc_peer::{Response, ResponsePayload};
|
use crate::core::rpc_peer::{Response, ResponsePayload};
|
||||||
use crate::error::RemoteError;
|
|
||||||
use serde::de::{DeserializeOwned, Error};
|
use serde::de::{DeserializeOwned, Error};
|
||||||
use serde_json::{json, Value};
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RpcObject(pub Value);
|
pub struct RpcObject(pub Value);
|
||||||
|
@ -200,7 +200,19 @@ impl<W: Write> RawPeer<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let json = resp.map(|resp| resp.into_json());
|
let json = resp.map(|resp| resp.into_json());
|
||||||
response_handler.invoke(json);
|
match json {
|
||||||
|
Ok(Some(json)) => {
|
||||||
|
response_handler.invoke(Ok(json));
|
||||||
|
},
|
||||||
|
Ok(None) => {
|
||||||
|
if !is_stream {
|
||||||
|
warn!("[RPC] only stream response can be None");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
response_handler.invoke(Err(err));
|
||||||
|
},
|
||||||
|
}
|
||||||
},
|
},
|
||||||
None => error!("[RPC] id {}'s handle not found", request_id),
|
None => error!("[RPC] id {}'s handle not found", request_id),
|
||||||
}
|
}
|
||||||
@ -306,19 +318,11 @@ impl ResponsePayload {
|
|||||||
matches!(self, ResponsePayload::StreamEnd(_))
|
matches!(self, ResponsePayload::StreamEnd(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn json(&self) -> &JsonValue {
|
pub fn into_json(self) -> Option<JsonValue> {
|
||||||
match self {
|
match self {
|
||||||
ResponsePayload::Json(v) => v,
|
ResponsePayload::Json(v) => Some(v),
|
||||||
ResponsePayload::Streaming(v) => v,
|
ResponsePayload::Streaming(v) => Some(v),
|
||||||
ResponsePayload::StreamEnd(v) => v,
|
ResponsePayload::StreamEnd(_) => None,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_json(self) -> JsonValue {
|
|
||||||
match self {
|
|
||||||
ResponsePayload::Json(v) => v,
|
|
||||||
ResponsePayload::Streaming(v) => v,
|
|
||||||
ResponsePayload::StreamEnd(v) => v,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
pub mod core;
|
pub mod core;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
pub mod plugins;
|
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
use crate::core::parser::{
|
|
||||||
ChatRelatedQuestionsResponseParser, ChatResponseParser, ChatStreamResponseParser,
|
|
||||||
};
|
|
||||||
use crate::core::plugin::{Plugin, PluginId};
|
|
||||||
use crate::error::SidecarError;
|
|
||||||
use anyhow::anyhow;
|
|
||||||
use serde_json::json;
|
|
||||||
use std::sync::Weak;
|
|
||||||
use tokio_stream::wrappers::ReceiverStream;
|
|
||||||
use tokio_stream::Stream;
|
|
||||||
|
|
||||||
pub struct ChatPluginOperation {
|
|
||||||
plugin: Weak<Plugin>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChatPluginOperation {
|
|
||||||
pub fn new(plugin: Weak<Plugin>) -> Self {
|
|
||||||
ChatPluginOperation { plugin }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_message(
|
|
||||||
&self,
|
|
||||||
chat_id: &str,
|
|
||||||
_plugin_id: PluginId,
|
|
||||||
message: &str,
|
|
||||||
) -> Result<String, SidecarError> {
|
|
||||||
let plugin = self
|
|
||||||
.plugin
|
|
||||||
.upgrade()
|
|
||||||
.ok_or(SidecarError::Internal(anyhow!("Plugin is dropped")))?;
|
|
||||||
|
|
||||||
let params = json!({"chat_id": chat_id, "method": "answer", "params": {"content": message}});
|
|
||||||
let resp = plugin
|
|
||||||
.async_request::<ChatResponseParser>("handle", ¶ms)
|
|
||||||
.await?;
|
|
||||||
Ok(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn stream_message(
|
|
||||||
&self,
|
|
||||||
chat_id: &str,
|
|
||||||
_plugin_id: PluginId,
|
|
||||||
message: &str,
|
|
||||||
) -> Result<ReceiverStream<Result<String, SidecarError>>, SidecarError> {
|
|
||||||
let plugin = self
|
|
||||||
.plugin
|
|
||||||
.upgrade()
|
|
||||||
.ok_or(SidecarError::Internal(anyhow!("Plugin is dropped")))?;
|
|
||||||
|
|
||||||
let params =
|
|
||||||
json!({"chat_id": chat_id, "method": "stream_answer", "params": {"content": message}});
|
|
||||||
plugin.stream_request::<ChatStreamResponseParser>("handle", ¶ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_related_questions(
|
|
||||||
&self,
|
|
||||||
chat_id: &str,
|
|
||||||
) -> Result<Vec<serde_json::Value>, SidecarError> {
|
|
||||||
let plugin = self
|
|
||||||
.plugin
|
|
||||||
.upgrade()
|
|
||||||
.ok_or(SidecarError::Internal(anyhow!("Plugin is dropped")))?;
|
|
||||||
|
|
||||||
let params = json!({"chat_id": chat_id, "method": "related_question"});
|
|
||||||
let resp = plugin
|
|
||||||
.async_request::<ChatRelatedQuestionsResponseParser>("handle", ¶ms)
|
|
||||||
.await?;
|
|
||||||
Ok(resp)
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,13 +11,13 @@ use crate::sqlite_impl::{Database, PoolConfig};
|
|||||||
|
|
||||||
const DB_NAME: &str = "cache.db";
|
const DB_NAME: &str = "cache.db";
|
||||||
|
|
||||||
/// [StorePreferences] uses a sqlite database to store key value pairs.
|
/// [KVStorePreferences] uses a sqlite database to store key value pairs.
|
||||||
/// Most of the time, it used to storage AppFlowy configuration.
|
/// Most of the time, it used to storage AppFlowy configuration.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct StorePreferences {
|
pub struct KVStorePreferences {
|
||||||
database: Option<Database>,
|
database: Option<Database>,
|
||||||
}
|
}
|
||||||
impl StorePreferences {
|
impl KVStorePreferences {
|
||||||
#[tracing::instrument(level = "trace", err)]
|
#[tracing::instrument(level = "trace", err)]
|
||||||
pub fn new(root: &str) -> Result<Self, anyhow::Error> {
|
pub fn new(root: &str) -> Result<Self, anyhow::Error> {
|
||||||
if !Path::new(root).exists() {
|
if !Path::new(root).exists() {
|
||||||
@ -138,7 +138,7 @@ mod tests {
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
use crate::kv::StorePreferences;
|
use crate::kv::KVStorePreferences;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)]
|
||||||
struct Person {
|
struct Person {
|
||||||
@ -150,7 +150,7 @@ mod tests {
|
|||||||
fn kv_store_test() {
|
fn kv_store_test() {
|
||||||
let tempdir = TempDir::new().unwrap();
|
let tempdir = TempDir::new().unwrap();
|
||||||
let path = tempdir.into_path();
|
let path = tempdir.into_path();
|
||||||
let store = StorePreferences::new(path.to_str().unwrap()).unwrap();
|
let store = KVStorePreferences::new(path.to_str().unwrap()).unwrap();
|
||||||
|
|
||||||
store.set_str("1", "hello".to_string());
|
store.set_str("1", "hello".to_string());
|
||||||
assert_eq!(store.get_str("1").unwrap(), "hello");
|
assert_eq!(store.get_str("1").unwrap(), "hello");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user_pub::cloud::UserCloudConfig;
|
use flowy_user_pub::cloud::UserCloudConfig;
|
||||||
use flowy_user_pub::entities::*;
|
use flowy_user_pub::entities::*;
|
||||||
use lib_dispatch::prelude::*;
|
use lib_dispatch::prelude::*;
|
||||||
@ -25,8 +25,8 @@ fn upgrade_manager(manager: AFPluginState<Weak<UserManager>>) -> FlowyResult<Arc
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade_store_preferences(
|
fn upgrade_store_preferences(
|
||||||
store: AFPluginState<Weak<StorePreferences>>,
|
store: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> FlowyResult<Arc<StorePreferences>> {
|
) -> FlowyResult<Arc<KVStorePreferences>> {
|
||||||
let store = store
|
let store = store
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.ok_or(FlowyError::internal().with_context("The store preferences is already drop"))?;
|
.ok_or(FlowyError::internal().with_context("The store preferences is already drop"))?;
|
||||||
@ -151,7 +151,7 @@ const APPEARANCE_SETTING_CACHE_KEY: &str = "appearance_settings";
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn set_appearance_setting(
|
pub async fn set_appearance_setting(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<AppearanceSettingsPB>,
|
data: AFPluginData<AppearanceSettingsPB>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
@ -165,7 +165,7 @@ pub async fn set_appearance_setting(
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn get_appearance_setting(
|
pub async fn get_appearance_setting(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> DataResult<AppearanceSettingsPB, FlowyError> {
|
) -> DataResult<AppearanceSettingsPB, FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
match store_preferences.get_str(APPEARANCE_SETTING_CACHE_KEY) {
|
match store_preferences.get_str(APPEARANCE_SETTING_CACHE_KEY) {
|
||||||
@ -187,7 +187,7 @@ const DATE_TIME_SETTINGS_CACHE_KEY: &str = "date_time_settings";
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn set_date_time_settings(
|
pub async fn set_date_time_settings(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<DateTimeSettingsPB>,
|
data: AFPluginData<DateTimeSettingsPB>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
@ -202,7 +202,7 @@ pub async fn set_date_time_settings(
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn get_date_time_settings(
|
pub async fn get_date_time_settings(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> DataResult<DateTimeSettingsPB, FlowyError> {
|
) -> DataResult<DateTimeSettingsPB, FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
match store_preferences.get_str(DATE_TIME_SETTINGS_CACHE_KEY) {
|
match store_preferences.get_str(DATE_TIME_SETTINGS_CACHE_KEY) {
|
||||||
@ -227,7 +227,7 @@ const NOTIFICATION_SETTINGS_CACHE_KEY: &str = "notification_settings";
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn set_notification_settings(
|
pub async fn set_notification_settings(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
data: AFPluginData<NotificationSettingsPB>,
|
data: AFPluginData<NotificationSettingsPB>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
@ -238,7 +238,7 @@ pub async fn set_notification_settings(
|
|||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn get_notification_settings(
|
pub async fn get_notification_settings(
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> DataResult<NotificationSettingsPB, FlowyError> {
|
) -> DataResult<NotificationSettingsPB, FlowyError> {
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
match store_preferences.get_str(NOTIFICATION_SETTINGS_CACHE_KEY) {
|
match store_preferences.get_str(NOTIFICATION_SETTINGS_CACHE_KEY) {
|
||||||
@ -348,7 +348,7 @@ pub async fn sign_in_with_provider_handler(
|
|||||||
pub async fn set_encrypt_secret_handler(
|
pub async fn set_encrypt_secret_handler(
|
||||||
manager: AFPluginState<Weak<UserManager>>,
|
manager: AFPluginState<Weak<UserManager>>,
|
||||||
data: AFPluginData<UserSecretPB>,
|
data: AFPluginData<UserSecretPB>,
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let manager = upgrade_manager(manager)?;
|
let manager = upgrade_manager(manager)?;
|
||||||
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
@ -408,7 +408,7 @@ pub async fn check_encrypt_secret_handler(
|
|||||||
pub async fn set_cloud_config_handler(
|
pub async fn set_cloud_config_handler(
|
||||||
manager: AFPluginState<Weak<UserManager>>,
|
manager: AFPluginState<Weak<UserManager>>,
|
||||||
data: AFPluginData<UpdateCloudConfigPB>,
|
data: AFPluginData<UpdateCloudConfigPB>,
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> Result<(), FlowyError> {
|
) -> Result<(), FlowyError> {
|
||||||
let manager = upgrade_manager(manager)?;
|
let manager = upgrade_manager(manager)?;
|
||||||
let session = manager.get_session()?;
|
let session = manager.get_session()?;
|
||||||
@ -468,7 +468,7 @@ pub async fn set_cloud_config_handler(
|
|||||||
#[tracing::instrument(level = "info", skip_all, err)]
|
#[tracing::instrument(level = "info", skip_all, err)]
|
||||||
pub async fn get_cloud_config_handler(
|
pub async fn get_cloud_config_handler(
|
||||||
manager: AFPluginState<Weak<UserManager>>,
|
manager: AFPluginState<Weak<UserManager>>,
|
||||||
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
store_preferences: AFPluginState<Weak<KVStorePreferences>>,
|
||||||
) -> DataResult<CloudSettingPB, FlowyError> {
|
) -> DataResult<CloudSettingPB, FlowyError> {
|
||||||
let manager = upgrade_manager(manager)?;
|
let manager = upgrade_manager(manager)?;
|
||||||
let session = manager.get_session()?;
|
let session = manager.get_session()?;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user_pub::session::Session;
|
use flowy_user_pub::session::Session;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@ -8,7 +8,7 @@ const MIGRATION_USER_NO_USER_UUID: &str = "migration_user_no_user_uuid";
|
|||||||
|
|
||||||
pub fn migrate_session_with_user_uuid(
|
pub fn migrate_session_with_user_uuid(
|
||||||
session_cache_key: &str,
|
session_cache_key: &str,
|
||||||
store_preferences: &Arc<StorePreferences>,
|
store_preferences: &Arc<KVStorePreferences>,
|
||||||
) -> Option<Session> {
|
) -> Option<Session> {
|
||||||
if !store_preferences.get_bool(MIGRATION_USER_NO_USER_UUID)
|
if !store_preferences.get_bool(MIGRATION_USER_NO_USER_UUID)
|
||||||
&& store_preferences
|
&& store_preferences
|
||||||
|
@ -5,7 +5,7 @@ use crate::services::sqlite_sql::user_sql::vacuum_database;
|
|||||||
use collab_integrate::CollabKVDB;
|
use collab_integrate::CollabKVDB;
|
||||||
|
|
||||||
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_sqlite::DBConnection;
|
use flowy_sqlite::DBConnection;
|
||||||
use flowy_user_pub::entities::UserWorkspace;
|
use flowy_user_pub::entities::UserWorkspace;
|
||||||
use flowy_user_pub::session::Session;
|
use flowy_user_pub::session::Session;
|
||||||
@ -19,12 +19,12 @@ pub struct AuthenticateUser {
|
|||||||
pub user_config: UserConfig,
|
pub user_config: UserConfig,
|
||||||
pub(crate) database: Arc<UserDB>,
|
pub(crate) database: Arc<UserDB>,
|
||||||
pub(crate) user_paths: UserPaths,
|
pub(crate) user_paths: UserPaths,
|
||||||
store_preferences: Arc<StorePreferences>,
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
session: Arc<parking_lot::RwLock<Option<Session>>>,
|
session: Arc<parking_lot::RwLock<Option<Session>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuthenticateUser {
|
impl AuthenticateUser {
|
||||||
pub fn new(user_config: UserConfig, store_preferences: Arc<StorePreferences>) -> Self {
|
pub fn new(user_config: UserConfig, store_preferences: Arc<KVStorePreferences>) -> Self {
|
||||||
let user_paths = UserPaths::new(user_config.storage_path.clone());
|
let user_paths = UserPaths::new(user_config.storage_path.clone());
|
||||||
let database = Arc::new(UserDB::new(user_paths.clone()));
|
let database = Arc::new(UserDB::new(user_paths.clone()));
|
||||||
let session = Arc::new(parking_lot::RwLock::new(None));
|
let session = Arc::new(parking_lot::RwLock::new(None));
|
||||||
|
@ -2,12 +2,12 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use flowy_encrypt::generate_encryption_secret;
|
use flowy_encrypt::generate_encryption_secret;
|
||||||
use flowy_error::FlowyResult;
|
use flowy_error::FlowyResult;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user_pub::cloud::UserCloudConfig;
|
use flowy_user_pub::cloud::UserCloudConfig;
|
||||||
|
|
||||||
const CLOUD_CONFIG_KEY: &str = "af_user_cloud_config";
|
const CLOUD_CONFIG_KEY: &str = "af_user_cloud_config";
|
||||||
|
|
||||||
fn generate_cloud_config(uid: i64, store_preference: &Arc<StorePreferences>) -> UserCloudConfig {
|
fn generate_cloud_config(uid: i64, store_preference: &Arc<KVStorePreferences>) -> UserCloudConfig {
|
||||||
let config = UserCloudConfig::new(generate_encryption_secret());
|
let config = UserCloudConfig::new(generate_encryption_secret());
|
||||||
let key = cache_key_for_cloud_config(uid);
|
let key = cache_key_for_cloud_config(uid);
|
||||||
store_preference.set_object(&key, config.clone()).unwrap();
|
store_preference.set_object(&key, config.clone()).unwrap();
|
||||||
@ -16,7 +16,7 @@ fn generate_cloud_config(uid: i64, store_preference: &Arc<StorePreferences>) ->
|
|||||||
|
|
||||||
pub fn save_cloud_config(
|
pub fn save_cloud_config(
|
||||||
uid: i64,
|
uid: i64,
|
||||||
store_preference: &Arc<StorePreferences>,
|
store_preference: &Arc<KVStorePreferences>,
|
||||||
config: UserCloudConfig,
|
config: UserCloudConfig,
|
||||||
) -> FlowyResult<()> {
|
) -> FlowyResult<()> {
|
||||||
tracing::info!("save user:{} cloud config: {}", uid, config);
|
tracing::info!("save user:{} cloud config: {}", uid, config);
|
||||||
@ -31,7 +31,7 @@ fn cache_key_for_cloud_config(uid: i64) -> String {
|
|||||||
|
|
||||||
pub fn get_cloud_config(
|
pub fn get_cloud_config(
|
||||||
uid: i64,
|
uid: i64,
|
||||||
store_preference: &Arc<StorePreferences>,
|
store_preference: &Arc<KVStorePreferences>,
|
||||||
) -> Option<UserCloudConfig> {
|
) -> Option<UserCloudConfig> {
|
||||||
let key = cache_key_for_cloud_config(uid);
|
let key = cache_key_for_cloud_config(uid);
|
||||||
store_preference.get_object::<UserCloudConfig>(&key)
|
store_preference.get_object::<UserCloudConfig>(&key)
|
||||||
@ -39,7 +39,7 @@ pub fn get_cloud_config(
|
|||||||
|
|
||||||
pub fn get_or_create_cloud_config(
|
pub fn get_or_create_cloud_config(
|
||||||
uid: i64,
|
uid: i64,
|
||||||
store_preferences: &Arc<StorePreferences>,
|
store_preferences: &Arc<KVStorePreferences>,
|
||||||
) -> UserCloudConfig {
|
) -> UserCloudConfig {
|
||||||
let key = cache_key_for_cloud_config(uid);
|
let key = cache_key_for_cloud_config(uid);
|
||||||
store_preferences
|
store_preferences
|
||||||
@ -47,7 +47,7 @@ pub fn get_or_create_cloud_config(
|
|||||||
.unwrap_or_else(|| generate_cloud_config(uid, store_preferences))
|
.unwrap_or_else(|| generate_cloud_config(uid, store_preferences))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_encrypt_secret(uid: i64, store_preference: &Arc<StorePreferences>) -> Option<String> {
|
pub fn get_encrypt_secret(uid: i64, store_preference: &Arc<KVStorePreferences>) -> Option<String> {
|
||||||
let key = cache_key_for_cloud_config(uid);
|
let key = cache_key_for_cloud_config(uid);
|
||||||
store_preference
|
store_preference
|
||||||
.get_object::<UserCloudConfig>(&key)
|
.get_object::<UserCloudConfig>(&key)
|
||||||
|
@ -26,7 +26,7 @@ use flowy_error::FlowyError;
|
|||||||
use flowy_folder_pub::cloud::gen_view_id;
|
use flowy_folder_pub::cloud::gen_view_id;
|
||||||
use flowy_folder_pub::entities::{AppFlowyData, ImportData};
|
use flowy_folder_pub::entities::{AppFlowyData, ImportData};
|
||||||
use flowy_folder_pub::folder_builder::{ParentChildViews, ViewBuilder};
|
use flowy_folder_pub::folder_builder::{ParentChildViews, ViewBuilder};
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_user_pub::cloud::{UserCloudService, UserCollabParams};
|
use flowy_user_pub::cloud::{UserCloudService, UserCollabParams};
|
||||||
use flowy_user_pub::entities::{user_awareness_object_id, Authenticator};
|
use flowy_user_pub::entities::{user_awareness_object_id, Authenticator};
|
||||||
use flowy_user_pub::session::Session;
|
use flowy_user_pub::session::Session;
|
||||||
@ -62,7 +62,7 @@ pub(crate) fn prepare_import(path: &str) -> anyhow::Result<ImportedFolder> {
|
|||||||
return Err(anyhow!("The path: {} is not exist", path));
|
return Err(anyhow!("The path: {} is not exist", path));
|
||||||
}
|
}
|
||||||
let user_paths = UserPaths::new(path.to_string());
|
let user_paths = UserPaths::new(path.to_string());
|
||||||
let other_store_preferences = Arc::new(StorePreferences::new(path)?);
|
let other_store_preferences = Arc::new(KVStorePreferences::new(path)?);
|
||||||
migrate_session_with_user_uuid("appflowy_session_cache", &other_store_preferences);
|
migrate_session_with_user_uuid("appflowy_session_cache", &other_store_preferences);
|
||||||
let imported_session = other_store_preferences
|
let imported_session = other_store_preferences
|
||||||
.get_object::<Session>("appflowy_session_cache")
|
.get_object::<Session>("appflowy_session_cache")
|
||||||
|
@ -4,7 +4,7 @@ use collab_user::core::MutexUserAwareness;
|
|||||||
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
use flowy_error::{internal_error, ErrorCode, FlowyResult};
|
||||||
|
|
||||||
use flowy_server_pub::AuthenticatorType;
|
use flowy_server_pub::AuthenticatorType;
|
||||||
use flowy_sqlite::kv::StorePreferences;
|
use flowy_sqlite::kv::KVStorePreferences;
|
||||||
use flowy_sqlite::schema::user_table;
|
use flowy_sqlite::schema::user_table;
|
||||||
use flowy_sqlite::ConnectionPool;
|
use flowy_sqlite::ConnectionPool;
|
||||||
use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods};
|
use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods};
|
||||||
@ -48,7 +48,7 @@ use super::manager_user_workspace::save_user_workspace;
|
|||||||
|
|
||||||
pub struct UserManager {
|
pub struct UserManager {
|
||||||
pub(crate) cloud_services: Arc<dyn UserCloudServiceProvider>,
|
pub(crate) cloud_services: Arc<dyn UserCloudServiceProvider>,
|
||||||
pub(crate) store_preferences: Arc<StorePreferences>,
|
pub(crate) store_preferences: Arc<KVStorePreferences>,
|
||||||
pub(crate) user_awareness: Arc<Mutex<Option<MutexUserAwareness>>>,
|
pub(crate) user_awareness: Arc<Mutex<Option<MutexUserAwareness>>>,
|
||||||
pub(crate) user_status_callback: RwLock<Arc<dyn UserStatusCallback>>,
|
pub(crate) user_status_callback: RwLock<Arc<dyn UserStatusCallback>>,
|
||||||
pub(crate) collab_builder: Weak<AppFlowyCollabBuilder>,
|
pub(crate) collab_builder: Weak<AppFlowyCollabBuilder>,
|
||||||
@ -63,7 +63,7 @@ pub struct UserManager {
|
|||||||
impl UserManager {
|
impl UserManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
cloud_services: Arc<dyn UserCloudServiceProvider>,
|
cloud_services: Arc<dyn UserCloudServiceProvider>,
|
||||||
store_preferences: Arc<StorePreferences>,
|
store_preferences: Arc<KVStorePreferences>,
|
||||||
collab_builder: Weak<AppFlowyCollabBuilder>,
|
collab_builder: Weak<AppFlowyCollabBuilder>,
|
||||||
authenticate_user: Arc<AuthenticateUser>,
|
authenticate_user: Arc<AuthenticateUser>,
|
||||||
user_workspace_service: Arc<dyn UserWorkspaceService>,
|
user_workspace_service: Arc<dyn UserWorkspaceService>,
|
||||||
@ -110,7 +110,7 @@ impl UserManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_store_preferences(&self) -> Weak<StorePreferences> {
|
pub fn get_store_preferences(&self) -> Weak<KVStorePreferences> {
|
||||||
Arc::downgrade(&self.store_preferences)
|
Arc::downgrade(&self.store_preferences)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user