Skip to content

Commit

Permalink
Merge branch 'cytospace' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sid597 committed Jun 10, 2024
2 parents 1b008a7 + 3c97c2e commit 93df2e8
Show file tree
Hide file tree
Showing 9 changed files with 1,528 additions and 45 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
"shadow-cljs": "2.26.1"
},
"dependencies": {
"shadow-cljs": "2.26.1",
"@blueprintjs/core": "^3.50.4",
"@blueprintjs/icons": "^3.33.0",
"cytoscape": "^3.29.2",
"cytoscape-cose-bilkent": "^4.1.0",
"openai": "^4.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
"react-dom": "^17.0.2",
"shadow-cljs": "2.26.1"
}
}
230 changes: 228 additions & 2 deletions src/main/server/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
(:gen-class)
(:require [compojure.core :refer :all]
[ring.middleware.params :refer [wrap-params]]
[clojure.core.async :as async :refer [<! >! <!! >!! thread promise-chan go]]
[wkok.openai-clojure.api :as api]
[cheshire.core :as json]
[tolkien.core :as token]
[clj-http.client :as client]
[server.env :as env :refer [oai-key pass-key anthropic-key gemini-key]]
[server.env :as env :refer [oai-key pass-key pinecone-dg-index-host anthropic-key gemini-key pinecone-dg-nodes-key]]
[ring.adapter.jetty :as jetty]))


Expand Down Expand Up @@ -228,6 +229,229 @@
:error
:message))

(defn get-openai-embedding-for [input]
(let [body (json/generate-string
{:model "text-embedding-3-small"
:input input})
headers {"Content-Type" "application/json"
"Authorization" (str "Bearer " oai-key)}
url "https://api.openai.com/v1/embeddings"]
(client/post url
{:headers headers
:body body
:content-type :json
:as :json
:throw-exceptions false})))


(defn merge-embeddings-with-metadata [embeddings uids strings]
(vec (map
(fn [e u s]
{:id u
:values (:embedding e)
:metadata {:title s}})
embeddings
uids
strings)))

