diff --git a/agent/application/application.py b/agent/application/application.py index a07d20b..f993482 100644 --- a/agent/application/application.py +++ b/agent/application/application.py @@ -7,12 +7,15 @@ from application.pages.index import render_index app = rx.App( theme=rx.theme(), + stylesheets=["/styles.css"], style={ "--prismui-background-color-1": "#ffffff", # 背景颜色:白色 "--prismui-background-color-2": "#ebebeb", "--prismui-background-color-3": "#f6f6f8", "--prismui-background-color-4": "#babbc0", + "--prismui-background-color-5": "#ffffff33", "--prismui-background-1": "linear-gradient(to bottom, #D0C9FF 0%, #E6D6F0 8%, #F1DBEA 12%, #C8DCFB 40%, #ABC6F6 60%, #87AEFE 90%)", # 背景:用于主页面渐变背景 + "--prismui-background-2": "linear-gradient(180deg, #fffffff2, #f8fafff2 99%)", # 背景:用于登录窗和工作区渐变背景 "--prismui-font-family": "HuaweiFont,Helvetica,Arial,PingFangSC-Regular,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Microsoft JhengHei", # 字体 "--prismui-font-size-1": "12px", "--prismui-font-size-2": "14px", # 字体大小:常用于正文 @@ -23,13 +26,15 @@ app = rx.App( "--prismui-color-1": "#252b3a", # 颜色:深灰色,常用于标题和正文颜色 "--prismui-color-2": "#575d6c", # 颜色:中灰色,常用于副标题 "--prismui-color-3": "#babbc0", # 颜色:浅灰色,常用于占位符 - "--prismui-color-4": "rgba(6, 10, 38, 0.24)", # 颜色:浅灰色,常用于不可点击元素 + "--prismui-color-4": "#060a263d", # 颜色:浅灰色,常用于不可点击元素 "--prismui-color-5": "#5e7ce0", # 颜色:蓝色,常用于可点击元素 "--prismui-color-6": "#f66f6a", # 颜色:红色,常用于错误提示 - "--prismui-border-1": "1px solid rgba(6, 10, 38, 0.06)", # 边框样式 + "--prismui-color-7": "#f2f2f3", # 颜色:浅灰色,常用于背景 + "--prismui-color-9": "#ffffff", # 颜色:白色 + "--prismui-border-1": "1px solid #060a260f", # 边框样式 + "--prismui-border-2": "1px solid #2222220f", "--mc-float-block-shadow": "#d5d5d5", "--devui-global-bg": "#f6f6f8", - "--mc-global-bg": "linear-gradient(to bottom, #D0C9FF 0%, #E6D6F0 8%, #F1DBEA 12%, #C8DCFB 40%, #ABC6F6 60%, #87AEFE 90%)", "--mc-box-shadow": "#191919", "--devui-shadow-length-connected-overlay": "0px 0px 12px 0px #000000", "--prismui-box-shadow-1": "0 4px 64px 0 #0000001a", # 登录卡片阴影 @@ -38,11 +43,9 @@ app = rx.App( "--prismui-background-color-weak": "#babbc0", "--devui-border-radius-feedback": "4px", "--prismui-border-1": "1px solid rgba(6, 10, 38, 0.06)", - "--prismui-border-radius": "8px", "--prismui-border-radius-1": "8px", "--prismui-border-radius-2": "12px", "--prismui-border-radius-3": "20px", - "--devui-border-radius-full": "100px", "box-shadow": "none", "background-color": "var(--prismui-background-color-1)", # 默认背景颜色 "font_family": "var(--prismui-font-family)", diff --git a/agent/application/pages/index.py b/agent/application/pages/index.py index 9ed0f49..9e6eb93 100644 --- a/agent/application/pages/index.py +++ b/agent/application/pages/index.py @@ -50,8 +50,8 @@ def render_nav_button( rx.text( nav_buttons[nav_button]["text"], line_height="20px", + font_size="var(--prismui-font-size-1)", color="var(--prismui-color-1)", - font_size="var(--prismui-font-size-2)", ), align_items="center", gap="4px", @@ -61,6 +61,90 @@ def render_nav_button( ) +def render_settings_button(): + """ + 渲染设置按钮 + :return: Component + """ + return rx.box( + rx.hover_card.root( + # 触发事件:点击自定义按钮 + rx.hover_card.trigger( + rx.box( + rx.icon( + "settings", + stroke_width=1.5, + width="20px", + height="20px", + color="var(--prismui-color-1)", + ), + display="flex", + flex_flow="column", + justify_content="center", + align_items="center", + width="36px", + height="36px", + border_radius="var(--prismui-border-radius-1)", + cursor="pointer", + style={ + "&:hover": { + "background": "var(--prismui-background-color-5)", + }, # 鼠标悬停渲染背景颜色 + }, + ) + ), + # 渲染悬停卡片 + rx.hover_card.content( + rx.vstack( + rx.box( + transform="translateX(-50%) rotate(45deg)", + position="absolute", + top="16px", + left="0", + width="8px", + height="8px", + background_color="#ffffff", + box_shadow="var(--prismui-box-shadow-3)", + ), + rx.box( + "退出登录", + width="100%", + height="24px", + padding="4px", + border_radius="4px", + line_height="16px", + style={ + "_hover": { + "background_color": "var(--prismui-color-7, #f2f2f3)", + }, + }, + # 点击事件:退出登录 + on_click=lambda: AuthState.logout(), + ), + ), + side="left", + side_offset=8, + position="relative", + align="center", + padding="8px", + border_radius="4px", + background_color="#ffffff", + box_shadow="0 2px 12px rgba(0,0,0,0.1)", + overflow="visible", + style={ + "font-size": "var(--prismui-font-size-1) !important", + "color": "var(--prismui-color-1) !important", + }, + ), + open=AuthState.is_settings_hover_card_open, + # 悬停卡片打开状态变化事件:设置设置悬停卡片打开状态 + on_open_change=AuthState.set_settings_hover_card_open, + ), + min_width="14px", + cursor="pointer", + ) + + def render_sidebar() -> rx.Component: """ 渲染侧边栏 @@ -73,16 +157,16 @@ def render_sidebar() -> rx.Component: # 品牌图标 rx.image( src="/logo.png", - width="34px", - height="34px", + width="32px", + height="32px", object_fit="contain", ), # 品牌名称 rx.text( "棱镜球", line_height="20px", - font_size="11px", - font_weight="var(--prismui-font-weight-1)", + font_size="var(--prismui-font-size-1)", + font_weight="var(--prismui-font-weight-2)", color="var(--prismui-color-1)", ), align_items="center", @@ -106,6 +190,14 @@ def render_sidebar() -> rx.Component: width="100%", margin_top="12px", ), + rx.vstack( + rx.vstack( + # 渲染设置按钮 + render_settings_button(), + ), + padding_bottom="16px", + gap="8px", + ), flex_shrink="0", justify_content="space-between", align_items="center", @@ -129,7 +221,7 @@ def render_login_window() -> rx.Component: "登录解锁更多功能", line_height="32px", font_size="var(--prismui-font-size-3)", - font_weight="var(--prismui-font-weight-2)", + font_weight="var(--prismui-font-weight-3)", margin_bottom="24px", ), rx.input( @@ -143,8 +235,8 @@ def render_login_window() -> rx.Component: line_height="16px", # 值变化事件:设置邮箱 on_change=AuthState.set_email, - # 获取焦点事件:清除提示信息 - on_focus=AuthState.reset_notification, + # 获取焦点事件:重置登录错误信息 + on_focus=AuthState.reset_error_message, ), # 自定义验证码输入框 rx.hstack( @@ -152,27 +244,30 @@ def render_login_window() -> rx.Component: placeholder="请输入验证码", max_length=6, value=AuthState.captcha, + # 值变化事件:设置验证码 + on_change=AuthState.set_captcha, + # 获取焦点事件:重置登录错误信息 + on_focus=AuthState.reset_error_message, flex=1, height="100%", padding="4px", line_height="16px", border="none", - # 值变化事件:设置验证码 - on_change=AuthState.set_captcha, style={ "&": { "border": "none !important", }, # 清除父元素边框 }, ), - rx.text( + rx.button( # 若验证码发送倒计时大于0则显示倒计时,否则显示获取验证码 rx.cond( - AuthState.captcha_sending_countdown, - f"{AuthState.captcha_sending_countdown} s", + AuthState.resend_captcha_countdown, + f"{AuthState.resend_captcha_countdown} s", "获取验证码", ), margin="0 8px", + background_color="var(--prismui-background-color-1)", line_height="16px", color=rx.cond( AuthState.is_captcha_sending_disabled, @@ -180,7 +275,9 @@ def render_login_window() -> rx.Component: "var(--prismui-color-5)", ), cursor="pointer", + # 点击事件:发送验证码 on_click=AuthState.send_captcha, + disabled=AuthState.is_captcha_sending_disabled, ), width="100%", height="45px", @@ -188,84 +285,124 @@ def render_login_window() -> rx.Component: border="var(--prismui-border-1)", border_radius="var(--prismui-border-radius-2)", ), - rx.cond( - AuthState.captcha_sending_countdown, - rx.hstack( - rx.icon( - "circle-check", - width="14px", - height="14px", - color="var(--prismui-color-2)", + rx.text( + AuthState.login_error_message, + width="100%", + min_height="20px", + text_align="left", + line_height="20px", + font_size="var(--prismui-font-size-1)", + color="var(--prismui-color-6)", + ), + rx.box( + rx.cond( + AuthState.is_captcha_sent, + rx.hstack( + rx.icon( + "circle-check", + width="12px", + height="12px", + color="var(--prismui-color-2)", + ), + rx.text( + "验证码已发送,请耐心等待", + line_height="14px", + font_size="var(--prismui-font-size-1)", + color="var(--prismui-color-2)", + ), + margin="0 0 10px 0", + gap="4px", ), - rx.text( - "验证码已发送,请耐心等待", - line_height="14px", - font_size="var(--prismui-font-size-1)", - color="var(--prismui-color-2)", - ), - margin="10px 0", - gap="4px", - ), - rx.text( - AuthState.notification, - width="100%", - text_align="left", - line_height="20px", - font_size="12px", - color="var(--prismui-color-6)", ), + display="flex", + align_items="center", + min_height="34px", ), rx.hstack( rx.checkbox( checked=AuthState.is_policies_agreed, + # 值变化事件:切换协议同意状态 on_change=AuthState.toggle_policies_agreed, + cursor="pointer", + style={ + "&::before": { + "width": "12px !important", + "height": "12px !important", + }, + "& svg": { + "width": "8px !important", + "height": "8px !important", + }, + "&[data-state='checked']::before": { + "background-color": "var(--prismui-color-5) !important", + }, + }, ), - rx.text("我已阅读并同意 ", font_size="13px"), - rx.link("用户协议、隐私政策", font_size="13px", href="#"), + rx.text( + "我已阅读并同意", + color="var(--prismui-color-2)", + line_height="14px", + ), + rx.link( + "用户协议、隐私政策", + href="#", + line_height="14px", + color="var(--prismui-color-5)", + cursor="pointer", + ), + margin_bottom="10px", align_items="center", + gap="4px", + font_size="var(--prismui-font-size-1)", ), rx.button( "登录", width="100%", - bg="#0a0e29", - color="white", - margin_top="12px", + height="38px", + border_radius="var(--prismui-border-radius-2)", + background_color="var(--prismui-color-5)", + color="var(--prismui-color-9)", + cursor="pointer", on_click=AuthState.login, loading=AuthState.is_logging_in, - disabled=AuthState.is_logging_in, ), rx.text( - "登录有问题?去反馈", + "登录遇到问题?加微信去吐槽", + margin="20px 0 40px 0", + line_height="14px", font_size="12px", - color="#666", - margin_top="8px", + color="var(--prismui-color-5)", ), width="396px", + height="100%", padding="40px 48px 0 48px", - background_color="var(--prismui-background-color-1)", align_items="center", + background_color="var(--prismui-background-color-1)", ), rx.vstack( rx.image( src="/qrcode.png", - width="160px", - height="160px", - padding="8px", - border="1px solid #eee", - border_radius="8px", - bg="white", + width="208px", + height="208px", + padding="20px", + background_color="var(--prismui-background-color-1)", + border="var(--prismui-border-2)", + border_radius="var(--prismui-border-radius-3)", ), rx.text( - "添加微信申请使用", - font_size="18px", - font_weight="600", - margin_top="16px", + "加微信好友申请使用", + margin="10px 0 12px 0", + line_height="32px", + font_size="var(--prismui-font-size-2)", + font_weight="var(--prismui-font-weight-2)", ), align_items="center", - width="320px", - padding="40px 32px", - style={"background": "#f8f9fc"}, + justify_content="center", + width="396px", + height="100%", + padding="72px 32px", ), + background="var(--prismui-background-2)", border="1px solid #2222220f", border_radius="var(--prismui-border-radius-3)", box_shadow="0 4px 64px 0 #0000001a", @@ -303,13 +440,11 @@ def render_index() -> rx.Component: overflow="auto", padding="8px 8px 8px 0", background="var(--prismui-background-1)", - # 挂载事件: - on_mount=AuthState.check, ), # 若用户唯一标识为空则渲染登录窗 rx.cond( - AuthState.user_id == "", - render_login_window(), + AuthState.user_id, rx.fragment(), + render_login_window(), ), ) diff --git a/agent/application/states/auth.py b/agent/application/states/auth.py index 5c48d9b..113f9cb 100644 --- a/agent/application/states/auth.py +++ b/agent/application/states/auth.py @@ -32,15 +32,18 @@ class AuthState(rx.State): # 验证码 captcha: str = "" # 协议同意状态 - is_policies_agreed: bool = False - # 提示信息 - notification: str = "" - - # 验证码发送倒计时 - captcha_sending_countdown: int = 0 + is_policies_agreed: bool = True + # 登录错误信息 + login_error_message: str = "" + # 再次发送验证码倒计时 + resend_captcha_countdown: int = 0 + # 验证码已发送状态 + is_captcha_sent: bool = False # 登录中状态 is_logging_in: bool = False + # 设置悬停卡片打开状态 + is_settings_hover_card_open: bool = False # 激活的导航按钮 activated_nav_button: str = "conversation" @@ -54,12 +57,12 @@ class AuthState(rx.State): self.user_id = "" @rx.event - def reset_notification(self) -> None: + def reset_error_message(self) -> None: """ - 清除提示信息 + 重置登录错误信息 :return: None """ - self.notification = "" + self.login_error_message = "" @rx.event def set_email(self, email: str) -> None: @@ -70,28 +73,17 @@ class AuthState(rx.State): """ self.email = email.strip() - @rx.var - def is_captcha_sending_disabled(self) -> bool: - """ - 验证码发送禁用状态 - :return: 禁用状态,True 表示禁用,False 表示未禁用 - """ - """ - 邮箱为空或验证码发送倒计时大于0时禁用 - """ - return not self.email or self.captcha_sending_countdown > 0 - def validate_email(self) -> bool: """ 校验邮箱 - :return: 校验结果,True 表示校验通过,False 表示校验不通过 + :return: 校验是否通过,True 表示通过,False 表示不通过 """ - # 非空校验 + # 邮箱非空校验 if not self.email: - self.notification = "请输入邮箱" + self.login_error_message = "请输入邮箱" return False - # 格式校验 + # 邮箱格式校验 """ 邮箱由用户名@域名组成,其中: 1)用户名首字符为字母或数字,中间可穿插下划线、短横线、加号或点,符号后为字母或数字; @@ -103,34 +95,42 @@ class AuthState(rx.State): r"^[a-zA-Z0-9]+([_\-+.][a-zA-Z0-9_\-+]+)*@[a-zA-Z0-9]+(\-[a-zA-Z0-9\-]+)*(\.[a-zA-Z0-9]+(\-[a-zA-Z0-9\-]+)*)*\.[a-zA-Z0-9]{2,}$", self.email, ): - self.notification = "邮箱格式不正确,请重新输入" + self.login_error_message = "邮箱格式不正确,请重新输入" return False - self.notification = "" + self.login_error_message = "" return True - @rx.event(background=True) - async def resend_captcha_countdown_(self) -> None: + @rx.var + def is_captcha_sending_disabled(self) -> bool: """ - 再次发送验证码倒计时(后台任务) + 验证码发送禁用状态 + 邮箱为空或再次发送验证码倒计时大于0时禁用 + :return: 禁用状态,True 表示禁用,False 表示未禁用 + """ + return not self.email or self.resend_captcha_countdown > 0 + + @rx.event(background=True) + async def countdown(self) -> None: + """ + 倒计时(后台任务) :return: None """ async with self: - self.captcha_sending_countdown = 59 + self.resend_captcha_countdown = 59 - while self.captcha_sending_countdown > 0: + while self.resend_captcha_countdown > 0: await sleep(1) async with self: - self.captcha_sending_countdown -= 1 + self.resend_captcha_countdown -= 1 @rx.event(background=True) - async def send_captcha_(self) -> None: + async def send_captcha_background(self) -> None: """ 发送验证码(后台任务) :return: None """ async with self: - self.notification = "验证码已发送" - # 创建验证码记录并赋值 + # 创建验证码记录并获取验证码 database_state = await self.get_state(DatabaseState) captcha = await database_state.create_captchas_record(email=self.email) @@ -141,13 +141,13 @@ class AuthState(rx.State): "utf-8", ) message["Subject"] = Header("验证码", "utf-8").encode() - message["From"] = "office@liubiren.cloud" + message["From"] = "prism@liubiren.cloud" message["To"] = self.email try: async with SMTP( hostname="smtp.feishu.cn", port=465, - username="office@liubiren.cloud", + username="prism@liubiren.cloud", password="cx1dM5tBcbyWftpS", use_tls=True, local_hostname="localhost", @@ -155,9 +155,7 @@ class AuthState(rx.State): await smtp.send_message(message) except SMTPException: - async with self: - self.notification = f"发送失败,请稍后重试" - self.captcha_sending_countdown = 0 + pass @rx.event async def send_captcha(self) -> AsyncGenerator[EventCallback, None]: @@ -169,9 +167,14 @@ class AuthState(rx.State): if not self.validate_email(): return - # 将再次发送验证码倒计时和发送验证码事件添加至后台任务队列 - yield type(self).resend_captcha_countdown_ - yield type(self).send_captcha_ + if self.resend_captcha_countdown > 0: + return + + self.is_captcha_sent = True + + # 将倒计时和发送验证码事件添加至后台任务队列 + yield type(self).countdown() + yield type(self).send_captcha_background() @rx.event def set_captcha(self, captcha: str) -> None: @@ -182,22 +185,6 @@ class AuthState(rx.State): """ self.captcha = captcha.strip() - def validate_captcha(self) -> bool: - """ - 校验验证码 - :return: 验证是否通过,True 表示校验通过,False 表示校验不通过 - """ - self.notification = "" - # 非空校验 - if not self.captcha: - self.notification = "请输入验证码" - return False - # 格式校验 - if not re.fullmatch(r"^\d{6}$", self.captcha): - self.notification = "验证码格式不正确,请重新输入" - return False - return True - @rx.event def toggle_policies_agreed(self) -> None: """ @@ -212,31 +199,63 @@ class AuthState(rx.State): 登录 :return: None """ - self.is_logging_in = True - - # 验证邮箱格式 + # 验证邮箱 if not self.validate_email(): return - # 验证验证码 - if not self.validate_captcha(): + # 验证码非空校验 + if not self.captcha: + self.login_error_message = "请输入验证码" return - # 创建验证码记录并赋值验证码 - database_state = await self.get_state(DatabaseState) + # 验证码格式校验 + if not re.fullmatch(r"^\d{6}$", self.captcha): + self.login_error_message = "验证码格式不正确,请重新输入" + return + # 校验协议同意状态 + if not self.is_policies_agreed: + self.login_error_message = "请先阅读并同意协议和政策" + return + + self.is_logging_in = True + + # 更新验证码记录,若更新成功则创建用户记录 + database_state = await self.get_state(DatabaseState) if not await database_state.update_captcha( email=self.email, captcha=self.captcha ): - self.notification = "验证码错误" + self.is_logging_in = False + self.login_error_message = "验证码错误" return + self.user_id = await database_state.create_users_record(email=self.email) - # 创建用户记录 - user_id = await database_state.create_users_record(email=self.email) - self.user_id = user_id - self.notification = "登录成功" + self.email = "" + self.captcha = "" + self.is_policies_agreed = True + self.login_error_message = "" + self.resend_captcha_countdown = 0 + self.is_captcha_sent = False self.is_logging_in = False + @rx.event + def set_settings_hover_card_open(self, is_settings_hover_card_open: bool) -> None: + """ + 设置设置悬停卡片打开状态 + :param is_settings_hover_card_open: 设置悬停卡片打开状态,True 表示打开,False 表示关闭 + :return: None + """ + self.is_settings_hover_card_open = is_settings_hover_card_open + + @rx.event + def logout(self) -> None: + """ + 退出登录 + :return: None + """ + self.is_settings_hover_card_open = False + self.user_id = "" + @rx.event def switch_activated_nav_button(self, button: str): """ diff --git a/agent/application/states/conversation.py b/agent/application/states/conversation.py index d64f7aa..44e27ec 100644 --- a/agent/application/states/conversation.py +++ b/agent/application/states/conversation.py @@ -80,6 +80,16 @@ class ConversationState(rx.State): # 正在新建会话状态,True表示正在新建,False表示未正在新建 is_creating_conversation: bool = False + @rx.event + def load_conversation_id(self, conversation_id: str) -> None: + """ + 设置当前会话唯一标识 + :param conversation_id: 当前会话唯一标识 + :return: None + """ + self.conversation_id = conversation_id + + @rx.event async def on_mount(self): """ diff --git a/agent/application/states/database.py b/agent/application/states/database.py index 2d9150b..fe1a67d 100644 --- a/agent/application/states/database.py +++ b/agent/application/states/database.py @@ -67,7 +67,7 @@ class DatabaseState(rx.State): async def update_captcha(self, email: str, captcha: str) -> bool: """ - 更新验证码 + 更新验证码记录 :param email: 邮箱 :param captcha: 验证码 :return: 是否更新成功,True 表示更新成功,False 表示更新失败 @@ -99,6 +99,7 @@ class DatabaseState(rx.State): async with rx.asession() as session: result = await session.exec(select(Users).where(Users.email == email)) record = result.first() + # 若用户记录存在则返回用户唯一标识,否则创建新用户记录并返回所创建的用户唯一标识 if record: return record.id new_user = Users(email=email) diff --git a/agent/assets/qrcode.png b/agent/assets/qrcode.png new file mode 100644 index 0000000..87098f5 Binary files /dev/null and b/agent/assets/qrcode.png differ diff --git a/agent/assets/styles.css b/agent/assets/styles.css new file mode 100644 index 0000000..a1e6ff4 --- /dev/null +++ b/agent/assets/styles.css @@ -0,0 +1,38 @@ +:root { + --prismui-background-color-1: #ffffff; + --prismui-background-color-2: #ebebeb; + --prismui-background-color-3: #f6f6f8; + --prismui-background-color-4: #babbc0; + --prismui-background-color-5: #ffffff33; + --prismui-background-1: linear-gradient(to bottom, #D0C9FF 0%, #E6D6F0 8%, #F1DBEA 12%, #C8DCFB 40%, #ABC6F6 60%, #87AEFE 90%); + --prismui-background-2: linear-gradient(180deg, #fffffff2, #f8fafff2 99%); + --prismui-font-family: HuaweiFont,Helvetica,Arial,PingFangSC-Regular,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Microsoft JhengHei; + --prismui-font-size-1: 12px; + --prismui-font-size-2: 14px; + --prismui-font-size-3: 20px; + --prismui-font-weight-1: normal; + --prismui-font-weight-2: 500; + --prismui-font-weight-3: 700; + --prismui-color-1: #252b3a; + --prismui-color-2: #575d6c; + --prismui-color-3: #babbc0; + --prismui-color-4: #060a263d; + --prismui-color-5: #5e7ce0; + --prismui-color-6: #f66f6a; + --prismui-color-7: #f2f2f3; + --prismui-color-9: #ffffff; + --prismui-border-1: 1px solid rgba(6, 10, 38, 0.06); + --prismui-border-radius-1: 8px; + --prismui-border-radius-2: 12px; + --prismui-border-radius-3: 20px; + --mc-float-block-shadow: #d5d5d5; + --devui-global-bg: #f6f6f8; + --mc-box-shadow: #191919; + --devui-shadow-length-connected-overlay: 0px 0px 12px 0px #000000; + --prismui-box-shadow-1: 0 4px 64px 0 #0000001a; + --prismui-box-shadow-2: 0 4px 12px #0000001a; + --prismui-box-shadow-3: 0 2px 12px 0 #252b3a3d; + --devui-icon-fill-weak: #babbc0; + --prismui-background-color-weak: #babbc0; + --devui-border-radius-feedback: 4px; +} \ No newline at end of file diff --git a/agent/database.db b/agent/database.db index 9e41141..23f3390 100644 Binary files a/agent/database.db and b/agent/database.db differ