1import { text, border, background, foreground, TextStyle } from "./components"
2import { Interactive, interactive, toggleable } from "../element"
3import { tab_bar_button } from "../component/tab_bar_button"
4import { StyleSets, useTheme } from "../theme"
5
6type RoleCycleButton = TextStyle & {
7 background?: string
8}
9// TODO: Replace these with zed types
10type RemainingTokens = TextStyle & {
11 background: string
12 margin: { top: number; right: number }
13 padding: {
14 right: number
15 left: number
16 top: number
17 bottom: number
18 }
19 corner_radius: number
20}
21
22export default function assistant(): any {
23 const theme = useTheme()
24
25 const interactive_role = (
26 color: StyleSets
27 ): Interactive<RoleCycleButton> => {
28 return interactive({
29 base: {
30 ...text(theme.highest, "sans", color, { size: "sm" }),
31 },
32 state: {
33 hovered: {
34 ...text(theme.highest, "sans", color, { size: "sm" }),
35 background: background(theme.highest, color, "hovered"),
36 },
37 clicked: {
38 ...text(theme.highest, "sans", color, { size: "sm" }),
39 background: background(theme.highest, color, "pressed"),
40 },
41 },
42 })
43 }
44
45 const tokens_remaining = (color: StyleSets): RemainingTokens => {
46 return {
47 ...text(theme.highest, "mono", color, { size: "xs" }),
48 background: background(theme.highest, "on", "default"),
49 margin: { top: 12, right: 20 },
50 padding: { right: 4, left: 4, top: 1, bottom: 1 },
51 corner_radius: 6,
52 }
53 }
54
55 return {
56 container: {
57 background: background(theme.highest),
58 padding: { left: 12 },
59 },
60 inline: {
61 background: background(theme.highest),
62 margin: { top: 3, bottom: 3 },
63 border: border(theme.lowest, "on", {
64 top: true,
65 bottom: true,
66 overlay: true,
67 }),
68 editor: {
69 text: text(theme.highest, "mono", "default", { size: "sm" }),
70 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
71 selection: theme.players[0],
72 },
73 disabled_editor: {
74 text: text(theme.highest, "mono", "disabled", { size: "sm" }),
75 placeholder_text: text(theme.highest, "sans", "on", "disabled"),
76 selection: {
77 cursor: text(theme.highest, "mono", "disabled").color,
78 selection: theme.players[0].selection,
79 },
80 },
81 pending_edit_background: background(theme.highest, "positive"),
82 context_status: {
83 error_icon: {
84 margin: { left: 8, right: 18 },
85 color: foreground(theme.highest, "negative"),
86 width: 12,
87 },
88 in_progress_icon: {
89 margin: { left: 8, right: 18 },
90 color: foreground(theme.highest, "positive"),
91 width: 12,
92 },
93 complete_icon: {
94 margin: { left: 8, right: 18 },
95 color: foreground(theme.highest, "positive"),
96 width: 12,
97 }
98 },
99 retrieve_context: toggleable({
100 base: interactive({
101 base: {
102 icon_size: 12,
103 color: foreground(theme.highest, "variant"),
104
105 button_width: 12,
106 background: background(theme.highest, "on"),
107 corner_radius: 2,
108 border: {
109 width: 1., color: background(theme.highest, "on")
110 },
111 margin: { left: 2 },
112 padding: {
113 left: 4,
114 right: 4,
115 top: 4,
116 bottom: 4,
117 },
118 },
119 state: {
120 hovered: {
121 ...text(theme.highest, "mono", "variant", "hovered"),
122 background: background(theme.highest, "on", "hovered"),
123 border: {
124 width: 1., color: background(theme.highest, "on", "hovered")
125 },
126 },
127 clicked: {
128 ...text(theme.highest, "mono", "variant", "pressed"),
129 background: background(theme.highest, "on", "pressed"),
130 border: {
131 width: 1., color: background(theme.highest, "on", "pressed")
132 },
133 },
134 },
135 }),
136 state: {
137 active: {
138 default: {
139 icon_size: 12,
140 button_width: 12,
141 color: foreground(theme.highest, "variant"),
142 background: background(theme.highest, "accent"),
143 border: border(theme.highest, "accent"),
144 },
145 hovered: {
146 background: background(theme.highest, "accent", "hovered"),
147 border: border(theme.highest, "accent", "hovered"),
148 },
149 clicked: {
150 background: background(theme.highest, "accent", "pressed"),
151 border: border(theme.highest, "accent", "pressed"),
152 },
153 },
154 },
155 }),
156 include_conversation: toggleable({
157 base: interactive({
158 base: {
159 icon_size: 12,
160 color: foreground(theme.highest, "variant"),
161
162 button_width: 12,
163 background: background(theme.highest, "on"),
164 corner_radius: 2,
165 border: {
166 width: 1., color: background(theme.highest, "on")
167 },
168 padding: {
169 left: 4,
170 right: 4,
171 top: 4,
172 bottom: 4,
173 },
174 },
175 state: {
176 hovered: {
177 ...text(theme.highest, "mono", "variant", "hovered"),
178 background: background(theme.highest, "on", "hovered"),
179 border: {
180 width: 1., color: background(theme.highest, "on", "hovered")
181 },
182 },
183 clicked: {
184 ...text(theme.highest, "mono", "variant", "pressed"),
185 background: background(theme.highest, "on", "pressed"),
186 border: {
187 width: 1., color: background(theme.highest, "on", "pressed")
188 },
189 },
190 },
191 }),
192 state: {
193 active: {
194 default: {
195 icon_size: 12,
196 button_width: 12,
197 color: foreground(theme.highest, "variant"),
198 background: background(theme.highest, "accent"),
199 border: border(theme.highest, "accent"),
200 },
201 hovered: {
202 background: background(theme.highest, "accent", "hovered"),
203 border: border(theme.highest, "accent", "hovered"),
204 },
205 clicked: {
206 background: background(theme.highest, "accent", "pressed"),
207 border: border(theme.highest, "accent", "pressed"),
208 },
209 },
210 },
211 }),
212 },
213 message_header: {
214 margin: { bottom: 4, top: 4 },
215 background: background(theme.highest),
216 },
217 hamburger_button: tab_bar_button(theme, {
218 icon: "icons/menu.svg",
219 }),
220
221 split_button: tab_bar_button(theme, {
222 icon: "icons/split_message.svg",
223 }),
224 quote_button: tab_bar_button(theme, {
225 icon: "icons/quote.svg",
226 }),
227 assist_button: tab_bar_button(theme, {
228 icon: "icons/magic-wand.svg",
229 }),
230 zoom_in_button: tab_bar_button(theme, {
231 icon: "icons/maximize.svg",
232 }),
233 zoom_out_button: tab_bar_button(theme, {
234 icon: "icons/minimize.svg",
235 }),
236 plus_button: tab_bar_button(theme, {
237 icon: "icons/plus.svg",
238 }),
239 title: {
240 ...text(theme.highest, "sans", "default", { size: "xs" }),
241 },
242 saved_conversation: {
243 container: interactive({
244 base: {
245 background: background(theme.middle),
246 padding: { top: 4, bottom: 4 },
247 border: border(theme.middle, "default", {
248 top: true,
249 overlay: true,
250 }),
251 },
252 state: {
253 hovered: {
254 background: background(theme.middle, "hovered"),
255 },
256 clicked: {
257 background: background(theme.middle, "pressed"),
258 },
259 },
260 }),
261 saved_at: {
262 margin: { left: 8 },
263 ...text(theme.highest, "sans", "variant", { size: "xs" }),
264 },
265 title: {
266 margin: { left: 12 },
267 ...text(theme.highest, "sans", "default", {
268 size: "sm",
269 weight: "bold",
270 }),
271 },
272 },
273 user_sender: interactive_role("base"),
274 assistant_sender: interactive_role("accent"),
275 system_sender: interactive_role("warning"),
276 sent_at: {
277 margin: { top: 2, left: 8 },
278 ...text(theme.highest, "sans", "variant", { size: "2xs" }),
279 },
280 model: interactive({
281 base: {
282 background: background(theme.highest),
283 margin: { left: 12, right: 4, top: 12 },
284 padding: { right: 4, left: 4, top: 1, bottom: 1 },
285 corner_radius: 4,
286 ...text(theme.highest, "sans", "default", { size: "xs" }),
287 },
288 state: {
289 hovered: {
290 background: background(theme.highest, "on", "hovered"),
291 border: border(theme.highest, "on", { overlay: true }),
292 },
293 },
294 }),
295 remaining_tokens: tokens_remaining("positive"),
296 low_remaining_tokens: tokens_remaining("warning"),
297 no_remaining_tokens: tokens_remaining("negative"),
298 error_icon: {
299 margin: { left: 8 },
300 color: foreground(theme.highest, "negative"),
301 width: 12,
302 },
303 api_key_editor: {
304 background: background(theme.highest, "on"),
305 corner_radius: 4,
306 text: text(theme.highest, "mono", "on"),
307 placeholder_text: text(theme.highest, "mono", "on", "disabled", {
308 size: "xs",
309 }),
310 selection: theme.players[0],
311 border: border(theme.highest, "on"),
312 padding: {
313 bottom: 4,
314 left: 8,
315 right: 8,
316 top: 4,
317 },
318 },
319 api_key_prompt: {
320 padding: 10,
321 ...text(theme.highest, "sans", "default", { size: "xs" }),
322 },
323 }
324}