hermium 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +56 -0
  2. package/bin/hermium.mjs +185 -164
  3. package/dist/api.mjs +3513 -0
  4. package/dist/public/assets/css/index-Dfs9RUU9.css +1 -0
  5. package/dist/public/assets/css/styles-B8p6jk5Z.css +1 -0
  6. package/dist/public/assets/js/ChatInputBlock-Bw7AL70H.js +1 -0
  7. package/dist/public/assets/js/MarkdownMessage-8d7Y6VL-.js +1 -0
  8. package/dist/public/assets/js/base-ui-BvQbAt_1.js +1 -0
  9. package/dist/public/assets/js/chat._sessionId-BG6lVraH.js +1 -0
  10. package/dist/public/assets/js/chat.index-D2zdMPTT.js +1 -0
  11. package/dist/public/assets/js/index-C0AK45FU.js +60 -0
  12. package/dist/public/assets/js/index-Cx5En4FK.js +1 -0
  13. package/dist/public/assets/js/memory-CeSRdTkW.js +3 -0
  14. package/dist/public/assets/js/router-8uDKazL-.js +1 -0
  15. package/dist/public/assets/js/settings-Bc3Y5zXO.js +1 -0
  16. package/dist/public/assets/js/skills-DZv7sA_5.js +1 -0
  17. package/dist/public/assets/js/theme-CPkdkpaj.js +1 -0
  18. package/dist/public/assets/js/usage-DXQsT9_b.js +1 -0
  19. package/dist/public/assets/woff2/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  20. package/dist/public/assets/woff2/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  21. package/dist/public/assets/woff2/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  22. package/dist/public/assets/woff2/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  23. package/dist/public/assets/woff2/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  24. package/dist/public/favicon.ico +0 -0
  25. package/dist/public/logo.png +0 -0
  26. package/package.json +1 -1
  27. package/dist/public/assets/IconAlertCircle-BHkmI3j7.js +0 -1
  28. package/dist/public/assets/IconAlertTriangle-wCJudlVg.js +0 -1
  29. package/dist/public/assets/IconCheck-CFuEh_p7.js +0 -1
  30. package/dist/public/assets/IconLoader2-BIx3OuF9.js +0 -1
  31. package/dist/public/assets/IconRefresh-Dgm93w3T.js +0 -1
  32. package/dist/public/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  33. package/dist/public/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  34. package/dist/public/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  35. package/dist/public/assets/index-Bbz3abmO.js +0 -14
  36. package/dist/public/assets/index-CWUaRwcE.js +0 -1
  37. package/dist/public/assets/index-CinLq3cd.js +0 -1
  38. package/dist/public/assets/index-CrQs9n6q.js +0 -29
  39. package/dist/public/assets/index-CtacpN3I.js +0 -1
  40. package/dist/public/assets/index-DY7aE-9s.js +0 -2
  41. package/dist/public/assets/index-DkYGodJj.js +0 -94
  42. package/dist/public/assets/index-DvDLadUx.js +0 -1
  43. package/dist/public/assets/index-U6RcWedt.js +0 -1
  44. package/dist/public/assets/index-_6iFZ0fh.js +0 -1
  45. package/dist/public/assets/index-enFS26SU.js +0 -1
  46. package/dist/public/assets/input-eNcwlDHp.js +0 -1
  47. package/dist/public/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  48. package/dist/public/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  49. package/dist/public/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  50. package/dist/public/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  51. package/dist/public/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  52. package/dist/public/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  53. package/dist/public/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  54. package/dist/public/assets/queries-iHRgZzw2.js +0 -1
  55. package/dist/public/assets/styles-KcflDlA_.css +0 -1
  56. package/dist/public/assets/switch-B1DcZLwL.js +0 -1
  57. package/dist/public/assets/syntax-highlighter-DWPF-A_h.js +0 -6
  58. package/dist/public/assets/textarea-Di_syYTS.js +0 -1
  59. package/dist/public/favicon.png +0 -0
  60. package/dist/public/nous-logo.png +0 -0
  61. package/dist/server/index.mjs +0 -244
  62. package/dist/web-server/__23tanstack-start-plugin-adapters-Cwee5PKy.mjs +0 -6
  63. package/dist/web-server/_chunks/ssr-renderer.mjs +0 -22
  64. package/dist/web-server/_libs/babel__runtime.mjs +0 -237
  65. package/dist/web-server/_libs/bail.mjs +0 -8
  66. package/dist/web-server/_libs/base-ui__react.mjs +0 -9554
  67. package/dist/web-server/_libs/base-ui__utils.mjs +0 -1101
  68. package/dist/web-server/_libs/ccount.mjs +0 -16
  69. package/dist/web-server/_libs/character-entities-legacy.mjs +0 -111
  70. package/dist/web-server/_libs/character-entities.mjs +0 -2130
  71. package/dist/web-server/_libs/character-reference-invalid.mjs +0 -33
  72. package/dist/web-server/_libs/class-variance-authority.mjs +0 -44
  73. package/dist/web-server/_libs/clsx.mjs +0 -16
  74. package/dist/web-server/_libs/comma-separated-tokens.mjs +0 -31
  75. package/dist/web-server/_libs/cookie-es.mjs +0 -44
  76. package/dist/web-server/_libs/croner.mjs +0 -1
  77. package/dist/web-server/_libs/crossws.mjs +0 -1
  78. package/dist/web-server/_libs/decode-named-character-reference+[...].mjs +0 -8
  79. package/dist/web-server/_libs/devlop.mjs +0 -8
  80. package/dist/web-server/_libs/escape-string-regexp.mjs +0 -9
  81. package/dist/web-server/_libs/estree-util-is-identifier-name.mjs +0 -11
  82. package/dist/web-server/_libs/extend.mjs +0 -97
  83. package/dist/web-server/_libs/fault.mjs +0 -1
  84. package/dist/web-server/_libs/floating-ui__core.mjs +0 -663
  85. package/dist/web-server/_libs/floating-ui__dom.mjs +0 -624
  86. package/dist/web-server/_libs/floating-ui__react-dom.mjs +0 -279
  87. package/dist/web-server/_libs/floating-ui__utils.mjs +0 -322
  88. package/dist/web-server/_libs/format.mjs +0 -1
  89. package/dist/web-server/_libs/h3.mjs +0 -408
  90. package/dist/web-server/_libs/hast-util-parse-selector.mjs +0 -39
  91. package/dist/web-server/_libs/hast-util-to-jsx-runtime.mjs +0 -388
  92. package/dist/web-server/_libs/hast-util-whitespace.mjs +0 -10
  93. package/dist/web-server/_libs/hastscript.mjs +0 -200
  94. package/dist/web-server/_libs/highlight.js.mjs +0 -1
  95. package/dist/web-server/_libs/hookable.mjs +0 -1
  96. package/dist/web-server/_libs/html-url-attributes.mjs +0 -26
  97. package/dist/web-server/_libs/inline-style-parser.mjs +0 -142
  98. package/dist/web-server/_libs/is-alphabetical.mjs +0 -7
  99. package/dist/web-server/_libs/is-alphanumerical.mjs +0 -8
  100. package/dist/web-server/_libs/is-decimal.mjs +0 -7
  101. package/dist/web-server/_libs/is-hexadecimal.mjs +0 -7
  102. package/dist/web-server/_libs/is-plain-obj.mjs +0 -10
  103. package/dist/web-server/_libs/isbot.mjs +0 -21
  104. package/dist/web-server/_libs/longest-streak.mjs +0 -25
  105. package/dist/web-server/_libs/lowlight.mjs +0 -1
  106. package/dist/web-server/_libs/markdown-table.mjs +0 -142
  107. package/dist/web-server/_libs/mdast-util-find-and-replace.mjs +0 -109
  108. package/dist/web-server/_libs/mdast-util-from-markdown.mjs +0 -717
  109. package/dist/web-server/_libs/mdast-util-gfm-autolink-literal+[...].mjs +0 -156
  110. package/dist/web-server/_libs/mdast-util-gfm-footnote.mjs +0 -117
  111. package/dist/web-server/_libs/mdast-util-gfm-strikethrough.mjs +0 -54
  112. package/dist/web-server/_libs/mdast-util-gfm-table.mjs +0 -157
  113. package/dist/web-server/_libs/mdast-util-gfm-task-list-item.mjs +0 -77
  114. package/dist/web-server/_libs/mdast-util-gfm.mjs +0 -29
  115. package/dist/web-server/_libs/mdast-util-phrasing.mjs +0 -30
  116. package/dist/web-server/_libs/mdast-util-to-hast.mjs +0 -710
  117. package/dist/web-server/_libs/mdast-util-to-markdown.mjs +0 -798
  118. package/dist/web-server/_libs/mdast-util-to-string.mjs +0 -38
  119. package/dist/web-server/_libs/micromark-core-commonmark.mjs +0 -2259
  120. package/dist/web-server/_libs/micromark-extension-gfm-autolink-literal+[...].mjs +0 -344
  121. package/dist/web-server/_libs/micromark-extension-gfm-footnote+[...].mjs +0 -279
  122. package/dist/web-server/_libs/micromark-extension-gfm-strikethrough+[...].mjs +0 -98
  123. package/dist/web-server/_libs/micromark-extension-gfm-table.mjs +0 -491
  124. package/dist/web-server/_libs/micromark-extension-gfm-tagfilter+[...].mjs +0 -1
  125. package/dist/web-server/_libs/micromark-extension-gfm-task-list-item+[...].mjs +0 -77
  126. package/dist/web-server/_libs/micromark-extension-gfm.mjs +0 -18
  127. package/dist/web-server/_libs/micromark-factory-destination.mjs +0 -94
  128. package/dist/web-server/_libs/micromark-factory-label.mjs +0 -63
  129. package/dist/web-server/_libs/micromark-factory-space.mjs +0 -24
  130. package/dist/web-server/_libs/micromark-factory-title.mjs +0 -65
  131. package/dist/web-server/_libs/micromark-factory-whitespace.mjs +0 -22
  132. package/dist/web-server/_libs/micromark-util-character.mjs +0 -44
  133. package/dist/web-server/_libs/micromark-util-chunked.mjs +0 -36
  134. package/dist/web-server/_libs/micromark-util-classify-character+[...].mjs +0 -12
  135. package/dist/web-server/_libs/micromark-util-combine-extensions+[...].mjs +0 -41
  136. package/dist/web-server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +0 -19
  137. package/dist/web-server/_libs/micromark-util-decode-string.mjs +0 -21
  138. package/dist/web-server/_libs/micromark-util-encode.mjs +0 -1
  139. package/dist/web-server/_libs/micromark-util-html-tag-name.mjs +0 -69
  140. package/dist/web-server/_libs/micromark-util-normalize-identifier+[...].mjs +0 -6
  141. package/dist/web-server/_libs/micromark-util-resolve-all.mjs +0 -15
  142. package/dist/web-server/_libs/micromark-util-sanitize-uri.mjs +0 -41
  143. package/dist/web-server/_libs/micromark-util-subtokenize.mjs +0 -346
  144. package/dist/web-server/_libs/micromark.mjs +0 -906
  145. package/dist/web-server/_libs/ocache.mjs +0 -1
  146. package/dist/web-server/_libs/ohash.mjs +0 -1
  147. package/dist/web-server/_libs/parse-entities.mjs +0 -245
  148. package/dist/web-server/_libs/property-information.mjs +0 -1210
  149. package/dist/web-server/_libs/react-dom.mjs +0 -10779
  150. package/dist/web-server/_libs/react-markdown.mjs +0 -147
  151. package/dist/web-server/_libs/react-syntax-highlighter.mjs +0 -941
  152. package/dist/web-server/_libs/react.mjs +0 -513
  153. package/dist/web-server/_libs/refractor.mjs +0 -2425
  154. package/dist/web-server/_libs/remark-gfm.mjs +0 -20
  155. package/dist/web-server/_libs/remark-parse.mjs +0 -19
  156. package/dist/web-server/_libs/remark-rehype.mjs +0 -21
  157. package/dist/web-server/_libs/reselect.mjs +0 -1
  158. package/dist/web-server/_libs/rou3.mjs +0 -8
  159. package/dist/web-server/_libs/seroval-plugins.mjs +0 -58
  160. package/dist/web-server/_libs/seroval.mjs +0 -1775
  161. package/dist/web-server/_libs/space-separated-tokens.mjs +0 -11
  162. package/dist/web-server/_libs/srvx.mjs +0 -781
  163. package/dist/web-server/_libs/style-to-js.mjs +0 -72
  164. package/dist/web-server/_libs/style-to-object.mjs +0 -38
  165. package/dist/web-server/_libs/tabler__icons-react.mjs +0 -230
  166. package/dist/web-server/_libs/tanstack__history.mjs +0 -204
  167. package/dist/web-server/_libs/tanstack__query-core.mjs +0 -2552
  168. package/dist/web-server/_libs/tanstack__react-query.mjs +0 -190
  169. package/dist/web-server/_libs/tanstack__react-router.mjs +0 -1120
  170. package/dist/web-server/_libs/tanstack__react-store.mjs +0 -2
  171. package/dist/web-server/_libs/tanstack__router-core.mjs +0 -4288
  172. package/dist/web-server/_libs/tanstack__store.mjs +0 -1
  173. package/dist/web-server/_libs/trim-lines.mjs +0 -41
  174. package/dist/web-server/_libs/trough.mjs +0 -85
  175. package/dist/web-server/_libs/ufo.mjs +0 -54
  176. package/dist/web-server/_libs/unctx.mjs +0 -1
  177. package/dist/web-server/_libs/ungap__structured-clone.mjs +0 -224
  178. package/dist/web-server/_libs/unified.mjs +0 -661
  179. package/dist/web-server/_libs/unist-util-is.mjs +0 -100
  180. package/dist/web-server/_libs/unist-util-position.mjs +0 -27
  181. package/dist/web-server/_libs/unist-util-stringify-position.mjs +0 -27
  182. package/dist/web-server/_libs/unist-util-visit-parents.mjs +0 -83
  183. package/dist/web-server/_libs/unist-util-visit.mjs +0 -24
  184. package/dist/web-server/_libs/unstorage.mjs +0 -1
  185. package/dist/web-server/_libs/use-sync-external-store.mjs +0 -139
  186. package/dist/web-server/_libs/vfile-message.mjs +0 -138
  187. package/dist/web-server/_libs/vfile.mjs +0 -467
  188. package/dist/web-server/_libs/zod.mjs +0 -3915
  189. package/dist/web-server/_libs/zustand.mjs +0 -343
  190. package/dist/web-server/_libs/zwitch.mjs +0 -1
  191. package/dist/web-server/_ssr/index-0n2Z3BPQ.mjs +0 -369
  192. package/dist/web-server/_ssr/index-6itDALOw.mjs +0 -339
  193. package/dist/web-server/_ssr/index-BIRTrOmp.mjs +0 -449
  194. package/dist/web-server/_ssr/index-BPzfADac.mjs +0 -66
  195. package/dist/web-server/_ssr/index-BQE3bF14.mjs +0 -1870
  196. package/dist/web-server/_ssr/index-C5HpvlUP.mjs +0 -190
  197. package/dist/web-server/_ssr/index-C_ZxnypN.mjs +0 -213
  198. package/dist/web-server/_ssr/index-Ca8JFH8f.mjs +0 -612
  199. package/dist/web-server/_ssr/index-DNVESZiA.mjs +0 -513
  200. package/dist/web-server/_ssr/index.mjs +0 -1558
  201. package/dist/web-server/_ssr/input-CqXjTRQg.mjs +0 -20
  202. package/dist/web-server/_ssr/queries-3H_19mUt.mjs +0 -16
  203. package/dist/web-server/_ssr/router-sbsNus0Y.mjs +0 -2093
  204. package/dist/web-server/_ssr/start-HYkvq4Ni.mjs +0 -4
  205. package/dist/web-server/_ssr/switch-usf2F1UM.mjs +0 -33
  206. package/dist/web-server/_ssr/syntax-highlighter-5vezNTce.mjs +0 -62
  207. package/dist/web-server/_ssr/textarea-DfRheWY0.mjs +0 -18
  208. package/dist/web-server/_tanstack-start-manifest_v-DqW-pKEH.mjs +0 -4
  209. package/dist/web-server/index.mjs +0 -597
