|
2 | 2 | (:require
|
3 | 3 | [babashka.fs :as fs]
|
4 | 4 | [clojure.core.async :as async]
|
5 |
| - [clojure.pprint :refer [pprint]] |
6 | 5 | [clojure.core.match :refer [match]]
|
7 | 6 | git
|
8 | 7 | jsonrpc
|
|
72 | 71 | [state]
|
73 | 72 | (run-llm (:messages state) (dissoc (:metadata state) :agent) (:functions state) (:opts state)))
|
74 | 73 |
|
75 |
| -;; TODO does the LangGraph Tool Node always search for the a tool_call |
76 | 74 | (defn tool
|
77 | 75 | "execute the tool_calls from the last AI message in the conversation"
|
78 | 76 | [state]
|
|
97 | 95 | [_]
|
98 | 96 | (async/go {}))
|
99 | 97 |
|
100 |
| -(defn construct-initial-state-from-prompts [{{:keys [prompts] :as opts} :opts :as state}] |
101 |
| - (try |
102 |
| - (-> state |
103 |
| - (merge |
104 |
| - {:metadata (prompts/collect-metadata prompts) |
105 |
| - :functions (prompts/collect-functions prompts) |
106 |
| - :opts (merge opts {:level (or (:level opts) 0)})}) |
107 |
| - (update |
108 |
| - :messages |
109 |
| - (fnil concat []) |
110 |
| - (when (not (seq (:messages state))) |
111 |
| - (let [new-prompts (prompts/get-prompts opts)] |
112 |
| - (jsonrpc/notify :prompts {:messages new-prompts}) |
113 |
| - new-prompts)))) |
114 |
| - (catch Throwable ex |
115 |
| - (jsonrpc/notify :error {:content |
116 |
| - (format "failure for prompt configuration:\n %s" (with-out-str (pprint (dissoc opts :pat :jwt)))) |
117 |
| - :exception (str ex)})))) |
118 |
| - |
119 |
| -; tool_calls are maps with an id and a function with arguments an name |
120 |
| -; look up the full tool definition using the name |
121 |
| - |
122 |
| -(defn add-prompt-ref [state] |
123 |
| - (let [definition (state/get-function-definition state) |
124 |
| - arg-context (let [raw-args (-> state :messages last :tool_calls first :function :arguments)] |
125 |
| - (tools/arg-context raw-args))] |
126 |
| - (-> state |
127 |
| - (dissoc :messages) |
128 |
| - (update-in [:opts :level] (fnil inc 0)) |
129 |
| - (update-in [:opts :prompts] (constantly (git/prompt-file (-> definition :function :ref)))) |
130 |
| - (update-in [:opts :parameters] (constantly arg-context))))) |
131 |
| - |
132 |
| -(comment |
133 |
| - ;; TODO move this into the thingy |
134 |
| - (add-prompt-ref {:messages [{:tool_calls [{:function {:name "sql_db_list_tables" |
135 |
| - :arguments "{\"arg\": 1}"}}]}] |
136 |
| - :functions [{:function {:name "sql_db_list_tables" |
137 |
| - :description "List all tables in the database" |
138 |
| - :parameters {:type "object" |
139 |
| - :properties |
140 |
| - {:database {:type "string" :description "the database to query"}}} |
141 |
| - :ref "github:docker/labs-ai-tools-for-devs?path=prompts/curl/README.md"}}]})) |
142 |
| - |
143 | 98 | (declare stream chat-with-tools)
|
144 | 99 |
|
145 |
| -(defn add-last-message-as-tool-call |
146 |
| - [state sub-graph-state] |
147 |
| - {:messages [(-> sub-graph-state |
148 |
| - :messages |
149 |
| - last |
150 |
| - (state/add-tool-call-id (-> state :messages last :tool_calls first :id)))]}) |
151 |
| - |
152 |
| -(defn append-new-messages |
153 |
| - [state sub-graph-state] |
154 |
| - {:messages (->> (:messages sub-graph-state) |
155 |
| - (filter (complement (fn [m] (some #(= m %) (:messages state))))))}) |
156 |
| - |
157 | 100 | (defn sub-graph-node
|
158 | 101 | "create a sub-graph node that initializes a conversation from the current one,
|
159 | 102 | creates a new agent graph from the current state and returns the messages to be added
|
|
165 | 108 | (async/<!
|
166 | 109 | (stream
|
167 | 110 | ((or construct-graph chat-with-tools) state)
|
168 |
| - ((or init-state (comp construct-initial-state-from-prompts add-prompt-ref)) state)))] |
169 |
| - ((or next-state add-last-message-as-tool-call) state sub-graph-state))))) |
| 111 | + (-> |
| 112 | + ((or init-state (comp state/construct-initial-state-from-prompts state/add-prompt-ref)) state) |
| 113 | + (update-in [:opts :level] (fnil inc 0)))))] |
| 114 | + ((or next-state state/add-last-message-as-tool-call) state sub-graph-state))))) |
170 | 115 |
|
171 | 116 | ; =====================================================
|
172 | 117 | ; edge functions takes state and returns next node
|
|
280 | 225 | ["tools-query"]]
|
281 | 226 | [["end" end]]])
|
282 | 227 |
|
283 |
| -(defn one-tool-call [_] |
| 228 | +(defn generate-one-tool-call [_] |
284 | 229 | (-> {}
|
285 | 230 | (add-node "start" start)
|
286 | 231 | (add-node "completion" completion)
|
|
302 | 247 | ["completion"]]
|
303 | 248 | [["end" end]]])
|
304 | 249 |
|
305 |
| -(comment |
306 |
| - (alter-var-root #'jsonrpc/notify (fn [_] (partial jsonrpc/-println {:debug true}))) |
307 |
| - (let [x {:prompts (fs/file "/Users/slim/docker/labs-ai-tools-for-devs/prompts/curl/README.md") |
308 |
| - :platform "darwin" |
309 |
| - :user "jimclark106" |
310 |
| - :thread-id "thread" |
311 |
| - :host-dir "/Users/slim" |
312 |
| - :stream true}] |
313 |
| - (state/summarize (async/<!! (stream (chat-with-tools x) x))))) |
314 |
| - |
315 |
| -(comment |
316 |
| - (def x {:stream true, |
317 |
| - :host-dir "/Users/slim/docker/labs-make-runbook", |
318 |
| - :prompts "/Users/slim/docker/labs-ai-tools-for-devs/prompts/hub/default.md" |
319 |
| - :platform "darwin", :user "jimclark106", |
320 |
| - :thread-id "3e61ffe7-840e-4177-b84a-f6f7db58b24d"}) |
321 |
| - (state/summarize |
322 |
| - (async/<!! (stream (chat-with-tools x) x)))) |
| 250 | +; requires finish-reason to be set to tool_calls |
| 251 | +(def start-with-tool |
| 252 | + [[["start" start] |
| 253 | + [:edge tool-or-end]] |
| 254 | + [["sub-graph" (sub-graph-node {})] |
| 255 | + ["end" end]] |
| 256 | + [["tool" (tool-node {})] |
| 257 | + ["end"]]]) |
323 | 258 |
|
0 commit comments