|
159 | 159 | function-name - the name of the function that the LLM has selected
|
160 | 160 | json-arg-string - the JSON arg string that the LLM has generated
|
161 | 161 | resolve fail - callbacks"
|
162 |
| - [{:keys [functions user pat thread-volume save-thread-volume] :as opts} function-name json-arg-string {:keys [resolve fail]}] |
| 162 | + [{:keys [functions user pat thread-id offline] :as opts} function-name json-arg-string {:keys [resolve fail]}] |
163 | 163 | (if-let [definition (->
|
164 | 164 | (->> (filter #(= function-name (-> % :function :name)) functions)
|
165 | 165 | first)
|
|
175 | 175 | (if json-arg-string [json-arg-string] ["{}"])
|
176 | 176 | (when-let [c (-> definition :container :command)] c))}
|
177 | 177 | (when user {:user user})
|
178 |
| - (when pat {:pat pat}) |
179 |
| - (when thread-volume {:thread-volume thread-volume}) |
180 |
| - (when (true? save-thread-volume) {:save-thread-volume true})) |
| 178 | + (when pat {:pat pat})) |
181 | 179 | {:keys [pty-output exit-code]} (docker/run-function function-call)]
|
182 | 180 | (if (= 0 exit-code)
|
183 | 181 | (resolve pty-output)
|
184 | 182 | (fail (format "call exited with non-zero code (%d): %s" exit-code pty-output))))
|
185 | 183 | (= "prompt" (:type definition)) ;; asynchronous call to another agent - new conversation-loop
|
186 | 184 | ;; TODO set a custom map for prompts in the next conversation loop
|
187 | 185 | (let [{:keys [messages _finish-reason] :as m}
|
188 |
| - (async/<!! (conversation-loop |
189 |
| - (:host-dir opts) |
190 |
| - (:user opts) |
191 |
| - (:host-dir opts) |
192 |
| - (:ref definition)))] |
| 186 | + (async/<!! (apply conversation-loop |
| 187 | + (concat |
| 188 | + [(:host-dir opts) |
| 189 | + (:user opts) |
| 190 | + (:host-dir opts) |
| 191 | + (:ref definition)] |
| 192 | + (when pat [:pat pat]) |
| 193 | + (when offline [:offline true]) |
| 194 | + [:thread-id thread-id])))] |
193 | 195 | (jsonrpc/notify :message {:debug (with-out-str (pprint m))})
|
194 | 196 | (resolve (->> messages
|
195 | 197 | (filter #(= "assistant" (:role %)))
|
|
208 | 210 | args for extracting functions, host-dir, user, platform
|
209 | 211 | returns channel that will contain the final set of messages and a finish-reason"
|
210 | 212 | [prompts & args]
|
211 |
| - (let [[host-dir user platform prompts-dir & {:keys [url pat save-thread-volume thread-id]}] args |
| 213 | + (let [[host-dir user platform prompts-dir & {:keys [url pat save-thread-volume offline thread-id]}] args |
212 | 214 | prompt-dir (get-dir prompts-dir)
|
213 | 215 | m (collect-metadata prompt-dir)
|
214 | 216 | functions (collect-functions prompt-dir)
|
|
221 | 223 | :platform platform}
|
222 | 224 | (when pat {:pat pat})
|
223 | 225 | (when save-thread-volume {:save-thread-volume true})
|
224 |
| - (if thread-id |
225 |
| - {:thread-volume thread-id} |
226 |
| - {:thread-volume (str (random-uuid))}))))] |
| 226 | + (when offline {:offline true}) |
| 227 | + {:thread-id thread-id})))] |
227 | 228 | (try
|
228 | 229 | (openai/openai
|
229 | 230 | (merge
|
230 | 231 | {:messages prompts}
|
231 | 232 | (when (seq functions) {:tools functions})
|
232 | 233 | (when url {:url url})
|
233 | 234 | m) h)
|
234 |
| - (catch ConnectException t |
| 235 | + (catch ConnectException _ |
235 | 236 | ;; when the conversation-loop can not connect to an openai compatible endpoint
|
236 | 237 | (async/>!! c {:messages [{:role "assistant" :content "I cannot connect to an openai compatible endpoint."}]
|
237 | 238 | :finish-reason "error"}))
|
|
262 | 263 | (jsonrpc/notify :message {:debug (with-out-str (pprint m))})
|
263 | 264 | {:messages (concat prompts messages) :done finish-reason})))))
|
264 | 265 |
|
| 266 | +(defn- with-volume [f & {:keys [thread-id save-thread-volume]}] |
| 267 | + (let [thread-id (or thread-id (str (random-uuid)))] |
| 268 | + (try |
| 269 | + (docker/thread-volume {:Name thread-id}) |
| 270 | + (f thread-id) |
| 271 | + (finally |
| 272 | + (when (not (true? save-thread-volume)) |
| 273 | + (docker/delete-thread-volume {:Name thread-id})))))) |
| 274 | + |
265 | 275 | (defn- -run-command
|
266 | 276 | " returns map result"
|
267 | 277 | [& args]
|
|
290 | 300 | (update-in m [:prompts] (fn [coll] (remove (fn [{:keys [type]}] (= type (second args))) coll)))))
|
291 | 301 |
|
292 | 302 | (= "run" (first args))
|
293 |
| - (select-keys |
294 |
| - (async/<!! (apply conversation-loop (rest args))) |
295 |
| - [:done]) |
| 303 | + (with-volume |
| 304 | + (fn [thread-id] |
| 305 | + (select-keys |
| 306 | + (async/<!! (apply conversation-loop (concat (rest args) [:thread-id thread-id]))) |
| 307 | + [:done])) |
| 308 | + (rest args)) |
296 | 309 |
|
297 | 310 | :else
|
298 | 311 | (apply get-prompts args)))
|
|
0 commit comments