|
6 | 6 | [clojure.core :as c]
|
7 | 7 | [clojure.core.async :as async]
|
8 | 8 | [clojure.pprint :as pprint]
|
| 9 | + [clojure.string :as string] |
| 10 | + docker |
9 | 11 | git
|
10 | 12 | graph
|
11 | 13 | jsonrpc
|
|
93 | 95 |
|
94 | 96 | (defn entry->prompt-listing [k v _messages]
|
95 | 97 | (merge
|
96 |
| - {:name (str k)} |
97 |
| - (select-keys (:metadata v) [:description]))) |
| 98 | + {:name (str k)} |
| 99 | + (select-keys (:metadata v) [:description]))) |
98 | 100 |
|
99 | 101 | (defmethod lsp.server/receive-request "prompts/list" [_ {:keys [db*]} params]
|
100 | 102 | ;; TODO might contain a cursor
|
|
211 | 213 | (defrecord TimbreLogger []
|
212 | 214 | logger/ILogger
|
213 | 215 | (setup [this]
|
214 |
| - (let [log-path (str (fs/file "/prompts/docker-mcp-server.out"))] |
| 216 | + (fs/create-dirs (fs/file "/prompts" "log")) |
| 217 | + (let [log-path (str (fs/file "/prompts/log/docker-mcp-server.out"))] |
215 | 218 | (timbre/merge-config! {:middleware [#(assoc % :hostname_ "")]
|
216 | 219 | :appenders {:println {:enabled? false}
|
217 | 220 | :spit (appenders/spit-appender {:fname log-path})}})
|
|
253 | 256 | (->> params (lsp.server/send-notification server "notifications/message")))
|
254 | 257 |
|
255 | 258 | (publish-prompt-list-changed [_ params]
|
| 259 | + (logger/info "send prompt list changed") |
256 | 260 | (->> params (lsp.server/send-notification server "notifications/prompts/list_changed")))
|
257 | 261 |
|
258 | 262 | (publish-resource-list-changed [_ params]
|
|
262 | 266 | (->> params (lsp.server/send-notification server "notifications/resources/updated")))
|
263 | 267 |
|
264 | 268 | (publish-tool-list-changed [_ params]
|
| 269 | + (logger/info "send tool list changed") |
265 | 270 | (->> params (lsp.server/send-notification server "notifications/tools/list_changed")))
|
266 | 271 | (publish-docker-notify [_ method params]
|
267 | 272 | (lsp.server/send-notification server method params)))
|
|
289 | 294 | :producer producer
|
290 | 295 | :server server}]
|
291 | 296 | (swap! db* merge {:log-path log-path} (dissoc opts :in))
|
| 297 | + ;; register static prompts |
292 | 298 | (when (:register opts)
|
293 | 299 | (try
|
294 | 300 | (db/add opts)
|
295 | 301 | (catch Throwable t
|
296 | 302 | (logger/error t))))
|
| 303 | + ;; register dynamic prompts |
| 304 | + (when (fs/exists? (fs/file "/prompts/registry.yaml")) |
| 305 | + (db/merge (assoc opts :registry-content (slurp "/prompts/registry.yaml")))) |
| 306 | + ;; watch dynamic prompts in background |
| 307 | + (async/thread |
| 308 | + (docker/run-streaming-function-with-no-stdin |
| 309 | + {:image "vonwig/inotifywait:latest" |
| 310 | + :volumes ["docker-prompts:/prompts"] |
| 311 | + :command ["-e" "create" "-e" "modify" "-e" "delete" "-q" "-m" "/prompts"] |
| 312 | + :opts {:Tty true |
| 313 | + :StdinOnce false |
| 314 | + :OpenStdin false |
| 315 | + :AttachStdin false}} |
| 316 | + (fn [line] |
| 317 | + (logger/info "registry changed" line) |
| 318 | + (let [[_dir _event f] (string/split line #"\s+")] |
| 319 | + (when (= f "registry.yaml") |
| 320 | + (try |
| 321 | + (db/merge (assoc opts :registry-content (slurp "/prompts/registry.yaml"))) |
| 322 | + (producer/publish-tool-list-changed producer {}) |
| 323 | + (producer/publish-prompt-list-changed producer {}) |
| 324 | + (catch Throwable t |
| 325 | + (logger/error t "unable to parse registry.yaml")))))))) |
297 | 326 | (monitor-server-logs log-ch)
|
298 | 327 | (logger/info "Starting server...")
|
299 | 328 | [producer (lsp.server/start server components)])))
|
|
0 commit comments