@@ -1,339 +0,0 @@
1
- import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
2
- import { d as useNavigate } from "../_libs/tanstack__react-router.mjs";
3
- import { u as updateModelConfig, c as createSession, B as Button, a as cn, D as DropdownMenu, b as DropdownMenuTrigger, d as DropdownMenuContent, e as DropdownMenuItem } from "./router-sbsNus0Y.mjs";
4
- import { u as useModels } from "./queries-3H_19mUt.mjs";
5
- import { x as IconChevronLeft, s as IconPencil, y as IconBook, z as IconCode, A as IconHeart, B as IconCloud, C as IconLoader2, D as IconArrowUp } from "../_libs/tabler__icons-react.mjs";
6
- import "../_libs/tanstack__router-core.mjs";
7
- import "../_libs/tanstack__history.mjs";
8
- import "../_libs/cookie-es.mjs";
9
- import "../_libs/seroval.mjs";
10
- import "../_libs/seroval-plugins.mjs";
11
- import "node:stream/web";
12
- import "node:stream";
13
- import "../_libs/react-dom.mjs";
14
- import "util";
15
- import "crypto";
16
- import "async_hooks";
17
- import "stream";
18
- import "../_libs/isbot.mjs";
19
- import "../_libs/tanstack__query-core.mjs";
20
- import "../_libs/tanstack__react-query.mjs";
21
- import "../_libs/clsx.mjs";
22
- import "../_libs/class-variance-authority.mjs";
23
- import "../_libs/zustand.mjs";
24
- import "../_libs/base-ui__react.mjs";
25
- import "../_libs/base-ui__utils.mjs";
26
- import "../_libs/use-sync-external-store.mjs";
27
- import "../_libs/floating-ui__utils.mjs";
28
- import "../_libs/floating-ui__react-dom.mjs";
29
- import "../_libs/floating-ui__dom.mjs";
30
- import "../_libs/floating-ui__core.mjs";
31
- import "../_libs/zod.mjs";
32
- const PROMPT_CARDS = [
33
- {
34
- icon: IconPencil,
35
- label: "Write",
36
- title: "Write",
37
- description: "Articles, stories, documentation, and all kinds of written content.",
38
- prompts: [
39
- "Write a short story about a robot learning to paint — make it emotional and reflective, around 500 words.",
40
- "Draft a professional email template for following up with clients after a meeting.",
41
- "Write a persuasive blog post on why companies should adopt a 4-day work week.",
42
- "Create a product description for a smart water bottle that tracks hydration, 3 sentences max per feature.",
43
- "Rewrite this paragraph to be more concise and impactful: [paste text]"
44
- ]
45
- },
46
- {
47
- icon: IconBook,
48
- label: "Learn",
49
- title: "Learn",
50
- description: "Explore new topics, get clear explanations, and dive deep into any subject.",
51
- prompts: [
52
- "Explain quantum computing like I'm 10 years old — simple but accurate with fun analogies.",
53
- "Teach me the basics of investing: stocks, bonds, ETFs, and how to start with $500.",
54
- "Give me a 5-minute summary of the French Revolution — key dates, people, and outcomes.",
55
- "Explain how large language models like you actually work under the hood.",
56
- "Walk me through the core principles of color theory for UI design."
57
- ]
58
- },
59
- {
60
- icon: IconCode,
61
- label: "Code",
62
- title: "Code",
63
- description: "Build, debug, refactor, and architect software with AI assistance.",
64
- prompts: [
65
- "Build a Python script that monitors a directory for new files and uploads them to S3. Include error handling, logging, and a config file.",
66
- "Review this code for performance bottlenecks and suggest specific improvements: [paste code]",
67
- "Create a React hook that debounces a value and returns loading/error states.",
68
- "Write a SQL query to find the top 5 customers by revenue this month, with their last order date.",
69
- "Explain the difference between REST and GraphQL — when would you choose one over the other, with a real example."
70
- ]
71
- },
72
- {
73
- icon: IconHeart,
74
- label: "Life stuff",
75
- title: "Life Stuff",
76
- description: "Productivity, habits, health, relationships, and everyday advice.",
77
- prompts: [
78
- "Give me a daily routine that balances deep work, exercise, social time, and rest. I work from home and tend to overwork.",
79
- "How do I start a regular meditation practice? Suggest a beginner-friendly 10-minute routine.",
80
- "I want to read more books — help me set up a sustainable reading habit and pick my first 5.",
81
- "What are 3 evidence-backed techniques to reduce anxiety before a big presentation?",
82
- "Help me plan a weekly meal prep routine that's healthy, affordable, and takes under 2 hours on Sunday."
83
- ]
84
- },
85
- {
86
- icon: IconCloud,
87
- label: "Weather",
88
- title: "Weather",
89
- description: "Forecasts, climate insights, and weather patterns anywhere in the world.",
90
- prompts: [
91
- "What's the weather like today in my area? Give me a detailed forecast with temperature, humidity, and chance of rain.",
92
- "What's the best time of year to visit Tokyo for mild weather and fewer crowds?",
93
- "Explain how hurricanes form and how their intensity is categorized.",
94
- "Compare the climates of San Francisco and New York — which one has milder winters?",
95
- "What does 'dew point' actually mean and why does it matter for comfort?"
96
- ]
97
- }
98
- ];
99
- function useGreeting() {
100
- const [greeting, setGreeting] = reactExports.useState("");
101
- reactExports.useEffect(() => {
102
- const hour = (/* @__PURE__ */ new Date()).getHours();
103
- if (hour < 12) setGreeting("Good morning");
104
- else if (hour < 17) setGreeting("Good afternoon");
105
- else if (hour < 21) setGreeting("Good evening");
106
- else setGreeting("Good night");
107
- }, []);
108
- return greeting;
109
- }
110
- function displayName(model) {
111
- if (model.name && model.name !== model.id) return model.name;
112
- const short = model.id.split("/").pop() || model.id;
113
- return short.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
114
- }
115
- function DashboardInput({
116
- onSubmit,
117
- disabled,
118
- selectedModelId,
119
- onModelChange,
120
- models,
121
- modelsLoading
122
- }) {
123
- const [value, setValue] = reactExports.useState("");
124
- const textareaRef = reactExports.useRef(null);
125
- const selectedModel = models.find((m) => m.id === selectedModelId);
126
- const autoResize = reactExports.useCallback(() => {
127
- const el = textareaRef.current;
128
- if (!el) return;
129
- el.style.height = "auto";
130
- el.style.height = `${Math.min(el.scrollHeight, 200)}px`;
131
- }, []);
132
- reactExports.useEffect(() => {
133
- autoResize();
134
- }, [value, autoResize]);
135
- reactExports.useEffect(() => {
136
- textareaRef.current?.focus();
137
- }, []);
138
- const handleSend = reactExports.useCallback(() => {
139
- const text = value.trim();
140
- if (!text || disabled) return;
141
- setValue("");
142
- if (textareaRef.current) textareaRef.current.style.height = "auto";
143
- onSubmit(text, selectedModelId);
144
- }, [value, disabled, onSubmit, selectedModelId]);
145
- function handleKeyDown(e) {
146
- if (e.key === "Enter" && !e.shiftKey) {
147
- e.preventDefault();
148
- handleSend();
149
- }
150
- }
151
- const canSend = value.trim().length > 0;
152
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-[80px] flex-col rounded-2xl border border-border bg-card shadow-sm transition-colors cursor-text hover:border-border/80", children: [
153
- /* @__PURE__ */ jsxRuntimeExports.jsx(
154
- "textarea",
155
- {
156
- ref: textareaRef,
157
- value,
158
- onChange: (e) => setValue(e.target.value),
159
- onKeyDown: handleKeyDown,
160
- placeholder: "Ask anything…",
161
- rows: 1,
162
- disabled,
163
- className: cn(
164
- "w-full rounded-none border-0 p-4 text-[15px] text-foreground resize-none shadow-none outline-none bg-transparent whitespace-pre-wrap break-words placeholder:text-muted-foreground disabled:opacity-50",
165
- "min-h-[56px] max-h-[200px]"
166
- )
167
- }
168
- ),
169
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-[40px] items-center gap-2 p-2 pb-1", children: [
170
- /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
171
- /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenuTrigger, { className: "flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors cursor-pointer outline-none", children: [
172
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconCloud, { className: "h-4 w-4 shrink-0" }),
173
- modelsLoading && /* @__PURE__ */ jsxRuntimeExports.jsx(IconLoader2, { className: "h-3.5 w-3.5 animate-spin shrink-0" }),
174
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn(modelsLoading && "opacity-60"), children: modelsLoading ? "Loading…" : selectedModel ? displayName(selectedModel) : "Select model" })
175
- ] }),
176
- /* @__PURE__ */ jsxRuntimeExports.jsx(DropdownMenuContent, { align: "start", className: "max-h-[300px] overflow-y-auto min-w-48", children: models.map((model) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
177
- DropdownMenuItem,
178
- {
179
- onClick: () => onModelChange(model.id),
180
- className: cn(
181
- "flex-col items-start py-2",
182
- model.id === selectedModelId && "bg-muted"
183
- ),
184
- children: [
185
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: displayName(model) }),
186
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground text-xs", children: model.provider_name })
187
- ]
188
- },
189
- model.id
190
- )) })
191
- ] }),
192
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
193
- Button,
194
- {
195
- variant: "ghost",
196
- size: "icon-sm",
197
- className: cn(
198
- "rounded-full transition-colors cursor-pointer",
199
- canSend && !disabled ? "bg-primary hover:bg-primary/90 text-primary-foreground" : "bg-primary text-primary-foreground opacity-40"
200
- ),
201
- disabled: !canSend || disabled,
202
- onClick: handleSend,
203
- title: "Send message",
204
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(IconArrowUp, { className: "h-4 w-4" })
205
- }
206
- ) })
207
- ] })
208
- ] });
209
- }
210
- function DashboardPage() {
211
- const navigate = useNavigate();
212
- const greeting = useGreeting();
213
- const [selectedPrompt, setSelectedPrompt] = reactExports.useState(null);
214
- const [isSubmitting, setIsSubmitting] = reactExports.useState(false);
215
- const submittingRef = reactExports.useRef(false);
216
- const { data: modelsData, isLoading: modelsLoading } = useModels();
217
- const models = modelsData?.models ?? [];
218
- const [selectedModelId, setSelectedModelId] = reactExports.useState("");
219
- reactExports.useEffect(() => {
220
- if (!models.length) return;
221
- if (selectedModelId && models.some((m) => m.id === selectedModelId)) return;
222
- const target = modelsData?.default_model || models[0]?.id;
223
- if (target) setSelectedModelId(target);
224
- }, [models, modelsData?.default_model, selectedModelId]);
225
- const handleModelChange = reactExports.useCallback(
226
- async (nextModelId) => {
227
- setSelectedModelId(nextModelId);
228
- try {
229
- await updateModelConfig({ model: nextModelId });
230
- } catch {
231
- }
232
- },
233
- []
234
- );
235
- const handleNewChat = reactExports.useCallback(
236
- async (initialMessage, modelId) => {
237
- if (submittingRef.current) return;
238
- submittingRef.current = true;
239
- setIsSubmitting(true);
240
- try {
241
- const effectiveModel = modelId || selectedModelId || void 0;
242
- const session = await createSession({ model: effectiveModel });
243
- if (initialMessage) {
244
- sessionStorage.setItem(`hermium_pending_msg_${session.id}`, initialMessage);
245
- }
246
- if (effectiveModel) {
247
- sessionStorage.setItem(`hermium_pending_model_${session.id}`, effectiveModel);
248
- }
249
- navigate({
250
- to: "/chat/$sessionId",
251
- params: { sessionId: session.id }
252
- });
253
- } catch {
254
- submittingRef.current = false;
255
- setIsSubmitting(false);
256
- }
257
- },
258
- [navigate, selectedModelId]
259
- );
260
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col items-center justify-center px-4 overflow-hidden", children: [
261
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-10 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-5xl font-semibold tracking-tight", children: greeting }) }),
262
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full max-w-3xl", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
263
- DashboardInput,
264
- {
265
- onSubmit: handleNewChat,
266
- disabled: isSubmitting,
267
- selectedModelId,
268
- onModelChange: handleModelChange,
269
- models,
270
- modelsLoading
271
- }
272
- ) }),
273
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6 w-full max-w-3xl", children: selectedPrompt ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
274
- "div",
275
- {
276
- className: "rounded-2xl border bg-card p-6",
277
- style: { animation: "fadeSlideIn 0.2s ease-out" },
278
- children: [
279
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
280
- "button",
281
- {
282
- disabled: isSubmitting,
283
- onClick: () => setSelectedPrompt(null),
284
- className: "mb-4 flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50",
285
- children: [
286
- /* @__PURE__ */ jsxRuntimeExports.jsx(IconChevronLeft, { className: "size-3.5" }),
287
- "Back to suggestions"
288
- ]
289
- }
290
- ),
291
- /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "space-y-2", children: selectedPrompt.prompts.map((prompt, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
292
- "button",
293
- {
294
- disabled: isSubmitting,
295
- onClick: () => handleNewChat(prompt, selectedModelId),
296
- className: "group w-full rounded-xl border border-border bg-muted/30 px-4 py-3 text-left text-sm leading-relaxed text-foreground transition-colors hover:bg-muted/60 hover:border-foreground/20 disabled:opacity-50",
297
- children: [
298
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "mr-2 text-xs font-medium text-muted-foreground", children: [
299
- i + 1,
300
- "."
301
- ] }),
302
- prompt
303
- ]
304
- }
305
- ) }, i)) })
306
- ]
307
- },
308
- "prompt-card"
309
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
310
- "div",
311
- {
312
- className: "flex flex-wrap justify-center gap-2",
313
- style: { animation: "fadeSlideIn 0.2s ease-out" },
314
- children: PROMPT_CARDS.map((meta) => {
315
- const Icon = meta.icon;
316
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(
317
- Button,
318
- {
319
- variant: "ghost",
320
- disabled: isSubmitting,
321
- className: "group flex items-center gap-2 rounded-lg border border-border bg-muted/40 dark:bg-muted/40 px-3 py-1.5 text-sm text-foreground transition-colors duration-200 ease-out hover:bg-muted/60 h-auto disabled:opacity-50",
322
- onClick: () => setSelectedPrompt(meta),
323
- children: [
324
- /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "h-5 w-5 text-muted-foreground transition-colors group-hover:text-foreground" }),
325
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[15px]", children: meta.label })
326
- ]
327
- },
328
- meta.label
329
- );
330
- })
331
- },
332
- "chips"
333
- ) })
334
- ] });
335
- }
336
- const SplitComponent = DashboardPage;
337
- export {
338
- SplitComponent as component
339
- };