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                ...text(theme.highest, "mono", "disabled", { size: "sm" }),
 84            },
 85            retrieve_context: toggleable({
 86                base: interactive({
 87                    base: {
 88                        icon_size: 12,
 89                        color: foreground(theme.highest, "variant"),
 90
 91                        button_width: 12,
 92                        background: background(theme.highest, "on"),
 93                        corner_radius: 2,
 94                        border: {
 95                            width: 1., color: background(theme.highest, "on")
 96                        },
 97                        padding: {
 98                            left: 4,
 99                            right: 4,
100                            top: 4,
101                            bottom: 4,
102                        },
103                    },
104                    state: {
105                        hovered: {
106                            ...text(theme.highest, "mono", "variant", "hovered"),
107                            background: background(theme.highest, "on", "hovered"),
108                            border: {
109                                width: 1., color: background(theme.highest, "on", "hovered")
110                            },
111                        },
112                        clicked: {
113                            ...text(theme.highest, "mono", "variant", "pressed"),
114                            background: background(theme.highest, "on", "pressed"),
115                            border: {
116                                width: 1., color: background(theme.highest, "on", "pressed")
117                            },
118                        },
119                    },
120                }),
121                state: {
122                    active: {
123                        default: {
124                            icon_size: 12,
125                            button_width: 12,
126                            color: foreground(theme.highest, "variant"),
127                            background: background(theme.highest, "accent"),
128                            border: border(theme.highest, "accent"),
129                        },
130                        hovered: {
131                            background: background(theme.highest, "accent", "hovered"),
132                            border: border(theme.highest, "accent", "hovered"),
133                        },
134                        clicked: {
135                            background: background(theme.highest, "accent", "pressed"),
136                            border: border(theme.highest, "accent", "pressed"),
137                        },
138                    },
139                },
140            }),
141            include_conversation: toggleable({
142                base: interactive({
143                    base: {
144                        icon_size: 12,
145                        color: foreground(theme.highest, "variant"),
146
147                        button_width: 12,
148                        background: background(theme.highest, "on"),
149                        corner_radius: 2,
150                        border: {
151                            width: 1., color: background(theme.highest, "on")
152                        },
153                        padding: {
154                            left: 4,
155                            right: 4,
156                            top: 4,
157                            bottom: 4,
158                        },
159                    },
160                    state: {
161                        hovered: {
162                            ...text(theme.highest, "mono", "variant", "hovered"),
163                            background: background(theme.highest, "on", "hovered"),
164                            border: {
165                                width: 1., color: background(theme.highest, "on", "hovered")
166                            },
167                        },
168                        clicked: {
169                            ...text(theme.highest, "mono", "variant", "pressed"),
170                            background: background(theme.highest, "on", "pressed"),
171                            border: {
172                                width: 1., color: background(theme.highest, "on", "pressed")
173                            },
174                        },
175                    },
176                }),
177                state: {
178                    active: {
179                        default: {
180                            icon_size: 12,
181                            button_width: 12,
182                            color: foreground(theme.highest, "variant"),
183                            background: background(theme.highest, "accent"),
184                            border: border(theme.highest, "accent"),
185                        },
186                        hovered: {
187                            background: background(theme.highest, "accent", "hovered"),
188                            border: border(theme.highest, "accent", "hovered"),
189                        },
190                        clicked: {
191                            background: background(theme.highest, "accent", "pressed"),
192                            border: border(theme.highest, "accent", "pressed"),
193                        },
194                    },
195                },
196            }),
197        },
198        message_header: {
199            margin: { bottom: 4, top: 4 },
200            background: background(theme.highest),
201        },
202        hamburger_button: tab_bar_button(theme, {
203            icon: "icons/menu.svg",
204        }),
205
206        split_button: tab_bar_button(theme, {
207            icon: "icons/split_message.svg",
208        }),
209        quote_button: tab_bar_button(theme, {
210            icon: "icons/quote.svg",
211        }),
212        assist_button: tab_bar_button(theme, {
213            icon: "icons/magic-wand.svg",
214        }),
215        zoom_in_button: tab_bar_button(theme, {
216            icon: "icons/maximize.svg",
217        }),
218        zoom_out_button: tab_bar_button(theme, {
219            icon: "icons/minimize.svg",
220        }),
221        plus_button: tab_bar_button(theme, {
222            icon: "icons/plus.svg",
223        }),
224        title: {
225            ...text(theme.highest, "sans", "default", { size: "xs" }),
226        },
227        saved_conversation: {
228            container: interactive({
229                base: {
230                    background: background(theme.middle),
231                    padding: { top: 4, bottom: 4 },
232                    border: border(theme.middle, "default", {
233                        top: true,
234                        overlay: true,
235                    }),
236                },
237                state: {
238                    hovered: {
239                        background: background(theme.middle, "hovered"),
240                    },
241                    clicked: {
242                        background: background(theme.middle, "pressed"),
243                    },
244                },
245            }),
246            saved_at: {
247                margin: { left: 8 },
248                ...text(theme.highest, "sans", "variant", { size: "xs" }),
249            },
250            title: {
251                margin: { left: 12 },
252                ...text(theme.highest, "sans", "default", {
253                    size: "sm",
254                    weight: "bold",
255                }),
256            },
257        },
258        user_sender: interactive_role("base"),
259        assistant_sender: interactive_role("accent"),
260        system_sender: interactive_role("warning"),
261        sent_at: {
262            margin: { top: 2, left: 8 },
263            ...text(theme.highest, "sans", "variant", { size: "2xs" }),
264        },
265        model: interactive({
266            base: {
267                background: background(theme.highest),
268                margin: { left: 12, right: 4, top: 12 },
269                padding: { right: 4, left: 4, top: 1, bottom: 1 },
270                corner_radius: 4,
271                ...text(theme.highest, "sans", "default", { size: "xs" }),
272            },
273            state: {
274                hovered: {
275                    background: background(theme.highest, "on", "hovered"),
276                    border: border(theme.highest, "on", { overlay: true }),
277                },
278            },
279        }),
280        remaining_tokens: tokens_remaining("positive"),
281        low_remaining_tokens: tokens_remaining("warning"),
282        no_remaining_tokens: tokens_remaining("negative"),
283        error_icon: {
284            margin: { left: 8 },
285            color: foreground(theme.highest, "negative"),
286            width: 12,
287        },
288        api_key_editor: {
289            background: background(theme.highest, "on"),
290            corner_radius: 4,
291            text: text(theme.highest, "mono", "on"),
292            placeholder_text: text(theme.highest, "mono", "on", "disabled", {
293                size: "xs",
294            }),
295            selection: theme.players[0],
296            border: border(theme.highest, "on"),
297            padding: {
298                bottom: 4,
299                left: 8,
300                right: 8,
301                top: 4,
302            },
303        },
304        api_key_prompt: {
305            padding: 10,
306            ...text(theme.highest, "sans", "default", { size: "xs" }),
307        },
308    }
309}