(defn get-openai-embedding-from [request]
(go
(let [input (-> request
:body
slurp
(json/parse-string true)
:input)
result-chan (promise-chan)
inp-strs (map #(:string %) input)
inp-uids (map #(:uid %) input)
res (<! (thread (get-openai-embedding-for inp-strs)))
_ (println "RES FROM OPEN AI: ")
res-body (:body res)
reply-body (cond
(not= 200
(:status res)) (str "^^ Error: code: " (:status res)
" and message: "
(-> res-body (json/parse-string-strict true) :error :message)
" ^^")
:else (merge-embeddings-with-metadata (-> res-body :data) inp-uids inp-strs))]
;(println "embeddings reply body: " reply-body)
(>!! result-chan {:status (:status res)
:headers {"Content-Type" "application/json"}
:body (json/generate-string reply-body)})
(<!! result-chan))))


(defn upsert-single [request]
(go
(let [embedding-res (-> (<! (thread (get-openai-embedding-for ["Hello"])))
:body
:data
first
:embedding)
result-chan (promise-chan)
_ (println "embeddings res" embedding-res)
vectors [{:id "1"
:values embedding-res}]
body (json/generate-string
{:vectors vectors})
headers {"Content-Type" "application/json"
"Api-Key" (str pinecone-dg-nodes-key)}
url (str pinecone-dg-index-host "/vectors/upsert")

res (client/post url
{:headers headers
:body body
:content-type :json
:as :json
:throw-exceptions false})
_ (println "RES -" res)
res-body (-> res :body)
reply-body (cond
(not= 200 (:status res))
(str "^^ Error: code: " (:status res)
" and message: "
(-> res-body (json/parse-string-strict true) :error :message)
" ^^")
:else (json/generate-string (str res-body)))]
(println "embeddings reply body: " reply-body)
(>!! result-chan {:status (:status res)
:headers {"Content-Type" "application/json"}
:body reply-body})
(<!! result-chan))))


(defn upsert-all [request]
(let [rq-map (-> request
:body
slurp
(json/parse-string true))
result-chan (promise-chan)]
(go
(let [input (:input rq-map)
inp-strs (map #(:title %) input)
inp-uids (map #(:uid %) input)
embed-res (<! (thread (get-openai-embedding-for inp-strs)))
embeddings (-> embed-res :body :data)
all-embeddings (merge-embeddings-with-metadata embeddings inp-uids inp-strs)
_ (println "UPLOADING " (count all-embeddings) " EMBEDDINGS")
body (json/generate-string
{:vectors all-embeddings}
{:pretty true})
headers {"content-type" "application/json"
"Api-Key" (str pinecone-dg-nodes-key)}
url (str pinecone-dg-index-host "/vectors/upsert")
_ (println "SENDING REQUEST ")
upsert-res (<! (thread (client/post url
{:headers headers
:body body
:content-type :json
:as :json
:throw-exceptions false})))

res-body (:body upsert-res)
_ (println "UPSERTED: "(-> res-body
:upsertedCount) "==" (:status upsert-res))
reply-body (cond
(not= 200 (:status upsert-res))
(str "^^ Error: code: " (:status upsert-res)
" and message: "
(-> res-body (json/parse-string-strict true) :error :message)
" ^^")
:else res-body)]
(println "embeddings reply body: " reply-body)
(>!! result-chan {:status (:status upsert-res)
:headers {"Content-Type" "application/json"}
:body (json/generate-string reply-body)})))
(<!! result-chan)))



(defn query-single-embedding [request]
(let [rq-map (-> request
:body
slurp
(json/parse-string true))
result-chan (promise-chan)]
(go
(let [inp-str (:input rq-map)
top-k (:top-k rq-map)
vector-embedding (-> (<! (thread (get-openai-embedding-for inp-str)))
:body :data first :embedding)
_ (println "--" vector-embedding)
body (json/generate-string
{:vector vector-embedding
:topK top-k
:includeMetadata true}
{:pretty true})
_ (println "BODY --" body)
headers {"content-type" "application/json"
"Api-Key" (str pinecone-dg-nodes-key)}
url (str pinecone-dg-index-host "/query")
query-res (<! (thread (client/post url
{:headers headers
:body body
:content-type :json
:as :json
:throw-exceptions false})))

res-body (:body query-res)
_ (println "QUERY RESULT: "(-> res-body
:matches) "==" (:status query-res))
reply-body (cond
(not= 200 (:status query-res))
(str "^^ Error: code: " (:status query-res)
" and message: "
(-> res-body (json/parse-string-strict true) :error :message)
" ^^")
:else (:matches res-body))]
(println "Query embeddings reply body: " reply-body)
(>!! result-chan {:status (:status query-res)
:headers {"Content-Type" "application/json"}
:body (json/generate-string reply-body)})))
(<!! result-chan)))

(defn get-query-res-for [vector-embedding top-k]
(let [body (json/generate-string
{:vector vector-embedding
:topK top-k
:includeMetadata true}
{:pretty true})
;_ (println "BODY --" body)
headers {"content-type" "application/json"
"Api-Key" (str pinecone-dg-nodes-key)}
url (str pinecone-dg-index-host "/query")]
(client/post url
{:headers headers
:body body
:content-type :json
:as :json
:throw-exceptions false})))


(defn query-multiple-embeddings [request]
(let [rq-map (-> request
:body
slurp
(json/parse-string true))
result-chan (promise-chan)]
(go
(let [inp-strs (:input rq-map)
top-k (:top-k rq-map)
vector-embeddings (-> (<! (thread (get-openai-embedding-for inp-strs)))
:body :data)
all-query-res (atom [])
_ (doseq [embedding vector-embeddings]
(let [query-res (-> (<! (thread (get-query-res-for (-> embedding :embedding) top-k)))
:body
:matches)]
(swap! all-query-res conj query-res)))
;_ (println "--" vector-embeddings)
_ (println "QUERY RESULT: " @all-query-res)]
(>!! result-chan {:status (:status all-query-res)
:headers {"Content-Type" "application/json"}
:body (json/generate-string @all-query-res)})))
(<!! result-chan)))


(defn- handle-preflight [f]
{:status 200
Expand All @@ -247,6 +471,8 @@
(POST "/chat-anthropic" request (cors-headers (chat-anthropic request)))
(OPTIONS "/chat-gemini" [] handle-preflight)
(POST "/chat-gemini" request (cors-headers (chat-gemini request)))
(OPTIONS "/get-openai-embeddings" [] handle-preflight)
(POST "/get-openai-embeddings" request (cors-headers (query-multiple-embeddings request)))
(OPTIONS "/count-tokens" [] handle-preflight)
(POST "/count-tokens" request (cors-headers (count-tokens request))))

Expand All @@ -257,4 +483,4 @@

(defn -main [& args]
(println "Starting server")
(jetty/run-jetty app {:port 8080}))
(jetty/run-jetty app {:port 3000}))
40 changes: 37 additions & 3 deletions src/main/ui/components/bottom_bar.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
(:require [cljs.core.async.interop :as asy :refer [<p!]]
[cljs.core.async :as async :refer [<! >! go chan put! take! timeout]]
[ui.components.quick-buttons :refer [button-with-settings text-to-image-button discourse-graph-this-page-button]]
[cljs-http.client :as http]
[ui.extract-data.chat :refer [data-for-nodes get-all-images-for-node]]
[ui.components.graph-overview-ai :refer [filtered-pages-button]]
[ui.utils :refer [p image-to-text-for ai-block-exists? chat-ui-with-context-struct uid->title log get-child-of-child-with-str-on-page get-open-page-uid get-block-parent-with-order get-focused-block create-struct gen-new-uid default-chat-struct get-todays-uid]]
[ui.utils :refer [p all-dg-nodes image-to-text-for ai-block-exists? chat-ui-with-context-struct uid->title log get-child-of-child-with-str-on-page get-open-page-uid get-block-parent-with-order get-focused-block create-struct gen-new-uid default-chat-struct get-todays-uid]]
["@blueprintjs/core" :as bp :refer [ControlGroup Checkbox Tooltip HTMLSelect Button ButtonGroup Card Slider Divider Menu MenuItem Popover MenuDivider]]))




(defn bottom-bar-buttons []
(p "Creating bottom bar buttons")

(fn []
(p "Render bottom bar buttons")
[:> ButtonGroup
Expand Down Expand Up @@ -83,9 +83,43 @@
chat-block-uid
true
(p (str pre "Created a new chat block under `AI chats` block and opening in sidebar. With no context."))))))}
"Start chat in daily notes, show in sidebar"]]
[:> Divider]
#_[:div
{:style {:flex "1 1 1"}}
[:> Button
{:minimal true
:small true
:on-click (fn [e]
(let [url "http://localhost:3000/get-openai-embeddings"
upsert-data (clj->js {:input (subvec (all-dg-nodes) 1600)})
multiple-query-data (clj->js {:input ["Myosin plays a critical role in assisting endocytosis under conditions of high membrane tension"
#_"Increasing membrane tension from 2 pN/nm to 2000 pN/nm in simulations showed a broader assistance by myosin in internalization"]
:top-k "8"})
single-query-data (clj->js {:input ["Increasing membrane tension from 2 pN/nm to 2000 pN/nm in simulations showed a broader assistance by myosin in internalization
Resistance to internalization increased as myosin unbinding rate decreased at higher membrane tension in simulations
At 20 pN/nm membrane tension, areas with low myosin unbinding rates had decreased internalization resistance
Investigate the relationship between myosin catch bonding parameters and internalization efficiency in live cell experiments
Myosin assists more broadly in membrane internalization under higher tension conditions
High membrane tension facilitates myosin’s role in overcoming resistance to internalization "]
:top-k "3"})


"Start chat in daily notes, show in sidebar"]]

headers {"Content-Type" "application/json"}
res-ch (http/post url {:with-credentials? false
:headers headers
:json-params multiple-query-data})]
#_(println "SENDING EMBEDDINGS REQUEST" (count (all-dg-nodes))) ""
#_(println "DATA : " (take 2 upsert-data))
(println "query data" single-query-data)
(take! res-ch (fn [res]
(let [embeddings (->> (js->clj (-> res :body ) :keywordize-keys true)
(map
(fn [x]
(str (-> x :metadata :title) "- Score: " (:score x)))))]
#_(println "GOT EMBEDDINGS :" "--" embeddings))))))}
"Create embeddings"]]
[:> Divider]
[:div
{:style {:flex "1 1 1"}}
Expand Down
Loading

0 comments on commit 93df2e8

Please sign in to comment.