|
2 | 2 | (:require |
3 | 3 | [babashka.curl :as curl] |
4 | 4 | [cheshire.core :as json] |
5 | | - [clj-yaml.core :as yaml] |
6 | | - [clojure.core.async :as async] |
7 | | - [tolkien.core :as tolkien] |
8 | 5 | [vector-db-process :as vec-db])) |
9 | 6 |
|
10 | 7 | ;; ================================================== |
11 | 8 | ;; DMR |
12 | 9 | ;; ================================================== |
13 | 10 |
|
14 | | -(def embedding-model "ai/embeddinggemma:latest") |
15 | | -(def summary-model "ai/gemma3-qat:latest") |
16 | 11 | (def url "localhost/exp/vDD4.40/engines/llama.cpp/v1/embeddings") |
17 | 12 | (def models-url "localhost/exp/vDD4.40/engines/llama.cpp/v1/models") |
18 | 13 | (def create-models-url "localhost/exp/vDD4.40/models/create") |
|
138 | 133 | (let [vec (create-embedding embedding-fn s)] |
139 | 134 | (vec-db/search-vectors connection vec options))) |
140 | 135 |
|
141 | | -;; ================================================== |
142 | | -;; Perform Embeddings |
143 | | -;; ================================================== |
144 | | -(defn summarize-registration [registration] |
145 | | - (str |
146 | | - #_(format "This tool comes from %s\n%s\n" (:server_name registration) (:server_title registration)) |
147 | | - (format "It provides the tool %s %s - %s\n" (-> registration :tool :name) (or (-> registration :tool :title) "") (-> registration :tool :description)) |
148 | | - (format "Input parameters are %s" (->> registration |
149 | | - :tool |
150 | | - :inputSchema |
151 | | - :properties |
152 | | - (map (fn [[k v]] (format "%s %s\n" (name k) (:description v)))) |
153 | | - (apply str))))) |
154 | | - |
155 | | -(defn summarize-tools [tool-registrations] |
156 | | - (doseq [tool-registration tool-registrations] |
157 | | - (println "-------" (-> tool-registration :tool :name) "--------" (count (json/generate-string tool-registration))) |
158 | | - (println (try |
159 | | - (summarize-tool |
160 | | - (partial dmr-completion summary-model) |
161 | | - (json/generate-string tool-registration)) |
162 | | - (catch Throwable _ "failed to summarize"))))) |
163 | | - |
164 | | -(defn embed-servers |
165 | | - "embed the server descriptions" |
166 | | - [{:keys [embedding-fn summarize-fn connection]} collection servers] |
167 | | - (println "> embed " (:name collection)) |
168 | | - (async/go |
169 | | - (async/<! (vec-db/delete-collection connection (:name collection))) |
170 | | - (async/<! (vec-db/create-collection connection (:name collection))) |
171 | | - (doseq [server servers :let [summary |
172 | | - (summarize-fn server)]] |
173 | | - (println " > embed " (-> server :name) " -> " (count summary)) |
174 | | - (let [vec (create-embedding embedding-fn summary)] |
175 | | - (async/<!! (vec-db/add-vector connection (:name collection) vec (select-keys server [:name]))))))) |
176 | | - |
177 | | -(defn embed-server-tools |
178 | | - "embed the server descriptions" |
179 | | - [{:keys [embedding-fn summarize-fn connection]} collection tool-registrations] |
180 | | - (println "> embed " (:name collection)) |
181 | | - (async/go |
182 | | - (async/<! (vec-db/delete-collection connection (:name collection))) |
183 | | - (async/<! (vec-db/create-collection connection (:name collection))) |
184 | | - (doseq [tool-registration tool-registrations :let [summary (summarize-fn tool-registration)]] |
185 | | - (let [vec (time (create-embedding embedding-fn summary))] |
186 | | - (println " > embed " (-> tool-registration :tool :name) " -> " (count summary)) |
187 | | - (async/<!! (vec-db/add-vector connection (:name collection) vec {:tool (select-keys (:tool tool-registration) [:name])})))))) |
188 | | - |
189 | | -(defn json-with-token-check [tool-registration] |
190 | | - (let [json (json/generate-string tool-registration)] |
191 | | - (if (< 2048 (tolkien/count-tokens "text-embedding-3-small" json)) |
192 | | - (-> tool-registration |
193 | | - (update :tool dissoc :outputSchema) |
194 | | - (json/generate-string)) |
195 | | - json))) |
196 | | - |
197 | | -(def servers |
198 | | - ["github-official" "gitmcp" "slack" "fetch" "duckduckgo" |
199 | | - "brave" "context7" "dockerhub" "playwright" "wikipedia-mcp" "SQLite" "notion-remote" "rust-mcp-filesystem" "arxiv-mcp-server" "google-maps" "google-maps-comprehensive" "hugging-face" "linkedin-mcp-server" "desktop-commander" |
200 | | - "openbnb-airbnb" |
201 | | - "youtube_transcript" |
202 | | - "time" |
203 | | - "sequentialthinking" |
204 | | - "semgrep" |
205 | | - "resend" |
206 | | - "papersearch" |
207 | | - "openweather" |
208 | | - "openapi-schema" |
209 | | - "openapi" |
210 | | - "node-code-sandbox" |
211 | | - "minecraft-wiki" |
212 | | - "microsoft-learn" |
213 | | - "memory" |
214 | | - "mcp-hackernews" |
215 | | - "maven-tools-mcp" |
216 | | - "markitdown" |
217 | | - "gemini-api-docs" |
218 | | - "filesystem" |
219 | | - "everart" |
220 | | - "stripe" |
221 | | - "elevenlabs"]) |
222 | | - |
223 | | -(def fetch (memoize (fn [url] (try (:body (curl/get url)) (catch Throwable _ ""))))) |
224 | | - |
225 | | -(defn filter-names [coll] (->> coll (map :name))) |
226 | | - |
227 | | -(defn read-catalog [] |
228 | | - (->> (slurp "/Users/slim/.docker/mcp/catalogs/docker-mcp.yaml") |
229 | | - (yaml/parse-string) |
230 | | - :registry |
231 | | - (map (fn [[k v]] (assoc (select-keys v [:title :description :type :readme :toolsUrl]) :name (name k)))) |
232 | | - #_(map (fn [m] (update m :readme fetch))) |
233 | | - (map (fn [m] (update m :toolsUrl (comp filter-names (fn [s] (json/parse-string s keyword)) fetch)))) |
234 | | - (map #(assoc % :tokens ((comp (partial tolkien/count-tokens "text-embedding-3-small") json/generate-string) %))))) |
235 | | - |
236 | | -(comment |
237 | | - ;; make 3 connections |
238 | | - (def connection (vec-db/vector-db-stdio-server {:dimension 1536 :db "vectors.db"})) |
239 | | - (async/<!! (vec-db/create-collection connection "hello2")) |
240 | | - (async/<!! (vec-db/list-collections connection)) |
241 | | - |
242 | | - (count servers) |
243 | | - (reduce + |
244 | | - (for [s servers] |
245 | | - (count |
246 | | - (vals |
247 | | - (json/parse-string (slurp (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s))))))) |
248 | | - (float (/ (reduce + (for [s servers] |
249 | | - (count (slurp (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s))))) 4)) |
250 | | - |
251 | | - ;; cleanup |
252 | | - (async/<!! |
253 | | - (async/go |
254 | | - (doseq [item (async/<! (vec-db/list-collections vec-db-connection))] |
255 | | - (println "delete " item) |
256 | | - (async/<! (vec-db/delete-collection vec-db-connection (:name item)))))) |
257 | | - |
258 | | - ;; make sure the model has been pulled |
259 | | - (dmr-models) |
260 | | - (dmr-get-model "ai" "embeddinggemma:latest") |
261 | | - (dmr-create-model embedding-model) |
262 | | - (dmr-create-model summary-model) |
263 | | - |
264 | | - ;; sembeds about 1 tool / second |
265 | | - ;; embed using GPT text-embedding-3-small (dimension is 1536) |
266 | | - ;; average 400ms per tool at 2m21s total |
267 | | - (time |
268 | | - (doseq [s servers] |
269 | | - (async/<!! |
270 | | - (embed-server-tools |
271 | | - {:embedding-fn (partial dmr-embeddings "ai/qwen3-embedding") ;gpt-embeddings |
272 | | - :summarize-fn json-with-token-check} |
273 | | - {:name s} |
274 | | - (vals |
275 | | - (json/parse-string |
276 | | - (slurp |
277 | | - (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s)) keyword)))))) |
278 | | - |
279 | | - ;; embed servers |
280 | | - (def catalog (read-catalog)) |
281 | | - (->> catalog |
282 | | - (filter #(< 8191 (:tokens %))) |
283 | | - (map #(select-keys % [:name :tokens]))) |
284 | | - (time |
285 | | - (async/<!! |
286 | | - (embed-servers |
287 | | - {:embedding-fn (partial dmr-embeddings "ai/qwen3-embedding") ;gpt-embeddings |
288 | | - :summarize-fn json/generate-string} |
289 | | - {:name "mcp-server-collection"} |
290 | | - catalog))) |
291 | | - |
292 | | - ;; search tools |
293 | | - (def search-config {:embedding-fn (partial dmr-embeddings "ai/qwen3-embedding") ;gpt-embeddings |
294 | | - :exclude_collections ["mcp-server-collection"]}) |
295 | | - (async/<!! (search search-config "I need to find github pull requests and I don't care about issues")) |
296 | | - (async/<!! (search search-config "create a new pull request on github")) |
297 | | - (async/<!! (search search-config "run bash on something")) |
298 | | - (async/<!! (search search-config "do a wikipedia search")) |
299 | | - (async/<!! (search search-config "are there any air bnb apartments in SF")) |
300 | | - (async/<!! (search search-config "I need to do a security scan")) |
301 | | - |
302 | | - ;; search servers |
303 | | - (def server-search-config {:collection_name "mcp-server-collection" |
304 | | - :embedding-fn (partial dmr-embeddings "ai/qwen3-embedding")}) |
305 | | - (async/<!! (search server-search-config "what if I need to integrate with different chat systems"))) |
306 | | - |
307 | | -(comment |
308 | | - |
309 | | - ; semgrep_scan 10781 bigger than 4096. |
310 | | - (doseq [s servers] |
311 | | - (println |
312 | | - s |
313 | | - " -> " |
314 | | - (-> |
315 | | - (vals (json/parse-string (slurp (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s)) keyword)) |
316 | | - (json/generate-string) |
317 | | - (count)))) |
318 | | - |
319 | | - ; experiment - summarize all of the tool metadata |
320 | | - (doseq [s servers] |
321 | | - (summarize-tools |
322 | | - (vals (json/parse-string (slurp (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s)) keyword)))) |
323 | | - |
324 | | - ;; all tools should have less than 2048 tokens in the data being embedded - should be empty |
325 | | - (->> |
326 | | - (for [s servers] |
327 | | - (for [tool (vals (json/parse-string (slurp (format "/Users/slim/docker/mcp-gateway/examples/tool_registrations/tool-json/%s.json" s)) keyword))] |
328 | | - [s (-> tool :tool :name) (tolkien/count-tokens "text-embedding-3-small" (json-with-token-check tool))])) |
329 | | - (apply concat) |
330 | | - (filter (fn [[_ _ n]] (< 2048 n))))) |
331 | | - |
0 commit comments