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., 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}