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