|
1 | 1 | (ns eca.features.chat |
2 | 2 | (:require |
3 | | - [babashka.fs :as fs] |
4 | 3 | [cheshire.core :as json] |
5 | 4 | [clojure.set :as set] |
6 | 5 | [clojure.string :as string] |
| 6 | + [eca.features.context :as f.context] |
7 | 7 | [eca.features.index :as f.index] |
8 | 8 | [eca.features.prompt :as f.prompt] |
9 | 9 | [eca.features.rules :as f.rules] |
|
18 | 18 |
|
19 | 19 | (def ^:private logger-tag "[CHAT]") |
20 | 20 |
|
21 | | -(defn ^:private raw-contexts->refined [contexts db] |
22 | | - (mapcat (fn [{:keys [type path lines-range uri]}] |
23 | | - (case (name type) |
24 | | - "file" [{:type :file |
25 | | - :path path |
26 | | - :partial (boolean lines-range) |
27 | | - :content (llm-api/refine-file-context path lines-range)}] |
28 | | - "directory" (->> (fs/glob path "**") |
29 | | - (remove fs/directory?) |
30 | | - (map (fn [path] |
31 | | - (let [filename (str (fs/canonicalize path))] |
32 | | - {:type :file |
33 | | - :path filename |
34 | | - :content (llm-api/refine-file-context filename nil)})))) |
35 | | - "repoMap" [{:type :repoMap}] |
36 | | - "mcpResource" (mapv |
37 | | - (fn [{:keys [text]}] |
38 | | - {:type :mcpResource |
39 | | - :uri uri |
40 | | - :content text}) |
41 | | - (:contents (f.mcp/get-resource! uri db))))) |
42 | | - contexts)) |
43 | | - |
44 | 21 | (defn default-model [db config] |
45 | 22 | (llm-api/default-model db config)) |
46 | 23 |
|
|
144 | 121 | (let [db @db* |
145 | 122 | manual-approval? (get-in config [:toolCall :manualApproval] false) |
146 | 123 | rules (f.rules/all config (:workspace-folders db)) |
147 | | - refined-contexts (raw-contexts->refined contexts db) |
| 124 | + refined-contexts (f.context/raw-contexts->refined contexts db) |
148 | 125 | repo-map* (delay (f.index/repo-map db {:as-string? true})) |
149 | 126 | instructions (f.prompt/build-instructions refined-contexts rules repo-map* (or behavior (:chat-default-behavior db)) config) |
150 | 127 | past-messages (get-in db [:chats chat-id :messages] []) |
|
292 | 269 | {:keys [db*] :as chat-ctx}] |
293 | 270 | (let [{:keys [arguments]} (first (filter #(= prompt (:name %)) (f.mcp/all-prompts @db*))) |
294 | 271 | args-vals (zipmap (map :name arguments) args) |
295 | | - {:keys [messages]} (f.mcp/get-prompt! prompt args-vals @db*)] |
296 | | - (prompt-messages! messages false chat-ctx))) |
| 272 | + {:keys [messages error-message]} (f.prompt/get-prompt! prompt args-vals @db*)] |
| 273 | + (if error-message |
| 274 | + (send-content! chat-ctx :system |
| 275 | + {:type :text |
| 276 | + :text error-message}) |
| 277 | + (prompt-messages! messages false chat-ctx)))) |
297 | 278 |
|
298 | 279 | (defn ^:private handle-command! [{:keys [command]} {:keys [chat-id db* model] :as chat-ctx}] |
299 | 280 | (let [db @db*] |
|
355 | 336 | (defn tool-call-reject [{:keys [chat-id tool-call-id]} db*] |
356 | 337 | (deliver (get-in @db* [:chats chat-id :tool-calls tool-call-id :approved?*]) false)) |
357 | 338 |
|
358 | | -(defn ^:private contexts-for [root-filename query config] |
359 | | - (let [all-files (fs/glob root-filename (str "**" (or query "") "**")) |
360 | | - allowed-files (f.index/filter-allowed all-files root-filename config)] |
361 | | - allowed-files)) |
362 | | - |
363 | 339 | (defn query-context |
364 | 340 | [{:keys [query contexts chat-id]} |
365 | 341 | db* |
366 | 342 | config] |
367 | | - (let [all-subfiles-and-dirs (into [] |
368 | | - (comp |
369 | | - (map :uri) |
370 | | - (map shared/uri->filename) |
371 | | - (mapcat #(contexts-for % query config)) |
372 | | - (take 200) ;; for performance, user can always make query specific for better results. |
373 | | - (map (fn [file-or-dir] |
374 | | - {:type (if (fs/directory? file-or-dir) |
375 | | - :directory |
376 | | - :file) |
377 | | - :path (str (fs/canonicalize file-or-dir))}))) |
378 | | - (:workspace-folders @db*)) |
379 | | - root-dirs (mapv (fn [{:keys [uri]}] {:type :directory |
380 | | - :path (shared/uri->filename uri)}) |
381 | | - (:workspace-folders @db*)) |
382 | | - mcp-resources (mapv #(assoc % :type :mcpResource) (f.mcp/all-resources @db*)) |
383 | | - all-contexts (concat [{:type :repoMap}] |
384 | | - root-dirs |
385 | | - all-subfiles-and-dirs |
386 | | - mcp-resources)] |
387 | | - {:chat-id chat-id |
388 | | - :contexts (set/difference (set all-contexts) |
389 | | - (set contexts))})) |
| 343 | + {:chat-id chat-id |
| 344 | + :contexts (set/difference (set (f.context/all-contexts query db* config)) |
| 345 | + (set contexts))}) |
390 | 346 |
|
391 | 347 | (defn query-commands |
392 | 348 | [{:keys [query chat-id]} |
|
0 commit comments