|
8 | 8 | [simulflow.frame :as frame] |
9 | 9 | [simulflow.schema :as schema] |
10 | 10 | [simulflow.utils.core :as u] |
| 11 | + [simulflow.utils.openai :as uai] |
11 | 12 | [simulflow.utils.request :as request] |
12 | 13 | [taoensso.telemere :as t])) |
13 | 14 |
|
|
103 | 104 |
|
104 | 105 | ,) |
105 | 106 |
|
106 | | -(def delta (comp :delta first :choices)) |
107 | | - |
108 | | -(defn flow-do-completion! |
109 | | - "Handle completion requests for OpenAI LLM models" |
110 | | - [state out-c context] |
111 | | - (let [{:llm/keys [model] :openai/keys [api-key]} state] |
112 | | - ;; Start request only when the last message in the context is by the user |
113 | | - |
114 | | - (a/>!! out-c (frame/llm-full-response-start true)) |
115 | | - (let [stream-ch (try (request/stream-chat-completion (merge {:model model |
116 | | - :api-key api-key |
117 | | - :messages (:messages context) |
118 | | - :tools (mapv u/->tool-fn (:tools context))})) |
119 | | - (catch Exception e |
120 | | - (t/log! :error e)))] |
121 | | - |
122 | | - (vthread-loop [] |
123 | | - (when-let [chunk (a/<!! stream-ch)] |
124 | | - (let [d (delta chunk)] |
125 | | - (if (= chunk :done) |
126 | | - (a/>!! out-c (frame/llm-full-response-end true)) |
127 | | - (do |
128 | | - (if-let [tool-call (first (:tool_calls d))] |
129 | | - (do |
130 | | - (t/log! ["Sending tool call" tool-call]) |
131 | | - (a/>!! out-c (frame/llm-tool-call-chunk tool-call))) |
132 | | - (when-let [c (:content d)] |
133 | | - (a/>!! out-c (frame/llm-text-chunk c)))) |
134 | | - (recur))))))))) |
135 | | - |
136 | 107 | (def openai-llm-process |
137 | 108 | (flow/process |
138 | 109 | (fn |
|
141 | 112 | :params (schema/->flow-describe-parameters OpenAILLMConfigSchema) |
142 | 113 | :workload :io}) |
143 | 114 | ([params] |
144 | | - (let [state (m/decode OpenAILLMConfigSchema params mt/default-value-transformer) |
| 115 | + (let [{:llm/keys [model] :openai/keys [api-key]} (m/decode OpenAILLMConfigSchema params mt/default-value-transformer) |
145 | 116 | llm-write (a/chan 100) |
146 | 117 | llm-read (a/chan 1024)] |
147 | 118 | (vthread-loop [] |
|
150 | 121 | (t/log! :info ["AI REQUEST" (:frame/data frame)]) |
151 | 122 | (assert (or (frame/llm-context? frame) |
152 | 123 | (frame/control-interrupt-start? frame)) "Invalid frame sent to LLM. Only llm-context or interrupt-start") |
153 | | - (flow-do-completion! state llm-read (:frame/data frame)) |
| 124 | + (let [context (:frame/data frame) |
| 125 | + _ (a/>!! llm-read (frame/llm-full-response-start true)) |
| 126 | + stream-ch (request/stream-chat-completion {:model model |
| 127 | + :api-key api-key |
| 128 | + :messages (:messages context) |
| 129 | + :tools (mapv u/->tool-fn (:tools context))})] |
| 130 | + (uai/handle-completion-request! stream-ch llm-read)) |
| 131 | + |
154 | 132 | (recur)) |
155 | 133 | (t/log! {:level :info :id :llm} "Closing llm loop"))) |
156 | 134 |
|
|
0 commit comments