|
131 | 131 | .!generateContent (.-models gen-ai) |
132 | 132 | js-object (:model "\"gemini-2.5-flash-image") (:contents content) |
133 | 133 | :config $ js-object |
134 | | - :httpOptions $ js-object (:baseUrl "\"https://ja.chenyong.life") |
| 134 | + :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
135 | 135 | :signal $ let |
136 | 136 | abort $ new js/AbortController |
137 | 137 | reset! *abort-control abort |
|
164 | 164 | :examples $ [] |
165 | 165 | |call-genai-msg! $ %{} :CodeEntry (:doc |) |
166 | 166 | :code $ quote |
167 | | - defn call-genai-msg! (variant cursor state prompt-text search? think? d! *text) (hint-fn async) |
| 167 | + defn call-genai-msg! (variant cursor state prompt-text search? think? d! *text *thinking-text) (hint-fn async) |
168 | 168 | if (nil? @*gen-ai-new) |
169 | 169 | reset! *gen-ai-new $ new GoogleGenAI |
170 | 170 | js-object $ :apiKey (get-gemini-key!) |
|
200 | 200 | :thinkingBudget $ get-env "\"think-budget" (if pro? 3200 800) |
201 | 201 | :includeThoughts think? |
202 | 202 | js-object (:thinkingBudget 0) (:includeThoughts false) |
203 | | - :httpOptions $ js-object |
204 | | - :baseUrl $ get-env "\"gemini-host" "\"https://ja.chenyong.life" |
| 203 | + :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
205 | 204 | :tools $ let |
206 | 205 | t $ -> |
207 | 206 | js-array |
|
223 | 222 | js-await $ js-for-await sdk-result |
224 | 223 | fn (? chunk) |
225 | 224 | if (some? chunk) |
226 | | - do |
227 | | - swap! *text str $ let |
228 | | - t $ either (.-text chunk) js/chunk.candidates?.[0]?.content?.parts?.[0]?.text |
229 | | - if (nil? t) (js/console.warn "\"empty text in:" chunk) |
230 | | - or t (-> chunk .?-promptFeedback .?-blockReason) "\"__BLANK__" |
231 | | - d! $ :: :states-merge cursor state |
232 | | - {} (:answer @*text) (:loading? false) (:done? false) |
| 225 | + let |
| 226 | + part js/chunk.candidates?.[0]?.content?.parts?.[0] |
| 227 | + is-thinking? $ if (some? part) (.-thought part) false |
| 228 | + t $ if (some? part) (.-text part) (.-text chunk) |
| 229 | + let |
| 230 | + text $ or t (-> chunk .?-promptFeedback .?-blockReason) |__BLANK__ |
| 231 | + if is-thinking? (swap! *thinking-text str text) (swap! *text str text) |
| 232 | + d! $ :: :states-merge cursor state |
| 233 | + {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
233 | 234 | d! $ :: :states-merge cursor state |
234 | | - {} (:answer @*text) (:loading? false) (:done? false) |
| 235 | + {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? false) |
235 | 236 | d! $ :: :states-merge cursor state |
236 | | - {} (:answer @*text) (:loading? false) (:done? true) |
| 237 | + {} (:answer @*text) (:thinking @*thinking-text) (:loading? false) (:done? true) |
237 | 238 | :examples $ [] |
238 | 239 | |call-imagen-4-msg! $ %{} :CodeEntry (:doc |) |
239 | 240 | :code $ quote |
|
259 | 260 | .!generateImages (.-models gen-ai) |
260 | 261 | js-object (:model "\"imagen-4.0-generate-001") (:prompt prompt-text) |
261 | 262 | :config $ js-object (:numberOfImages 1) (:includeRaiReason true) |
262 | | - :httpOptions $ js-object (:baseUrl "\"https://ja.chenyong.life") |
| 263 | + :httpOptions $ js-object (:baseUrl |https://ja.chenyong.life) |
263 | 264 | :signal $ let |
264 | 265 | abort $ new js/AbortController |
265 | 266 | reset! *abort-control abort |
|
382 | 383 | if (:loading? state) |
383 | 384 | div ({}) (memof1-call-by :abort-loading comp-abort "\"Loading...") |
384 | 385 | if |
385 | | - not $ blank? (:answer state) |
| 386 | + or |
| 387 | + not $ blank? (:answer state) |
| 388 | + not $ blank? (:thinking state) |
386 | 389 | div ({}) |
387 | 390 | if |
388 | | - json-pattern? $ :answer state |
389 | | - pre $ {} (:class-name style-code-content) |
390 | | - :inner-text $ :answer state |
391 | | - memof1-call comp-md-block |
392 | | - -> (:answer state) (either "\"") |
393 | | - {} $ :class-name style-md-content |
| 391 | + not $ blank? (:thinking state) |
| 392 | + div |
| 393 | + {} $ :class-name style-thinking |
| 394 | + memof1-call comp-md-block |
| 395 | + -> (:thinking state) (either "\"") |
| 396 | + {} $ :class-name style-md-content |
| 397 | + if |
| 398 | + not $ blank? (:answer state) |
| 399 | + div ({}) |
| 400 | + if |
| 401 | + json-pattern? $ :answer state |
| 402 | + pre $ {} (:class-name style-code-content) |
| 403 | + :inner-text $ :answer state |
| 404 | + memof1-call comp-md-block |
| 405 | + -> (:answer state) (either "\"") |
| 406 | + {} $ :class-name style-md-content |
394 | 407 | div |
395 | 408 | {} $ :class-name css/row-parted |
396 | 409 | div |
|
607 | 620 | {} $ :max-width "\"90vw" |
608 | 621 | "\"&" $ {} (:color "\"#999") (:transition-duration "\"300ms") |
609 | 622 | :background-color $ hsl 0 0 98 |
| 623 | + :touch-action :none |
610 | 624 | "\"&:hover" $ {} (:color "\"#777") |
611 | 625 | :background-color $ hsl 0 0 100 |
612 | 626 | :examples $ [] |
|
691 | 705 | "\"&" $ {} (:border-radius 12) (:height "\"max(160px,20vh)") (:width "\"100%") (:transition-duration "\"320ms") (:border :none) (:background-color :transparent) |
692 | 706 | "\"&.focus-within" $ {} (:height "\"max(240px,32vh)") (:border :none) (:box-shadow :none) |
693 | 707 | :examples $ [] |
| 708 | + |style-thinking $ %{} :CodeEntry (:doc |) |
| 709 | + :code $ quote |
| 710 | + defstyle style-thinking $ {} |
| 711 | + "\"&" $ {} (:max-height 200) (:overflow :auto) (:padding "\"12px 16px") |
| 712 | + :background-color $ hsl 0 0 96 |
| 713 | + :font-size 12 |
| 714 | + :line-height "\"1.8" |
| 715 | + :color $ hsl 0 0 50 |
| 716 | + :border-radius 8 |
| 717 | + :margin-bottom 12 |
| 718 | + :border $ str "\"1px solid " (hsl 0 0 90) |
| 719 | + "\"& .md-p" $ {} (:margin "\"4px 0") |
| 720 | + :examples $ [] |
694 | 721 | |submit-message! $ %{} :CodeEntry (:doc |) |
695 | 722 | :code $ quote |
696 | 723 | defn submit-message! (cursor state prompt-text search? think? model d!) (hint-fn async) |
697 | 724 | let |
698 | 725 | *text $ atom "\"" |
| 726 | + *thinking-text $ atom "\"" |
699 | 727 | model $ :model state |
700 | 728 | try |
701 | 729 | case-default model |
702 | | - js-await $ call-genai-msg! model cursor state prompt-text search? think? d! *text |
703 | | - :gemini-pro $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
| 730 | + js-await $ call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text |
| 731 | + :gemini-pro $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
704 | 732 | :flash-imagen $ js-await (call-flash-imagen-msg! model cursor state prompt-text d!) |
705 | 733 | :imagen-4 $ js-await (call-imagen-4-msg! model cursor state prompt-text d!) |
706 | | - :gemini-thinking $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
707 | | - :gemini-flash-thinking $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
708 | | - :gemini-flash-lite $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
709 | | - :gemini-flash $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
710 | | - :gemini-learnlm $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text) |
| 734 | + :gemini-thinking $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
| 735 | + :gemini-flash-thinking $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
| 736 | + :gemini-flash-lite $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
| 737 | + :gemini-flash $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
| 738 | + :gemini-learnlm $ js-await (call-genai-msg! model cursor state prompt-text search? think? d! *text *thinking-text) |
711 | 739 | :claude-3.7 $ js-await (call-anthropic-msg! cursor state prompt-text "\"claude-3-7-sonnet-20250219" false d!) |
712 | 740 | :openrouter/anthropic/claude-sonnet-4 $ js-await (call-openrouter! cursor state prompt-text "\"anthropic/claude-sonnet-4" true d! *text) |
713 | 741 | :openrouter/anthropic/claude-opus-4 $ js-await (call-openrouter! cursor state prompt-text "\"anthropic/claude-opus-4" true d! *text) |
|
741 | 769 | "\"@google/genai" :refer $ GoogleGenAI Modality |
742 | 770 | "\"../lib/image" :refer $ base64ToBlob |
743 | 771 | "\"openai" :default OpenAI |
| 772 | + :examples $ [] |
744 | 773 | |app.config $ %{} :FileEntry |
745 | 774 | :defs $ {} |
746 | 775 | |chrome-extension? $ %{} :CodeEntry (:doc |) |
|
757 | 786 | :examples $ [] |
758 | 787 | :ns $ %{} :CodeEntry (:doc |) |
759 | 788 | :code $ quote (ns app.config) |
| 789 | + :examples $ [] |
760 | 790 | |app.main $ %{} :FileEntry |
761 | 791 | :defs $ {} |
762 | 792 | |*reel $ %{} :CodeEntry (:doc |) |
|
778 | 808 | if |
779 | 809 | = "\"menu-trigger" $ .-action message |
780 | 810 | let |
781 | | - content $ str "\"你扮演一个专业的工程师, 对以下内容做一下讲解, 用中文, 注意要简略, 内容注意分块.\n\n" &newline &newline (.-content message) |
| 811 | + content $ str "\"你扮演一个专业的工程师, 对以下内容做一下讲解, 用中文, 注意要简略, 内容注意分块.\n\n" &newline &newline (.-content message) |
782 | 812 | store $ :store @*reel |
783 | 813 | cursor $ [] |
784 | 814 | state0 $ get-in store ([] :states :data) |
|
797 | 827 | js/window.addEventListener |beforeunload $ fn (event) (persist-storage!) |
798 | 828 | js/window.addEventListener |visibilitychange $ fn (event) |
799 | 829 | if (= "\"hidden" js/document.visibilityState) (persist-storage!) |
| 830 | + js/window.addEventListener |dblclick $ fn (event) (.!preventDefault event) |
| 831 | + js/window.addEventListener |wheel |
| 832 | + fn (event) |
| 833 | + if (.-ctrlKey event) (.!preventDefault event) |
| 834 | + js-object $ :passive false |
800 | 835 | ; flipped js/setInterval 60000 persist-storage! |
801 | 836 | let |
802 | 837 | raw $ js/localStorage.getItem (:storage-key config/site) |
|
842 | 877 | app.config :as config |
843 | 878 | "\"./calcit.build-errors" :default build-errors |
844 | 879 | "\"bottom-tip" :default hud! |
| 880 | + :examples $ [] |
845 | 881 | |app.schema $ %{} :FileEntry |
846 | 882 | :defs $ {} |
847 | 883 | |store $ %{} :CodeEntry (:doc |) |
|
853 | 889 | :examples $ [] |
854 | 890 | :ns $ %{} :CodeEntry (:doc |) |
855 | 891 | :code $ quote (ns app.schema) |
| 892 | + :examples $ [] |
856 | 893 | |app.updater $ %{} :FileEntry |
857 | 894 | :defs $ {} |
858 | 895 | |updater $ %{} :CodeEntry (:doc |) |
|
874 | 911 | :code $ quote |
875 | 912 | ns app.updater $ :require |
876 | 913 | respo.cursor :refer $ update-states update-states-merge |
| 914 | + :examples $ [] |
0 commit comments