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