|
1 | 1 |
|
2 | 2 | {} (:about "|file is generated - never edit directly; learn cr edit/tree workflows before changing") (:package |app) |
3 | 3 | :configs $ {} (:init-fn |app.main/main!) (:reload-fn |app.main/reload!) (:version |0.0.1) |
4 | | - :modules $ [] |respo.calcit/ |lilac/ |memof/ |respo-ui.calcit/ |reel.calcit/ |respo-markdown.calcit/ |alerts.calcit/ |respo-feather.calcit/ |
| 4 | + :modules $ [] |respo.calcit/ |lilac/ |memof/ |respo-ui.calcit/ |reel.calcit/ |respo-markdown.calcit/ |alerts.calcit/ |respo-feather.calcit/ |genai.calcit/ |
5 | 5 | :entries $ {} |
6 | 6 | :files $ {} |
7 | 7 | |app.comp.container $ %{} :FileEntry |
|
113 | 113 | :code $ quote |
114 | 114 | defn call-flash-imagen-msg! (variant cursor state prompt-text d!) (hint-fn async) |
115 | 115 | if (nil? @*gen-ai-new) |
116 | | - reset! *gen-ai-new $ new GoogleGenAI |
117 | | - js-object $ :apiKey (get-gemini-key!) |
| 116 | + reset! *gen-ai-new $ sdk/new-client (get-gemini-key!) |
118 | 117 | if-let |
119 | 118 | target $ js/document.querySelector "\".show-image" |
120 | 119 | .!setAttribute target "\"src" "\"" |
|
126 | 125 | -> state (assoc :answer nil) (assoc :loading? true) |
127 | 126 | let |
128 | 127 | selected $ js-await (get-selected) |
129 | | - gen-ai $ let |
130 | | - ai @*gen-ai-new |
131 | | - js/console.log ai |
132 | | - , ai |
| 128 | + gen-ai @*gen-ai-new |
133 | 129 | content $ .!replace prompt-text "\"{{selected}}" (or selected "\"<未找到选中内容>") |
134 | 130 | sdk-result $ js-await |
135 | | - .!generateContent (.-models gen-ai) |
136 | | - js-object (:model "\"gemini-2.5-flash-image") (:contents content) |
137 | | - :config $ js-object |
138 | | - :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
139 | | - :signal $ let |
140 | | - abort $ new js/AbortController |
141 | | - reset! *abort-control abort |
142 | | - .-signal abort |
143 | | - :responseModalities $ js-array (.-TEXT Modality) (.-IMAGE Modality) |
| 131 | + sdk/generate-content! gen-ai $ {} (:model "\"gemini-2.5-flash-image") (:contents content) |
| 132 | + :abort-signal $ sdk/make-abort-signal *abort-control |
| 133 | + :http-options $ sdk/make-http-options |https://ja.chenyong.life |
| 134 | + :response-modalities $ js-array "\"TEXT" "\"IMAGE" |
144 | 135 | *text $ atom "\"" |
145 | | - js-await $ -> sdk-result .-candidates .-0 .-content .-parts |
| 136 | + js-await $ -> (sdk/extract-content-parts sdk-result) |
146 | 137 | .!forEach $ fn (? chunk _a _b) |
147 | 138 | if (some? chunk) |
148 | 139 | if-let |
|
170 | 161 | :code $ quote |
171 | 162 | defn call-genai-msg! (variant cursor state prompt-text search? think? d! *text *thinking-text) (hint-fn async) |
172 | 163 | if (nil? @*gen-ai-new) |
173 | | - reset! *gen-ai-new $ new GoogleGenAI |
174 | | - js-object $ :apiKey (get-gemini-key!) |
| 164 | + reset! *gen-ai-new $ sdk/new-client (get-gemini-key!) |
175 | 165 | if-let |
176 | 166 | abort $ deref *abort-control |
177 | 167 | do (js/console.warn "\"Aborting prev") (.!abort abort) |
178 | 168 | let |
179 | 169 | selected $ if (.includes? prompt-text "\"{{selected}}") |
180 | 170 | js-await $ get-selected |
181 | | - gen-ai $ let |
182 | | - ai @*gen-ai-new |
183 | | - , ai |
| 171 | + gen-ai @*gen-ai-new |
184 | 172 | model $ pick-model variant |
185 | 173 | content $ .!replace prompt-text "\"{{selected}}" (or selected "\"<未找到选中内容>") |
186 | 174 | json? $ or (.!includes prompt-text "\"{{json}}") (.!includes prompt-text "\"{{JSON}}") |
|
189 | 177 | messages0 $ or (:messages state) ([]) |
190 | 178 | messages1 $ upsert-assistant-message messages0 "\"" nil |
191 | 179 | sdk-result $ js-await |
192 | | - .!generateContentStream (.-models gen-ai) |
193 | | - js-object (:model model) |
194 | | - :contents $ messages->gemini messages0 |
195 | | - :config $ js/Object.assign |
196 | | - js-object |
197 | | - :thinkingConfig $ if think? |
198 | | - js-object |
199 | | - :thinkingBudget $ get-env "\"think-budget" (if pro? 3200 800) |
200 | | - :includeThoughts think? |
201 | | - js-object (:thinkingBudget 0) (:includeThoughts false) |
202 | | - :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
203 | | - :tools $ let |
204 | | - t $ -> |
205 | | - js-array |
206 | | - if search? $ js-object |
207 | | - :googleSearch $ js-object |
208 | | - if has-url? $ js-object |
209 | | - :urlContext $ js-object |
210 | | - .!filter $ fn (x & _a) x |
211 | | - if |
212 | | - = 0 $ .-length t |
213 | | - , js/undefined t |
214 | | - :abortSignal $ let |
215 | | - abort $ new js/AbortController |
216 | | - reset! *abort-control abort |
217 | | - .-signal abort |
218 | | - if json? |
219 | | - js-object $ "\"responseMimeType" "\"application/json" |
220 | | - , js/undefined |
| 180 | + sdk/generate-content-stream! gen-ai $ {} (:model model) |
| 181 | + :contents $ sdk/messages->contents messages0 |
| 182 | + :thinking-config $ if think? |
| 183 | + sdk/make-thinking-config |
| 184 | + get-env "\"think-budget" $ if pro? 3200 800 |
| 185 | + , true |
| 186 | + sdk/make-thinking-config 0 false |
| 187 | + :tools $ sdk/make-search-tools search? has-url? |
| 188 | + :abort-signal $ sdk/make-abort-signal *abort-control |
| 189 | + :http-options $ sdk/make-http-options |https://ja.chenyong.life |
| 190 | + :response-mime-type $ if json? "\"application/json" nil |
221 | 191 | do |
222 | 192 | js/setTimeout $ fn () |
223 | 193 | d! $ :: :states-merge cursor state |
|
226 | 196 | fn (? chunk) |
227 | 197 | if (some? chunk) |
228 | 198 | let |
229 | | - part js/chunk.candidates?.[0]?.content?.parts?.[0] |
230 | | - is-thinking? $ if (some? part) (.-thought part) false |
231 | | - t $ if (some? part) (.-text part) (.-text chunk) |
232 | | - let |
233 | | - text $ or t (-> chunk .?-promptFeedback .?-blockReason) |__BLANK__ |
234 | | - if is-thinking? (swap! *thinking-text str text) (swap! *text str text) |
235 | | - d! $ :: :states-merge cursor state |
236 | | - {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
237 | | - :messages $ upsert-assistant-message messages1 @*text @*thinking-text |
238 | | - d! $ :: :states-merge cursor state |
239 | | - {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
240 | | - :messages $ upsert-assistant-message messages1 @*text @*thinking-text |
| 199 | + info $ sdk/extract-stream-chunk chunk |
| 200 | + is-thinking? $ :thinking? info |
| 201 | + text $ or (:text info) |__BLANK__ |
| 202 | + if is-thinking? (swap! *thinking-text str text) (swap! *text str text) |
| 203 | + d! $ :: :states-merge cursor state |
| 204 | + {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
| 205 | + :messages $ upsert-assistant-message messages1 @*text @*thinking-text |
| 206 | + d! $ :: :states-merge cursor state |
| 207 | + {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
| 208 | + :messages $ upsert-assistant-message messages1 @*text @*thinking-text |
241 | 209 | d! $ :: :states-merge cursor state |
242 | 210 | {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? true) |
243 | 211 | :messages $ upsert-assistant-message messages1 @*text @*thinking-text |
|
246 | 214 | :code $ quote |
247 | 215 | defn call-imagen-4-msg! (variant cursor state prompt-text d!) (hint-fn async) |
248 | 216 | if (nil? @*gen-ai-new) |
249 | | - reset! *gen-ai-new $ new GoogleGenAI |
250 | | - js-object $ :apiKey (get-gemini-key!) |
| 217 | + reset! *gen-ai-new $ sdk/new-client (get-gemini-key!) |
251 | 218 | if-let |
252 | 219 | target $ js/document.querySelector "\".show-image" |
253 | 220 | .!removeAttribute target "\"src" |
|
259 | 226 | -> state (assoc :answer nil) (assoc :loading? true) |
260 | 227 | let |
261 | 228 | selected $ js-await (get-selected) |
262 | | - gen-ai $ let |
263 | | - ai @*gen-ai-new |
264 | | - , ai |
| 229 | + gen-ai @*gen-ai-new |
265 | 230 | response $ js-await |
266 | | - .!generateImages (.-models gen-ai) |
267 | | - js-object (:model "\"imagen-4.0-generate-001") (:prompt prompt-text) |
268 | | - :config $ js-object (:numberOfImages 1) (:includeRaiReason true) |
269 | | - :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
270 | | - :signal $ let |
271 | | - abort $ new js/AbortController |
272 | | - reset! *abort-control abort |
273 | | - .-signal abort |
| 231 | + sdk/generate-images! gen-ai $ {} (:model "\"imagen-4.0-generate-001") (:prompt prompt-text) (:number-of-images 1) (:include-rai-reason true) |
| 232 | + :abort-signal $ sdk/make-abort-signal *abort-control |
| 233 | + :http-options $ sdk/make-http-options |https://ja.chenyong.life |
274 | 234 | *text $ atom "\"" |
275 | 235 | if-let |
276 | | - image-data $ -> response .-generatedImages .-0 .-image .-imageBytes |
| 236 | + image-data $ sdk/extract-image-bytes response |
277 | 237 | let |
278 | 238 | image-blob $ base64ToBlob image-data |
279 | 239 | url $ js/URL.createObjectURL image-blob |
|
1176 | 1136 | respo-ui.comp :refer $ comp-copy comp-close |
1177 | 1137 | "\"../extension/get-selected" :refer $ get-selected |
1178 | 1138 | memof.once :refer $ memof1-call memof1-call-by |
1179 | | - "\"@google/genai" :refer $ GoogleGenAI Modality |
1180 | 1139 | "\"../lib/image" :refer $ base64ToBlob |
1181 | 1140 | "\"openai" :default OpenAI |
1182 | 1141 | feather.core :refer $ comp-i |
1183 | 1142 | respo-alerts.core :refer $ [] use-modal-menu use-prompt use-drawer |
| 1143 | + genai.sdk :as sdk |
1184 | 1144 | :examples $ [] |
1185 | 1145 | |app.config $ %{} :FileEntry |
1186 | 1146 | :defs $ {} |
|
0 commit comments