From c837f3779e437c3a11bf75e5f0a0002c1707df61 Mon Sep 17 00:00:00 2001 From: sabaimran <65192171+sabaimran@users.noreply.github.com> Date: Mon, 15 Jul 2024 21:40:55 -0700 Subject: [PATCH] Update the agents page with new UX (#850) - Use icons/colors for setting the styling of agents - Update automations page to use the shadcn cards: https://github.com/shadcn-ui/ui --- .../web/app/agents/agents.module.css | 160 -------- src/interface/web/app/agents/layout.tsx | 4 +- src/interface/web/app/agents/page.tsx | 364 ++++++++++++------ src/interface/web/app/automations/layout.tsx | 3 +- .../web/app/components/navMenu/navMenu.tsx | 26 +- src/interface/web/package.json | 10 +- src/interface/web/yarn.lock | 8 +- ...0053_agent_style_color_agent_style_icon.py | 61 +++ src/khoj/database/models/__init__.py | 35 ++ src/khoj/routers/api_agents.py | 2 + src/khoj/routers/api_chat.py | 4 + yarn.lock | 2 + 12 files changed, 395 insertions(+), 284 deletions(-) create mode 100644 src/khoj/database/migrations/0053_agent_style_color_agent_style_icon.py create mode 100644 yarn.lock diff --git a/src/interface/web/app/agents/agents.module.css b/src/interface/web/app/agents/agents.module.css index 671f8ecc..af3490b2 100644 --- a/src/interface/web/app/agents/agents.module.css +++ b/src/interface/web/app/agents/agents.module.css @@ -16,28 +16,7 @@ div.agentPersonality { overflow: hidden; } -div.agentInfo { - font-size: medium; -} -div.agentInfo a, -div.agentInfo h2 { - margin: 0; -} - -div.agent img { - border-radius: 50%; - object-fit: cover; -} - -div.agent a { - text-decoration: none; -} - -div#agentsHeader { - display: grid; - grid-template-columns: auto; -} button.infoButton { border: none; @@ -47,63 +26,6 @@ button.infoButton { font-size: medium; } -div#agentsHeader a, -div.agentInfo button { - font-size: 24px; - font-weight: bold; - padding: 4px; - border: none; - border-radius: 8px; - font: inherit; - cursor: pointer; - transition: background-color 0.3s; -} - -div#agentsHeader a:hover, -div.agentInfo button:hover { - box-shadow: 0 0 10px var(--primary-hover); -} - -div.agent { - display: grid; - grid-template-columns: auto 1fr auto; - gap: 4px; - align-items: center; - padding: 20px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); - border-radius: 8px; - background: linear-gradient(18.48deg,rgba(252, 213, 87, 0.25) 2.76%,rgba(197, 0, 0, 0) 17.23%),linear-gradient(200.6deg,rgba(244, 229, 68, 0.25) 4.13%,rgba(230, 26, 26, 0) 20.54%); -} - -div.agentModal { - background: linear-gradient(18.48deg,rgba(252, 213, 87, 0.25) 2.76%,rgba(197, 0, 0, 0) 17.23%),linear-gradient(200.6deg,rgba(244, 229, 68, 0.25) 4.13%,rgba(230, 26, 26, 0) 20.54%); -} - -div.agentModalContent button { - width: 100%; - margin: 10px 0; - padding: 8px; -} - -div.agentModalHeader { - display: grid; - grid-template-columns: 1fr auto; -} - -div.agentAvatar { - display: flex; - align-items: center; - gap: 8px; -} - -div.agentModalContent p { - white-space: break-spaces; - line-height: 1.5; -} - -div.agentInfo { - text-align: left; -} div.agentList { display: grid; @@ -115,53 +37,6 @@ div.agentList { margin-left: auto; } -svg.newConvoButton { - width: 20px; - margin-left: 5px; -} - -div.agentModalContainer { - position: fixed; /* Changed from absolute to fixed */ - top: 0; - left: 0; - width: 100%; - height: 100%; /* This ensures it covers the viewport height */ - display: flex; - justify-content: center; - align-items: center; - background-color: rgba(1,1,1,0.5); - z-index: 1000; /* Ensure it's above other content */ - overflow-y: auto; /* Allows scrolling within the modal if needed */ -} - -div.agentModal { - position: relative; - width: 50%; - margin: auto; - padding: 20px; - background-color: white; - border-radius: 8px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); -} - -div.agentModalActions { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} - -div.agentModalActions button { - padding: 8px; - border: none; - border-radius: 8px; - font-size: 16px; - cursor: pointer; - transition: background-color 0.3s; -} - -div.agentModalActions button:hover { - box-shadow: 0 0 10px var(hsla(--background)); -} @media only screen and (max-width: 700px) { div.agentList { @@ -171,39 +46,4 @@ div.agentModalActions button:hover { margin-left: auto; grid-template-columns: 1fr; } - - div.agentModal { - width: 90%; - } - -} -.loader { - width: 48px; - height: 48px; - border-radius: 50%; - display: inline-block; - border-top: 4px solid var(--primary-color); - border-right: 4px solid transparent; - box-sizing: border-box; - animation: rotation 1s linear infinite; -} -.loader::after { - content: ''; - box-sizing: border-box; - position: absolute; - left: 0; - top: 0; - width: 48px; - height: 48px; - border-radius: 50%; - border-bottom: 4px solid transparent; - animation: rotation 0.5s linear infinite reverse; -} -@keyframes rotation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } } diff --git a/src/interface/web/app/agents/layout.tsx b/src/interface/web/app/agents/layout.tsx index 7e8e3d59..f24bd08f 100644 --- a/src/interface/web/app/agents/layout.tsx +++ b/src/interface/web/app/agents/layout.tsx @@ -3,6 +3,8 @@ import type { Metadata } from "next"; import NavMenu from '../components/navMenu/navMenu'; import styles from './agentsLayout.module.css'; +import "../globals.css"; + export const metadata: Metadata = { title: "Khoj AI - Agents", description: "Use Agents with Khoj AI for deeper, more personalized queries.", @@ -18,7 +20,7 @@ export default function RootLayout({ }>) { return (
- + {children}
); diff --git a/src/interface/web/app/agents/page.tsx b/src/interface/web/app/agents/page.tsx index 458031a1..a8fd1112 100644 --- a/src/interface/web/app/agents/page.tsx +++ b/src/interface/web/app/agents/page.tsx @@ -10,13 +10,56 @@ import { useEffect, useState } from 'react'; import { useAuthenticatedData, UserProfile } from '../common/auth'; import { Button } from '@/components/ui/button'; +import { + Lightbulb, + Robot, + Aperture, + GraduationCap, + Jeep, + Island, + MathOperations, + Asclepius, + Couch, + Code, + Atom, + ClockCounterClockwise, + PaperPlaneTilt, + Info, + UserCircle +} from "@phosphor-icons/react"; +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; +import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTrigger } from '@/components/ui/dialog'; +import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/components/ui/drawer'; +import LoginPrompt from '../components/loginPrompt/loginPrompt'; +import Loading, { InlineLoading } from '../components/loading/loading'; +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; +interface IconMap { + [key: string]: (color: string, width: string, height: string) => JSX.Element | null; +} + +const iconMap: IconMap = { + Lightbulb: (color: string, width: string, height: string) => , + Robot: (color: string, width: string, height: string) => , + Aperture: (color: string, width: string, height: string) => , + GraduationCap: (color: string, width: string, height: string) => , + Jeep: (color: string, width: string, height: string) => , + Island: (color: string, width: string, height: string) => , + MathOperations: (color: string, width: string, height: string) => , + Asclepius: (color: string, width: string, height: string) => , + Couch: (color: string, width: string, height: string) => , + Code: (color: string, width: string, height: string) => , + Atom: (color: string, width: string, height: string) => , + ClockCounterClockwise: (color: string, width: string, height: string) => , +}; export interface AgentData { slug: string; avatar: string; name: string; personality: string; + color: string; + icon: string; } async function openChat(slug: string, userData: UserProfile | null) { @@ -30,7 +73,7 @@ async function openChat(slug: string, userData: UserProfile | null) { const response = await fetch(`/api/chat/sessions?agent_slug=${slug}`, { method: "POST" }); if (response.status == 200) { window.location.href = `/chat`; - } else if(response.status == 403 || response.status == 401) { + } else if (response.status == 403 || response.status == 401) { window.location.href = unauthenticatedRedirectUrl; } else { alert("Failed to start chat session"); @@ -39,86 +82,68 @@ async function openChat(slug: string, userData: UserProfile | null) { const agentsFetcher = () => window.fetch('/api/agents').then(res => res.json()).catch(err => console.log(err)); -interface AgentModalProps { - data: AgentData; - setShowModal: (show: boolean) => void; - userData: UserProfile | null; -} interface AgentCardProps { data: AgentData; userProfile: UserProfile | null; + isMobileWidth: boolean; } -function AgentModal(props: AgentModalProps) { - const [copiedToClipboard, setCopiedToClipboard] = useState(false); +function getIconFromIconName(iconName: string, color: string = 'gray', width: string = 'w-8', height: string = 'h-8') { + const icon = iconMap[iconName]; + const colorName = color.toLowerCase(); + const colorClass = convertColorToTextClass(colorName); - useEffect(() => { - if (copiedToClipboard) { - setTimeout(() => setCopiedToClipboard(false), 3000); - } - }, [copiedToClipboard]); + return icon ? icon(colorClass, width, height) : null; +} - return ( -
-
-
-
-
- {props.data.name} -

