assistant.ts

  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,
110                            color: background(theme.highest, "on"),
111                        },
112                        margin: { left: 2 },
113                        padding: {
114                            left: 4,
115                            right: 4,
116                            top: 4,
117                            bottom: 4,
118                        },
119                    },
120                    state: {
121                        hovered: {
122                            ...text(
123                                theme.highest,
124                                "mono",
125                                "variant",
126                                "hovered",
127                            ),
128                            background: background(
129                                theme.highest,
130                                "on",
131                                "hovered",
132                            ),
133                            border: {
134                                width: 1,
135                                color: background(
136                                    theme.highest,
137                                    "on",
138                                    "hovered",
139                                ),
140                            },
141                        },
142                        clicked: {
143                            ...text(
144                                theme.highest,
145                                "mono",
146                                "variant",
147                                "pressed",
148                            ),
149                            background: background(
150                                theme.highest,
151                                "on",
152                                "pressed",
153                            ),
154                            border: {
155                                width: 1,
156                                color: background(
157                                    theme.highest,
158                                    "on",
159                                    "pressed",
160                                ),
161                            },
162                        },
163                    },
164                }),
165                state: {
166                    active: {
167                        default: {
168                            icon_size: 12,
169                            button_width: 12,
170                            color: foreground(theme.highest, "variant"),
171                            background: background(theme.highest, "accent"),
172                            border: border(theme.highest, "accent"),
173                        },
174                        hovered: {
175                            background: background(
176                                theme.highest,
177                                "accent",
178                                "hovered",
179                            ),
180                            border: border(theme.highest, "accent", "hovered"),
181                        },
182                        clicked: {
183                            background: background(
184                                theme.highest,
185                                "accent",
186                                "pressed",
187                            ),
188                            border: border(theme.highest, "accent", "pressed"),
189                        },
190                    },
191                },
192            }),
193            include_conversation: toggleable({
194                base: interactive({
195                    base: {
196                        icon_size: 12,
197                        color: foreground(theme.highest, "variant"),
198
199                        button_width: 12,
200                        background: background(theme.highest, "on"),
201                        corner_radius: 2,
202                        border: {
203                            width: 1,
204                            color: background(theme.highest, "on"),
205                        },
206                        padding: {
207                            left: 4,
208                            right: 4,
209                            top: 4,
210                            bottom: 4,
211                        },
212                    },
213                    state: {
214                        hovered: {
215                            ...text(
216                                theme.highest,
217                                "mono",
218                                "variant",
219                                "hovered",
220                            ),
221                            background: background(
222                                theme.highest,
223                                "on",
224                                "hovered",
225                            ),
226                            border: {
227                                width: 1,
228                                color: background(
229                                    theme.highest,
230                                    "on",
231                                    "hovered",
232                                ),
233                            },
234                        },
235                        clicked: {
236                            ...text(
237                                theme.highest,
238                                "mono",
239                                "variant",
240                                "pressed",
241                            ),
242                            background: background(
243                                theme.highest,
244                                "on",
245                                "pressed",
246                            ),
247                            border: {
248                                width: 1,
249                                color: background(
250                                    theme.highest,
251                                    "on",
252                                    "pressed",
253                                ),
254                            },
255                        },
256                    },
257                }),
258                state: {
259                    active: {
260                        default: {
261                            icon_size: 12,
262                            button_width: 12,
263                            color: foreground(theme.highest, "variant"),
264                            background: background(theme.highest, "accent"),
265                            border: border(theme.highest, "accent"),
266                        },
267                        hovered: {
268                            background: background(
269                                theme.highest,
270                                "accent",
271                                "hovered",
272                            ),
273                            border: border(theme.highest, "accent", "hovered"),
274                        },
275                        clicked: {
276                            background: background(
277                                theme.highest,
278                                "accent",
279                                "pressed",
280                            ),
281                            border: border(theme.highest, "accent", "pressed"),
282                        },
283                    },
284                },
285            }),
286        },
287        message_header: {
288            margin: { bottom: 4, top: 4 },
289            background: background(theme.highest),
290        },
291        hamburger_button: tab_bar_button(theme, {
292            icon: "icons/menu.svg",
293        }),
294
295        split_button: tab_bar_button(theme, {
296            icon: "icons/split_message.svg",
297        }),
298        quote_button: tab_bar_button(theme, {
299            icon: "icons/quote.svg",
300        }),
301        assist_button: tab_bar_button(theme, {
302            icon: "icons/magic-wand.svg",
303        }),
304        zoom_in_button: tab_bar_button(theme, {
305            icon: "icons/maximize.svg",
306        }),
307        zoom_out_button: tab_bar_button(theme, {
308            icon: "icons/minimize.svg",
309        }),
310        plus_button: tab_bar_button(theme, {
311            icon: "icons/plus.svg",
312        }),
313        title: {
314            ...text(theme.highest, "sans", "default", { size: "xs" }),
315        },
316        saved_conversation: {
317            container: interactive({
318                base: {
319                    background: background(theme.middle),
320                    padding: { top: 4, bottom: 4 },
321                    border: border(theme.middle, "default", {
322                        top: true,
323                        overlay: true,
324                    }),
325                },
326                state: {
327                    hovered: {
328                        background: background(theme.middle, "hovered"),
329                    },
330                    clicked: {
331                        background: background(theme.middle, "pressed"),
332                    },
333                },
334            }),
335            saved_at: {
336                margin: { left: 8 },
337                ...text(theme.highest, "sans", "variant", { size: "xs" }),
338            },
339            title: {
340                margin: { left: 12 },
341                ...text(theme.highest, "sans", "default", {
342                    size: "sm",
343                    weight: "bold",
344                }),
345            },
346        },
347        user_sender: interactive_role("base"),
348        assistant_sender: interactive_role("accent"),
349        system_sender: interactive_role("warning"),
350        sent_at: {
351            margin: { top: 2, left: 8 },
352            ...text(theme.highest, "sans", "variant", { size: "2xs" }),
353        },
354        model: interactive({
355            base: {
356                background: background(theme.highest),
357                margin: { left: 12, right: 4, top: 12 },
358                padding: { right: 4, left: 4, top: 1, bottom: 1 },
359                corner_radius: 4,
360                ...text(theme.highest, "sans", "default", { size: "xs" }),
361            },
362            state: {
363                hovered: {
364                    background: background(theme.highest, "on", "hovered"),
365                    border: border(theme.highest, "on", { overlay: true }),
366                },
367            },
368        }),
369        remaining_tokens: tokens_remaining("positive"),
370        low_remaining_tokens: tokens_remaining("warning"),
371        no_remaining_tokens: tokens_remaining("negative"),
372        error_icon: {
373            margin: { left: 8 },
374            color: foreground(theme.highest, "negative"),
375            width: 12,
376        },
377        api_key_editor: {
378            background: background(theme.highest, "on"),
379            corner_radius: 4,
380            text: text(theme.highest, "mono", "on"),
381            placeholder_text: text(theme.highest, "mono", "on", "disabled", {
382                size: "xs",
383            }),
384            selection: theme.players[0],
385            border: border(theme.highest, "on"),
386            padding: {
387                bottom: 4,
388                left: 8,
389                right: 8,
390                top: 4,
391            },
392        },
393        api_key_prompt: {
394            padding: 10,
395            ...text(theme.highest, "sans", "default", { size: "xs" }),
396        },
397    }
398}