瀏覽代碼

dev (api): vector store try-create

Junyi Du 2 年之前
父節點
當前提交
ca259ff694

+ 26 - 7
src/main/frontend/ai/vector_store.cljs

@@ -10,8 +10,9 @@
 (defonce js-vector-store-class VectorStorage)
 
 (defn create
-  "Get a vector store handler
+  "Get a vector store handler in the app runtime state
    It the store is persisted, it will be loaded from the disk
+   If the handler is already created, return a rejected promise.
    - id-str: identifier for the vector store (should be unique!)
    - dim: dimension of the vector
    
@@ -19,12 +20,30 @@
    or throw an error if the store already exists"
   [id-str dim]
   ;; Check if the store already exists
-  (when (contains? @*stores id-str)
-    (throw (js/Error. (str "Vector store " id-str " already exists"))))
-  (let [store (VectorStorage. id-str dim)]
-    (swap! *stores assoc id-str store)
-    (p/let [_ (.initialize store)]
-      (.load store))))
+  (if (contains? @*stores id-str)
+    (p/rejected (js/Error. (str "Vector store " id-str " already exists")))
+    (let [store (VectorStorage. id-str dim)]
+      (swap! *stores assoc id-str store)
+      (p/let [_ (.initialize store)]
+        (.load store)))))
+
+(defn try-create
+  "Get a vector store handler in the app runtime state
+   It the store is persisted, it will be loaded from the disk
+   If the handler is already created, return a rejected promise.
+   - id-str: identifier for the vector store (should be unique!)
+   - dim: dimension of the vector
+   
+   Returns a promise of the vector store prepared (loaded, and the num of vecs that loaded)
+   or nil if the store already exists"
+  [id-str dim]
+  ;; Check if the store already exists
+  (if (contains? @*stores id-str)
+    nil
+    (let [store (VectorStorage. id-str dim)]
+      (swap! *stores assoc id-str store)
+      (p/let [_ (.initialize store)]
+        (.load store)))))
 
 (defn add
   "Add a record to the vector store

+ 14 - 1
src/main/frontend/components/settings.cljs

@@ -739,6 +739,16 @@
                (file-sync-handler/set-sync-diff-merge-enabled! (not enabled?)))
              true))
 
+(defn semsearch-status-row []
+  (row-with-button-action {:left-label (str (t :settings-page/semsearch) " (" (t :experimental-warn) ")")
+                           :action     [:div (:name (state/get-semsearch-encoder))]
+                           :desc       (ui/tippy {:html        [:div
+                                                                [:div (t :settings-page/semsearch-enabling)]]
+                                                  :class       "tippy-hover ml-2"
+                                                  :interactive true
+                                                  :disabled    false}
+                                                 (svg/info))}))
+
 (defn sync-switcher-row [enabled?]
   (row-with-button-action
    {:left-label (t :settings-page/sync)
@@ -746,7 +756,7 @@
 
 (defn sync-diff-merge-switcher-row [enabled?]
   (row-with-button-action
-   {:left-label (str (t :settings-page/sync-diff-merge) " (Experimental!)") ;; Not included in i18n to avoid outdating translations
+   {:left-label (str (t :settings-page/sync-diff-merge) " ("(t :experimental-warn)")") ;; Not included in i18n to avoid outdating translations
     :action (sync-diff-merge-enabled-switcher enabled?)
     :desc (ui/tippy {:html        [:div
                                    [:div (t :settings-page/sync-diff-merge-desc)]
@@ -964,6 +974,7 @@
   (let [current-repo (state/get-current-repo)
         enable-journals? (state/enable-journals? current-repo)
         enable-flashcards? (state/enable-flashcards? current-repo)
+        enable-semsearch? (state/semsearch-enabled?)
         enable-sync? (state/enable-sync?)
         enable-sync-diff-merge? (state/enable-sync-diff-merge?)
         enable-whiteboards? (state/enable-whiteboards? current-repo)
@@ -1014,6 +1025,8 @@
           (ui/icon  (if logged-in? "lock-open" "lock") {:class "mr-1"}) (t :settings-page/beta-features)]]
         [:div.flex.flex-col.gap-4
          {:class (when-not user-handler/alpha-or-beta-user? "opacity-50 pointer-events-none cursor-not-allowed")}
+         (when enable-semsearch?
+           (semsearch-status-row))
          (sync-switcher-row enable-sync?)
          (when enable-sync?
            (sync-diff-merge-switcher-row enable-sync-diff-merge?))

+ 11 - 1
src/main/frontend/state.cljs

@@ -1934,10 +1934,20 @@ Similar to re-frame subscriptions"
 (def lsp-enabled?
   (lsp-enabled?-or-theme))
 
+;; TODO make this setting configurable
+(defn get-semsearch-encoder
+  "Returns a semantic search encoder in the state map"
+  []
+  (-> (sub :ai/text-encoders)
+      seq
+      first ;; Pick a "first" elem in the map, temporarily
+      second ;; Return the encoder, without the encoder key
+      ))
+
 (defn semsearch-enabled?
   "Conditions to enable semantic search"
   []
-  (-> (:ai/text-encoders @state)
+  (-> (sub :ai/text-encoders)
       (not-empty)
       (boolean)))
 

+ 3 - 0
src/resources/dicts/en.edn

@@ -339,6 +339,8 @@
  :settings-page/sync-diff-merge "Enable smart merge when syncing"
  :settings-page/sync-diff-merge-desc "Merge local updates with remote files automatically when conflict happens, instead of overwriting the remote files"
  :settings-page/sync-diff-merge-warn "Smart merge ability is only activated on a client after first successful sync with the remote server on the graph in the new Logseq version. Enabling this on all devices to reach the best experience."
+ :settings-page/semsearch "Semantic Search"
+ :settings-page/semsearch-enabling "To Enable semantic search, install any text encoder plugin."
  :settings-page/enable-whiteboards "Whiteboards"
  :settings-page/native-titlebar "Native title bar"
  :settings-page/native-titlebar-desc "Enables the native window title bar on Windows and Linux."
@@ -354,6 +356,7 @@
 
  :yes "Yes"
 
+ :experimental-warn "Experimental!"
  :submit "Submit"
  :cancel "Cancel"
  :close "Close"