{props.data.name}

-
-
- - -
-
-

{props.data.personality}

-
- -
-
-
-
- ); +function convertColorToClass(color: string) { + // We can't dyanmically generate the classes for tailwindcss, so we have to explicitly use the whole string. + // See models/__init__.py 's definition of the Agent model for the color choices. + if (color === 'red') return `bg-red-500 hover:bg-red-600`; + if (color === 'yellow') return `bg-yellow-500 hover:bg-yellow-600`; + if (color === 'green') return `bg-green-500 hover:bg-green-600`; + if (color === 'blue') return `bg-blue-500 hover:bg-blue-600`; + if (color === 'orange') return `bg-orange-500 hover:bg-orange-600`; + if (color === 'purple') return `bg-purple-500 hover:bg-purple-600`; + if (color === 'pink') return `bg-pink-500 hover:bg-pink-600`; + if (color === 'teal') return `bg-teal-500 hover:bg-teal-600`; + if (color === 'cyan') return `bg-cyan-500 hover:bg-cyan-600`; + if (color === 'lime') return `bg-lime-500 hover:bg-lime-600`; + if (color === 'indigo') return `bg-indigo-500 hover:bg-indigo-600`; + if (color === 'fuschia') return `bg-fuschia-500 hover:bg-fuschia-600`; + if (color === 'rose') return `bg-rose-500 hover:bg-rose-600`; + if (color === 'sky') return `bg-sky-500 hover:bg-sky-600`; + if (color === 'amber') return `bg-amber-500 hover:bg-amber-600`; + if (color === 'emerald') return `bg-emerald-500 hover:bg-emerald-600`; + return `bg-gray-500 hover:bg-gray-600`; +} + +function convertColorToTextClass(color: string) { + if (color === 'red') return `text-red-500`; + if (color === 'yellow') return `text-yellow-500`; + if (color === 'green') return `text-green-500`; + if (color === 'blue') return `text-blue-500`; + if (color === 'orange') return `text-orange-500`; + if (color === 'purple') return `text-purple-500`; + if (color === 'pink') return `text-pink-500`; + if (color === 'teal') return `text-teal-500`; + if (color === 'cyan') return `text-cyan-500`; + if (color === 'lime') return `text-lime-500`; + if (color === 'indigo') return `text-indigo-500`; + if (color === 'fuschia') return `text-fuschia-500`; + if (color === 'rose') return `text-rose-500`; + if (color === 'sky') return `text-sky-500`; + if (color === 'amber') return `text-amber-500`; + if (color === 'emerald') return `text-emerald-500`; + return `text-gray-500`; } function AgentCard(props: AgentCardProps) { const searchParams = new URLSearchParams(window.location.search); const agentSlug = searchParams.get('agent'); const [showModal, setShowModal] = useState(agentSlug === props.data.slug); + const [showLoginPrompt, setShowLoginPrompt] = useState(false); const userData = props.userProfile; @@ -126,52 +151,144 @@ function AgentCard(props: AgentCardProps) { window.history.pushState({}, `Khoj AI - Agent ${props.data.slug}`, `/agents?agent=${props.data.slug}`); } + const stylingString = convertColorToClass(props.data.color); + return ( -
+ { - showModal && + showLoginPrompt && + } - -
- {props.data.name} + + + { + !props.isMobileWidth ? + { + setShowModal(!showModal); + window.history.pushState({}, `Khoj AI - Agents`, `/agents`); + }}> + +
+ { + getIconFromIconName(props.data.icon, props.data.color) || {props.data.name} + } + {props.data.name} +
+
+ + +
+ { + getIconFromIconName(props.data.icon, props.data.color) || {props.data.name} + } + {props.data.name} +
+
+ {props.data.personality} + + + +
+
+ : + { + setShowModal(open); + window.history.pushState({}, `Khoj AI - Agents`, `/agents`); + }}> + +
+ { + getIconFromIconName(props.data.icon, props.data.color) || {props.data.name} + } + {props.data.name} +
+
+ + + {props.data.name} + Full Prompt + + {props.data.personality} + + + Done + + + +
+ } +
+
+ +
+
- -
- -
-
- -
-
- -
-
- ); + + + { + props.userProfile ? + + : + + } + +
+ ) } export default function Agents() { const { data, error } = useSWR('agents', agentsFetcher, { revalidateOnFocus: false }); - const userData = useAuthenticatedData(); + const authenticatedData = useAuthenticatedData(); + const [isMobileWidth, setIsMobileWidth] = useState(false); + const [showLoginPrompt, setShowLoginPrompt] = useState(false); + + useEffect(() => { + if (typeof window !== 'undefined') { + setIsMobileWidth(window.innerWidth < 768); + } + + window.addEventListener('resize', () => { + setIsMobileWidth(window.innerWidth < 768); + }); + }, []); if (error) { return ( @@ -193,7 +310,7 @@ export default function Agents() { Talk to a Specialized Agent
- Loading agents... + booting up your agents
); @@ -201,12 +318,39 @@ export default function Agents() { return (
-
- Talk to a Specialized Agent -
+

+ Agents +

+ { + showLoginPrompt && + + } + + + + How this works + + You can use any of these specialized agents to tailor to tune your conversation to your needs. + { + !authenticatedData && + <> +
+ + + + } +
+ Coming Soon: Support for making your own agents. + +
{data.map(agent => ( - + ))}
diff --git a/src/interface/web/app/automations/layout.tsx b/src/interface/web/app/automations/layout.tsx index 23493c75..7e6f8fc8 100644 --- a/src/interface/web/app/automations/layout.tsx +++ b/src/interface/web/app/automations/layout.tsx @@ -1,9 +1,10 @@ - import type { Metadata } from "next"; import NavMenu from '../components/navMenu/navMenu'; import styles from './automationsLayout.module.css'; import { Toaster } from "@/components/ui/toaster"; +import "../globals.css"; + export const metadata: Metadata = { title: "Khoj AI - Automations", diff --git a/src/interface/web/app/components/navMenu/navMenu.tsx b/src/interface/web/app/components/navMenu/navMenu.tsx index 2409db3e..5eaad6cd 100644 --- a/src/interface/web/app/components/navMenu/navMenu.tsx +++ b/src/interface/web/app/components/navMenu/navMenu.tsx @@ -40,6 +40,7 @@ export default function NavMenu(props: NavMenuProps) { const [isMobileWidth, setIsMobileWidth] = useState(false); const [darkMode, setDarkMode] = useState(false); + const [initialLoadDone, setInitialLoadDone] = useState(false); useEffect(() => { setIsMobileWidth(window.innerWidth < 768); @@ -62,13 +63,26 @@ export default function NavMenu(props: NavMenuProps) { if (localStorage.getItem('theme') === 'dark') { document.documentElement.classList.add('dark'); setDarkMode(true); - } else if (mq.matches) { - document.documentElement.classList.add('dark'); - setDarkMode(true); + } else if (localStorage.getItem('theme') === 'light') { + document.documentElement.classList.remove('dark'); + setDarkMode(false); + } else { + const mq = window.matchMedia( + "(prefers-color-scheme: dark)" + ); + + if (mq.matches) { + document.documentElement.classList.add('dark'); + setDarkMode(true); + } } + + setInitialLoadDone(true); }, []); + useEffect(() => { + if (!initialLoadDone) return; toggleDarkMode(darkMode); }, [darkMode]); @@ -128,17 +142,17 @@ export default function NavMenu(props: NavMenuProps) { : - + Chat - + Agents - + Automations diff --git a/src/interface/web/package.json b/src/interface/web/package.json index 8c94ea7c..fbb4e926 100644 --- a/src/interface/web/package.json +++ b/src/interface/web/package.json @@ -39,17 +39,22 @@ "@types/dompurify": "^3.0.5", "@types/katex": "^0.16.7", "@types/markdown-it": "^14.1.1", + "@types/react": "^18", + "@types/react-dom": "^18", "autoprefixer": "^10.4.19", "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", "cmdk": "^1.0.0", - "cronstrue": "^2.50.0", "dompurify": "^3.1.6", + "eslint": "^8", + "eslint-config-next": "14.2.3", + "clsx": "^2.1.1", + "cronstrue": "^2.50.0", "katex": "^0.16.10", "lucide-react": "^0.397.0", "markdown-it": "^14.1.0", "markdown-it-highlightjs": "^4.1.0", "next": "14.2.3", + "nodemon": "^3.1.3", "postcss": "^8.4.38", "react": "^18", "react-dom": "^18", @@ -58,6 +63,7 @@ "swr": "^2.2.5", "tailwind-merge": "^2.3.0", "tailwindcss": "^3.4.4", + "typescript": "^5", "tailwindcss-animate": "^1.0.7", "vaul": "^0.9.1", "zod": "^3.23.8" diff --git a/src/interface/web/yarn.lock b/src/interface/web/yarn.lock index 60696340..65b65b92 100644 --- a/src/interface/web/yarn.lock +++ b/src/interface/web/yarn.lock @@ -1140,10 +1140,10 @@ resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== -"@types/node@^20": - version "20.14.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" - integrity sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q== +"@types/node@20.14.10": + version "20.14.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" + integrity sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ== dependencies: undici-types "~5.26.4" diff --git a/src/khoj/database/migrations/0053_agent_style_color_agent_style_icon.py b/src/khoj/database/migrations/0053_agent_style_color_agent_style_icon.py new file mode 100644 index 00000000..0aa78c41 --- /dev/null +++ b/src/khoj/database/migrations/0053_agent_style_color_agent_style_icon.py @@ -0,0 +1,61 @@ +# Generated by Django 5.0.6 on 2024-07-13 16:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("database", "0052_alter_searchmodelconfig_bi_encoder_docs_encode_config_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="agent", + name="style_color", + field=models.CharField( + choices=[ + ("blue", "Blue"), + ("green", "Green"), + ("red", "Red"), + ("yellow", "Yellow"), + ("orange", "Orange"), + ("purple", "Purple"), + ("pink", "Pink"), + ("teal", "Teal"), + ("cyan", "Cyan"), + ("lime", "Lime"), + ("indigo", "Indigo"), + ("fuschia", "Fuschia"), + ("rose", "Rose"), + ("sky", "Sky"), + ("amber", "Amber"), + ("emerald", "Emerald"), + ], + default="blue", + max_length=200, + ), + ), + migrations.AddField( + model_name="agent", + name="style_icon", + field=models.CharField( + choices=[ + ("Lightbulb", "Lighbulb"), + ("Health", "Health"), + ("Robot", "Robot"), + ("Aperture", "Aperture"), + ("GraduationCap", "Graduation Cap"), + ("Jeep", "Jeep"), + ("Island", "Island"), + ("MathOperations", "Math Operations"), + ("Asclepius", "Asclepius"), + ("Couch", "Couch"), + ("Code", "Code"), + ("Atom", "Atom"), + ("ClockCounterClockwise", "Clock Counter Clockwise"), + ], + default="Lightbulb", + max_length=200, + ), + ), + ] diff --git a/src/khoj/database/models/__init__.py b/src/khoj/database/models/__init__.py index 096d14bc..1f8d55ab 100644 --- a/src/khoj/database/models/__init__.py +++ b/src/khoj/database/models/__init__.py @@ -103,6 +103,39 @@ class VoiceModelOption(BaseModel): class Agent(BaseModel): + class StyleColorTypes(models.TextChoices): + BLUE = "blue" + GREEN = "green" + RED = "red" + YELLOW = "yellow" + ORANGE = "orange" + PURPLE = "purple" + PINK = "pink" + TEAL = "teal" + CYAN = "cyan" + LIME = "lime" + INDIGO = "indigo" + FUSCHIA = "fuschia" + ROSE = "rose" + SKY = "sky" + AMBER = "amber" + EMERALD = "emerald" + + class StyleIconTypes(models.TextChoices): + LIGHBULB = "Lightbulb" + HEALTH = "Health" + ROBOT = "Robot" + APERTURE = "Aperture" + GRADUATION_CAP = "GraduationCap" + JEEP = "Jeep" + ISLAND = "Island" + MATH_OPERATIONS = "MathOperations" + ASCLEPIUS = "Asclepius" + COUCH = "Couch" + CODE = "Code" + ATOM = "Atom" + CLOCK_COUNTER_CLOCKWISE = "ClockCounterClockwise" + creator = models.ForeignKey( KhojUser, on_delete=models.CASCADE, default=None, null=True, blank=True ) # Creator will only be null when the agents are managed by admin @@ -114,6 +147,8 @@ class Agent(BaseModel): managed_by_admin = models.BooleanField(default=False) chat_model = models.ForeignKey(ChatModelOptions, on_delete=models.CASCADE) slug = models.CharField(max_length=200) + style_color = models.CharField(max_length=200, choices=StyleColorTypes.choices, default=StyleColorTypes.BLUE) + style_icon = models.CharField(max_length=200, choices=StyleIconTypes.choices, default=StyleIconTypes.LIGHBULB) class ProcessLock(BaseModel): diff --git a/src/khoj/routers/api_agents.py b/src/khoj/routers/api_agents.py index cdef6206..8d497aec 100644 --- a/src/khoj/routers/api_agents.py +++ b/src/khoj/routers/api_agents.py @@ -34,6 +34,8 @@ async def all_agents( "public": agent.public, "creator": agent.creator.username if agent.creator else None, "managed_by_admin": agent.managed_by_admin, + "color": agent.style_color, + "icon": agent.style_icon, } ) diff --git a/src/khoj/routers/api_chat.py b/src/khoj/routers/api_chat.py index 15e7a143..8a288b71 100644 --- a/src/khoj/routers/api_chat.py +++ b/src/khoj/routers/api_chat.py @@ -212,6 +212,8 @@ def chat_history( "name": conversation.agent.name, "avatar": conversation.agent.avatar, "isCreator": conversation.agent.creator == user, + "color": conversation.agent.style_color, + "icon": conversation.agent.style_icon, "persona": conversation.agent.personality, } @@ -267,6 +269,8 @@ def get_shared_chat( "name": conversation.agent.name, "avatar": conversation.agent.avatar, "isCreator": conversation.agent.creator == user, + "color": conversation.agent.style_color, + "icon": conversation.agent.style_icon, "persona": conversation.agent.personality, } diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..4a580188 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1