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            include_conversation: 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        },
139        message_header: {
140            margin: { bottom: 4, top: 4 },
141            background: background(theme.highest),
142        },
143        hamburger_button: tab_bar_button(theme, {
144            icon: "icons/menu.svg",
145        }),
146
147        split_button: tab_bar_button(theme, {
148            icon: "icons/split_message.svg",
149        }),
150        quote_button: tab_bar_button(theme, {
151            icon: "icons/quote.svg",
152        }),
153        assist_button: tab_bar_button(theme, {
154            icon: "icons/magic-wand.svg",
155        }),
156        zoom_in_button: tab_bar_button(theme, {
157            icon: "icons/maximize.svg",
158        }),
159        zoom_out_button: tab_bar_button(theme, {
160            icon: "icons/minimize.svg",
161        }),
162        plus_button: tab_bar_button(theme, {
163            icon: "icons/plus.svg",
164        }),
165        title: {
166            ...text(theme.highest, "sans", "default", { size: "xs" }),
167        },
168        saved_conversation: {
169            container: interactive({
170                base: {
171                    background: background(theme.middle),
172                    padding: { top: 4, bottom: 4 },
173                    border: border(theme.middle, "default", {
174                        top: true,
175                        overlay: true,
176                    }),
177                },
178                state: {
179                    hovered: {
180                        background: background(theme.middle, "hovered"),
181                    },
182                    clicked: {
183                        background: background(theme.middle, "pressed"),
184                    },
185                },
186            }),
187            saved_at: {
188                margin: { left: 8 },
189                ...text(theme.highest, "sans", "variant", { size: "xs" }),
190            },
191            title: {
192                margin: { left: 12 },
193                ...text(theme.highest, "sans", "default", {
194                    size: "sm",
195                    weight: "bold",
196                }),
197            },
198        },
199        user_sender: interactive_role("base"),
200        assistant_sender: interactive_role("accent"),
201        system_sender: interactive_role("warning"),
202        sent_at: {
203            margin: { top: 2, left: 8 },
204            ...text(theme.highest, "sans", "variant", { size: "2xs" }),
205        },
206        model: interactive({
207            base: {
208                background: background(theme.highest),
209                margin: { left: 12, right: 4, top: 12 },
210                padding: { right: 4, left: 4, top: 1, bottom: 1 },
211                corner_radius: 4,
212                ...text(theme.highest, "sans", "default", { size: "xs" }),
213            },
214            state: {
215                hovered: {
216                    background: background(theme.highest, "on", "hovered"),
217                    border: border(theme.highest, "on", { overlay: true }),
218                },
219            },
220        }),
221        remaining_tokens: tokens_remaining("positive"),
222        low_remaining_tokens: tokens_remaining("warning"),
223        no_remaining_tokens: tokens_remaining("negative"),
224        error_icon: {
225            margin: { left: 8 },
226            color: foreground(theme.highest, "negative"),
227            width: 12,
228        },
229        api_key_editor: {
230            background: background(theme.highest, "on"),
231            corner_radius: 4,
232            text: text(theme.highest, "mono", "on"),
233            placeholder_text: text(theme.highest, "mono", "on", "disabled", {
234                size: "xs",
235            }),
236            selection: theme.players[0],
237            border: border(theme.highest, "on"),
238            padding: {
239                bottom: 4,
240                left: 8,
241                right: 8,
242                top: 4,
243            },
244        },
245        api_key_prompt: {
246            padding: 10,
247            ...text(theme.highest, "sans", "default", { size: "xs" }),
248        },
249    }
250}