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 = (color: StyleSets): Interactive<RoleCycleButton> => {
 26        return (
 27            interactive({
 28                base: {
 29                    ...text(theme.highest, "sans", color, { size: "sm" }),
 30                },
 31                state: {
 32                    hovered: {
 33                        ...text(theme.highest, "sans", color, { size: "sm" }),
 34                        background: background(theme.highest, color, "hovered"),
 35                    },
 36                    clicked: {
 37                        ...text(theme.highest, "sans", color, { size: "sm" }),
 38                        background: background(theme.highest, color, "pressed"),
 39                    }
 40                },
 41            })
 42        )
 43    }
 44
 45    const tokens_remaining = (color: StyleSets): RemainingTokens => {
 46        return (
 47            {
 48                ...text(theme.highest, "mono", color, { size: "xs" }),
 49                background: background(theme.highest, "on", "default"),
 50                margin: { top: 12, right: 20 },
 51                padding: { right: 4, left: 4, top: 1, bottom: 1 },
 52                corner_radius: 6,
 53            }
 54        )
 55    }
 56
 57    return {
 58        container: {
 59            background: background(theme.highest),
 60            padding: { left: 12 },
 61        },
 62        inline: {
 63            background: background(theme.highest),
 64            margin: { top: 3, bottom: 3 },
 65            border: border(theme.lowest, "on", {
 66                top: true,
 67                bottom: true,
 68                overlay: true,
 69            }),
 70            editor: {
 71                text: text(theme.highest, "mono", "default", { size: "sm" }),
 72                placeholder_text: text(theme.highest, "sans", "on", "disabled"),
 73                selection: theme.players[0],
 74            },
 75            disabled_editor: {
 76                text: text(theme.highest, "mono", "disabled", { size: "sm" }),
 77                placeholder_text: text(theme.highest, "sans", "on", "disabled"),
 78                selection: {
 79                    cursor: text(theme.highest, "mono", "disabled").color,
 80                    selection: theme.players[0].selection,
 81                },
 82            },
 83            pending_edit_background: background(theme.highest, "positive"),
 84            include_conversation: toggleable({
 85                base: interactive({
 86                    base: {
 87                        icon_size: 12,
 88                        color: foreground(theme.highest, "variant"),
 89
 90                        button_width: 12,
 91                        background: background(theme.highest, "on"),
 92                        corner_radius: 2,
 93                        border: {
 94                            width: 1., color: background(theme.highest, "on")
 95                        },
 96                        padding: {
 97                            left: 4,
 98                            right: 4,
 99                            top: 4,
100                            bottom: 4,
101                        },
102                    },
103                    state: {
104                        hovered: {
105                            ...text(theme.highest, "mono", "variant", "hovered"),
106                            background: background(theme.highest, "on", "hovered"),
107                            border: {
108                                width: 1., color: background(theme.highest, "on", "hovered")
109                            },
110                        },
111                        clicked: {
112                            ...text(theme.highest, "mono", "variant", "pressed"),
113                            background: background(theme.highest, "on", "pressed"),
114                            border: {
115                                width: 1., color: background(theme.highest, "on", "pressed")
116                            },
117                        },
118                    },
119                }),
120                state: {
121                    active: {
122                        default: {
123                            icon_size: 12,
124                            button_width: 12,
125                            color: foreground(theme.highest, "variant"),
126                            background: background(theme.highest, "accent"),
127                            border: border(theme.highest, "accent"),
128                        },
129                        hovered: {
130                            background: background(theme.highest, "accent", "hovered"),
131                            border: border(theme.highest, "accent", "hovered"),
132                        },
133                        clicked: {
134                            background: background(theme.highest, "accent", "pressed"),
135                            border: border(theme.highest, "accent", "pressed"),
136                        },
137                    },
138                },
139            }),
140        },
141        message_header: {
142            margin: { bottom: 4, top: 4 },
143            background: background(theme.highest),
144        },
145        hamburger_button: tab_bar_button(theme, {
146            icon: "icons/hamburger_15.svg",
147        }),
148
149        split_button: tab_bar_button(theme, {
150            icon: "icons/split_message_15.svg",
151        }),
152        quote_button: tab_bar_button(theme, {
153            icon: "icons/radix/quote.svg",
154        }),
155        assist_button: tab_bar_button(theme, {
156            icon: "icons/radix/magic-wand.svg",
157        }),
158        zoom_in_button: tab_bar_button(theme, {
159            icon: "icons/radix/maximize.svg",
160        }),
161        zoom_out_button: tab_bar_button(theme, {
162            icon: "icons/radix/minimize.svg",
163        }),
164        plus_button: tab_bar_button(theme, {
165            icon: "icons/radix/plus.svg",
166        }),
167        title: {
168            ...text(theme.highest, "sans", "default", { size: "xs" }),
169        },
170        saved_conversation: {
171            container: interactive({
172                base: {
173                    background: background(theme.middle),
174                    padding: { top: 4, bottom: 4 },
175                    border: border(theme.middle, "default", { top: true, overlay: true }),
176                },
177                state: {
178                    hovered: {
179                        background: background(theme.middle, "hovered"),
180                    },
181                    clicked: {
182                        background: background(theme.middle, "pressed"),
183                    }
184                },
185            }),
186            saved_at: {
187                margin: { left: 8 },
188                ...text(theme.highest, "sans", "variant", { size: "xs" }),
189            },
190            title: {
191                margin: { left: 12 },
192                ...text(theme.highest, "sans", "default", {
193                    size: "sm",
194                    weight: "bold",
195                }),
196            },
197        },
198        user_sender: interactive_role("base"),
199        assistant_sender: interactive_role("accent"),
200        system_sender: interactive_role("warning"),
201        sent_at: {
202            margin: { top: 2, left: 8 },
203            ...text(theme.highest, "sans", "variant", { size: "2xs" }),
204        },
205        model: interactive({
206            base: {
207                background: background(theme.highest),
208                margin: { left: 12, right: 4, top: 12 },
209                padding: { right: 4, left: 4, top: 1, bottom: 1 },
210                corner_radius: 4,
211                ...text(theme.highest, "sans", "default", { size: "xs" }),
212            },
213            state: {
214                hovered: {
215                    background: background(theme.highest, "on", "hovered"),
216                    border: border(theme.highest, "on", { overlay: true }),
217                },
218            },
219        }),
220        remaining_tokens: tokens_remaining("positive"),
221        low_remaining_tokens: tokens_remaining("warning"),
222        no_remaining_tokens: tokens_remaining("negative"),
223        error_icon: {
224            margin: { left: 8 },
225            color: foreground(theme.highest, "negative"),
226            width: 12,
227        },
228        api_key_editor: {
229            background: background(theme.highest, "on"),
230            corner_radius: 4,
231            text: text(theme.highest, "mono", "on"),
232            placeholder_text: text(theme.highest, "mono", "on", "disabled", {
233                size: "xs",
234            }),
235            selection: theme.players[0],
236            border: border(theme.highest, "on"),
237            padding: {
238                bottom: 4,
239                left: 8,
240                right: 8,
241                top: 4,
242            },
243        },
244        api_key_prompt: {
245            padding: 10,
246            ...text(theme.highest, "sans", "default", { size: "xs" }),
247        },
248    }
249}