[
  {
    "path": ".gitignore",
    "content": "node_modules\n"
  },
  {
    "path": "README.md",
    "content": "# Open-Poe-AI\n\nOpen-source, self-hosted alternative to [Poe AI](https://poe.com) — chat with multiple large language models from a single interface, on your own infrastructure.\n\nPoe (by Quora) is a hosted aggregator that puts GPT, Claude, Gemini, Grok, DeepSeek, Llama, Mistral and image/video models behind one chat UI. **Open-Poe-AI** is the self-hosted version: bring your own API keys, run it on your own server, and keep full control of prompts, conversations, and data.\n\n## Features\n\n- **Multi-model chat** — unified interface for OpenAI, Anthropic, Google, Mistral, DeepSeek, xAI, Meta Llama, and any OpenAI-compatible endpoint (including local models via Ollama / vLLM / LM Studio).\n- **Multi-bot conversations** — query several models in the same thread and compare answers side by side.\n- **Custom bots** — build and share bots with their own system prompts, tools, and knowledge bases.\n- **Group chat** — multiple users and multiple AI models in one shared conversation.\n- **Multimodal** — text, image generation, vision, and audio; pluggable adapters for image/video model providers.\n- **Bring your own keys** — no subscription, no rate caps beyond the providers you use.\n- **Self-hosted** — Docker Compose for one-command deploy; works on a laptop, VPS, or Kubernetes.\n- **Open protocol** — bot server API so anyone can host their own bot and plug it in.\n\n## Status\n\nEarly work in progress. Contributions welcome.\n\n## Quick start\n\n```bash\ngit clone https://github.com/Anil-matcha/Open-Poe-AI.git\ncd Open-Poe-AI\ncp .env.example .env   # add your provider API keys\ndocker compose up -d\n```\n\nThen open http://localhost:3000.\n\n## License\n\nMIT\n"
  },
  {
    "path": "client/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.*\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/versions\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# env files (can opt-in for committing if needed)\n.env*\n\n# vercel\n.vercel\n\n# typescript\n*.tsbuildinfo\nnext-env.d.ts\npackage-lock.json\n\n"
  },
  {
    "path": "client/app/agents/[agent_id]/[conversation_id]/page.js",
    "content": "import { cookies } from \"next/headers\"; \nimport { fetchAgentData, fetchHistoryData } from \"@/context/fetchAgentData\";\nimport AgentClientWrapper from \"@/components/AgentClientWrapper\";\n\nexport default async function Page({ params }) {\n  const { agent_id, conversation_id } = await params;\n  const cookieStore = await cookies();\n  const cookieStr = cookieStore.toString();\n\n  // Fetch agent and history in parallel\n  const [agentDetails, initialHistory] = await Promise.all([\n    fetchAgentData(agent_id, cookieStr, true),\n    fetchHistoryData(agent_id, conversation_id, cookieStr)\n  ]);\n\n  return (\n    <AgentClientWrapper initialAgentDetails={agentDetails} initialHistory={initialHistory} />\n  );\n}\n"
  },
  {
    "path": "client/app/agents/[agent_id]/page.js",
    "content": "import { cookies } from \"next/headers\";\nimport { fetchAgentData } from \"@/context/fetchAgentData\";\nimport AgentClientWrapper from \"@/components/AgentClientWrapper\";\n\nexport default async function Page({ params }) {\n  const { agent_id } = await params;\n  const cookieStore = await cookies();\n\n  // Fetch agent by slug\n  const agentDetails = await fetchAgentData(agent_id, cookieStore.toString(), true);\n  return (\n    <AgentClientWrapper initialAgentDetails={agentDetails} />\n  );\n}\n"
  },
  {
    "path": "client/app/agents/[agent_id]/profile/page.js",
    "content": "\"use client\";\n\nimport { AgentProfile } from \"ai-agent\";\nimport \"ai-agent/dist/tailwind.css\";\nimport { useParams } from \"next/navigation\";\n\n// Mock user context to pass into components\nconst mockUseUser = () => ({\n  user: {\n    name: \"Tester\",\n    username: \"dev_user\",\n    profile_photo: \"\",\n  }\n});\n\nexport default function AgentProfileRoute() {\n  const params = useParams();\n  const agent_id = params.agent_id;\n\n  return (\n    <div className=\"w-full h-dvh bg-white\">\n      <AgentProfile agent_id={agent_id} useUser={mockUseUser} usedIn=\"muapiapp\" />\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/app/agents/create/page.js",
    "content": "\"use client\";\n\nimport { CreateAgentPage } from \"ai-agent\";\nimport \"ai-agent/dist/tailwind.css\";\n\n// Mock user context to pass into components\nconst mockUseUser = () => ({\n  user: {\n    name: \"Tester\",\n    username: \"dev_user\",\n    profile_photo: \"\",\n  }\n});\n\nexport default function CreateAgentRoute() {\n  return (\n    <div className=\"w-full h-dvh bg-white\">\n      <CreateAgentPage useUser={mockUseUser} usedIn=\"muapiapp\" />\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/app/agents/edit/[id]/page.js",
    "content": "\"use client\";\n\nimport { EditAgentPage } from \"ai-agent\";\nimport \"ai-agent/dist/tailwind.css\";\nimport { useParams } from \"next/navigation\";\n\n// Mock user context to pass into components\nconst mockUseUser = () => ({\n  user: {\n    name: \"Tester\",\n    username: \"dev_user\",\n    profile_photo: \"\",\n  }\n});\n\nexport default function EditAgentRoute() {\n  const params = useParams();\n  const id = params.id;\n\n  return (\n    <div className=\"h-dvh bg-white\">\n      <EditAgentPage id={id} useUser={mockUseUser} usedIn=\"muapiapp\" />\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/app/agents/loading.js",
    "content": "export default function Loading() {\n  return (\n    <div className=\"flex flex-col items-center justify-center min-h-[60vh] gap-4\">\n      <div className=\"w-10 h-10 border-2 border-slate-200 border-t-blue-500 rounded-full animate-spin\" />\n      <p className=\"text-slate-400 text-sm font-bold uppercase tracking-widest animate-pulse\">Syncing Library...</p>\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/app/agents/page.js",
    "content": "\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport Link from \"next/link\";\nimport axios from \"axios\";\nimport { \n  RiRobot2Fill, \n  RiUser3Line, \n  RiLayoutGridLine, \n  RiStarLine, \n  RiSearchLine, \n  RiArrowRightUpLine, \n  RiAddLine,\n  RiInformationLine\n} from \"react-icons/ri\";\n\nconst AgentCard = ({ agent, category }) => (\n  <Link\n    href={`/agents/${agent.agent_id}`}\n    className=\"group flex flex-col bg-white border border-slate-200 rounded-2xl p-2 hover:bg-slate-50 hover:border-slate-300 transition-all duration-200 shadow-sm hover:shadow-md\"\n  >\n    {/* Large Image Top (muapiapp style) */}\n    <div className=\"relative aspect-square w-full rounded-xl overflow-hidden bg-slate-100 border border-slate-200 flex items-center justify-center mb-4\">\n      {agent.icon_url ? (\n        <img\n          src={agent.icon_url}\n          alt={agent.name}\n          className=\"object-cover w-full h-full transition-transform duration-500 group-hover:scale-105\"\n        />\n      ) : (\n        <RiRobot2Fill className=\"w-12 h-12 text-slate-300\" />\n      )}\n      <div className=\"absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity\">\n        <div className=\"p-1.5 bg-white/80 backdrop-blur-md rounded-lg border border-slate-200 shadow-sm\">\n          <RiArrowRightUpLine className=\"w-3.5 h-3.5 text-slate-600\" />\n        </div>\n      </div>\n    </div>\n\n    {/* Content Bottom */}\n    <div className=\"px-2 pb-2\">\n      <div className=\"flex items-center justify-between gap-2 mb-1\">\n        <h3 className=\"text-sm font-bold text-slate-900 truncate group-hover:text-blue-600 transition-colors\">\n          {agent.name}\n        </h3>\n        <span className=\"text-[9px] font-black text-blue-500 uppercase tracking-widest shrink-0\">\n           {category}\n        </span>\n      </div>\n\n      <p className=\"text-[11px] text-slate-500 line-clamp-2 leading-relaxed h-8 mb-4 font-medium\">\n        {agent.description || \"Specialized AI Intelligence Unit for complex workflows.\"}\n      </p>\n\n      <div className=\"flex items-center justify-between mt-auto pt-3 border-t border-slate-100\">\n        <div className=\"flex items-center gap-1.5\">\n          <span className=\"flex h-1 w-1 rounded-full bg-emerald-500 shadow-[0_0_4px_rgba(16,185,129,0.5)]\" />\n          <span className=\"text-[9px] font-bold text-slate-400 uppercase tracking-wider\">Ready</span>\n        </div>\n        <div className=\"text-[9px] font-bold text-slate-200 uppercase tracking-tighter\">\n          ACTIVE HUB\n        </div>\n      </div>\n    </div>\n  </Link>\n);\n\nconst CategorySection = ({ title, icon: Icon, agents, categoryLabel }) => {\n  const items = Array.isArray(agents) ? agents : [];\n  if (items.length === 0) return null;\n  \n  return (\n    <section className=\"animate-fade-in-up\">\n      <div className=\"flex items-center gap-2 mb-6 border-l-2 border-blue-500/30 pl-3\">\n        <Icon className=\"w-4 h-4 text-slate-400\" />\n        <h2 className=\"text-lg font-bold text-slate-900 tracking-tight\">{title}</h2>\n        <span className=\"text-[10px] font-black text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded-md ml-1\">{items.length}</span>\n      </div>\n      <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\">\n        {items.map(a => (\n          <AgentCard key={a.id || a.agent_id} agent={a} category={categoryLabel} />\n        ))}\n      </div>\n    </section>\n  );\n};\n\nexport default function AgentsLibrary() {\n  const [agents, setAgents] = useState([]);\n  const [templates, setTemplates] = useState([]);\n  const [featured, setFeatured] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n  const [searchTerm, setSearchTerm] = useState(\"\");\n  const [activeTab, setActiveTab] = useState(\"workforce\"); // Removed \"all\"\n\n  const fetchAllData = useCallback(async () => {\n    try {\n      setLoading(true);\n      setError(null);\n      \n      const BASE_URL = \"/api/agents\";\n\n      const [userRes, templatesRes, featuredRes] = await Promise.all([\n        axios.get(`${BASE_URL}/user/agents`),\n        axios.get(`${BASE_URL}/templates/agents`),\n        axios.get(`${BASE_URL}/featured/agents`)\n      ]);\n\n      setAgents(Array.isArray(userRes.data) ? userRes.data : []);\n      setTemplates(Array.isArray(templatesRes.data) ? templatesRes.data : []);\n      setFeatured(Array.isArray(featuredRes.data) ? featuredRes.data : []);\n    } catch (err) {\n      console.error(err);\n      setError(\"Synchronizing failed. Check connectivity.\");\n    } finally {\n      setLoading(false);\n    }\n  }, []);\n\n  useEffect(() => {\n    fetchAllData();\n  }, [fetchAllData]);\n\n  const filterAgents = (list) => {\n    const arr = Array.isArray(list) ? list : [];\n    if (!searchTerm) return arr;\n    return arr.filter(a => \n      (a.name && a.name.toLowerCase().includes(searchTerm.toLowerCase())) || \n      (a.description && a.description.toLowerCase().includes(searchTerm.toLowerCase()))\n    );\n  };\n\n  const filteredAgents = filterAgents(agents);\n  const filteredTemplates = filterAgents(templates);\n  const filteredFeatured = filterAgents(featured);\n\n  const TABS = [\n    { id: \"workforce\", label: \"My Workforce\", icon: RiUser3Line },\n    { id: \"templates\", label: \"Templates\", icon: RiLayoutGridLine },\n    { id: \"featured\", label: \"Featured\", icon: RiStarLine },\n  ];\n\n  return (\n    <div className=\"min-h-screen bg-[#FDFDFD] text-slate-900 selection:bg-blue-500/10 font-sans pb-20\">\n      <div className=\"fixed top-0 right-0 w-1/3 h-1/3 bg-blue-500/[0.03] rounded-full blur-[100px] pointer-events-none\" />\n      <div className=\"fixed inset-0 bg-[#00000003] backdrop-noise pointer-events-none\" />\n\n      <div className=\"relative z-10 max-w-[1400px] mx-auto px-6 py-12\">\n        \n        <header className=\"flex flex-col md:flex-row md:items-center justify-between gap-6 mb-12 animate-fade-in-up\">\n          <div className=\"space-y-1\">\n            <h1 className=\"text-3xl font-bold tracking-tight text-slate-900 flex items-center gap-2\">\n              <RiRobot2Fill className=\"text-blue-600 w-8 h-8\" />\n              Agent Library\n            </h1>\n            <p className=\"text-slate-400 text-sm font-medium uppercase tracking-widest text-[10px]\">Manage Intelligence Workflow</p>\n          </div>\n\n          <div className=\"flex flex-col sm:flex-row items-center gap-3\">\n             <div className=\"relative min-w-[280px]\">\n                <RiSearchLine className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400\" />\n                <input \n                  type=\"text\"\n                  placeholder=\"Filter intelligence...\"\n                  value={searchTerm}\n                  onChange={(e) => setSearchTerm(e.target.value)}\n                  className=\"w-full bg-white border border-slate-200 rounded-xl pl-9 pr-4 py-2 text-sm outline-none focus:border-blue-500/40 focus:ring-4 focus:ring-blue-500/5 transition-all font-medium text-slate-900监测:text-slate-400\"\n                />\n             </div>\n             <Link \n               href=\"/agents/create\"\n               className=\"flex items-center justify-center gap-1.5 px-5 py-2 bg-slate-900 text-white text-sm font-bold rounded-xl hover:bg-slate-800 transition-all shrink-0 shadow-sm\"\n             >\n               <RiAddLine className=\"w-4 h-4\" />\n               Create\n             </Link>\n          </div>\n        </header>\n\n        {/* Tab Strip */}\n        <nav className=\"flex items-center gap-1 bg-slate-100/50 border border-slate-200/60 p-1 rounded-2xl mb-12 w-fit animate-fade-in-up shadow-sm\" style={{ animationDelay: '0.1s' }}>\n          {TABS.map(tab => (\n            <button\n              key={tab.id}\n              onClick={() => setActiveTab(tab.id)}\n              className={`flex items-center gap-2 px-5 py-2.5 text-[12px] font-bold rounded-xl transition-all ${\n                activeTab === tab.id \n                  ? \"bg-white text-slate-900 shadow-sm border border-slate-200/50\" \n                  : \"text-slate-500 hover:text-slate-900 hover:bg-white/50\"\n              }`}\n            >\n              <tab.icon className={`w-3.5 h-3.5 ${activeTab === tab.id ? \"text-blue-600\" : \"text-slate-400\"}`} />\n              {tab.label}\n            </button>\n          ))}\n        </nav>\n\n        {loading ? (\n          <div className=\"flex flex-col items-center justify-center py-32 gap-4\">\n            <div className=\"w-8 h-8 border-2 border-slate-200 border-t-blue-500 rounded-full animate-spin\" />\n            <p className=\"text-slate-400 text-[10px] font-bold uppercase tracking-widest animate-pulse\">Syncing Library...</p>\n          </div>\n        ) : error ? (\n          <div className=\"flex flex-col items-center justify-center py-20 p-8 border border-slate-200 bg-white rounded-3xl text-center max-w-md mx-auto shadow-sm\">\n             <RiInformationLine className=\"w-8 h-8 text-red-500/50 mb-4\" />\n             <h2 className=\"text-lg font-bold mb-1 text-slate-900\">Connection Error</h2>\n             <p className=\"text-slate-500 text-xs mb-6 leading-relaxed\">{error}</p>\n             <button \n               onClick={fetchAllData}\n               className=\"px-6 py-2 bg-slate-900 text-white rounded-xl text-xs font-bold hover:bg-slate-800 transition-all shadow-sm\"\n             >\n               Reconnect\n             </button>\n          </div>\n        ) : (\n          <div className=\"space-y-4\">\n            \n            {activeTab === \"workforce\" && (\n              <CategorySection \n                title=\"My Workforce\"\n                icon={RiUser3Line}\n                agents={filteredAgents}\n                categoryLabel=\"Personal\"\n              />\n            )}\n\n            {activeTab === \"templates\" && (\n              <CategorySection \n                title=\"Templates\"\n                icon={RiLayoutGridLine}\n                agents={filteredTemplates}\n                categoryLabel=\"Blueprint\"\n              />\n            )}\n\n            {activeTab === \"featured\" && (\n              <CategorySection \n                title=\"Featured\"\n                icon={RiStarLine}\n                agents={filteredFeatured}\n                categoryLabel=\"Verified\"\n              />\n            )}\n\n            {(activeTab === \"workforce\" ? filteredAgents : activeTab === \"templates\" ? filteredTemplates : filteredFeatured).length === 0 && (\n              <div className=\"py-32 text-center bg-slate-50/50 rounded-3xl border border-dashed border-slate-200\">\n                <RiSearchLine className=\"w-10 h-10 text-slate-200 mx-auto mb-4\" />\n                <h3 className=\"text-lg font-bold text-slate-400 mb-1\">No units found</h3>\n                <p className=\"text-slate-400 text-[10px] font-medium uppercase tracking-widest\">Adjust filters or architect a new unit</p>\n              </div>\n            )}\n\n          </div>\n        )}\n      </div>\n\n      <style jsx global>{`\n        @keyframes fade-in-up {\n          from { opacity: 0; transform: translateY(10px); }\n          to { opacity: 1; transform: translateY(0); }\n        }\n        .animate-fade-in-up {\n          animation: fade-in-up 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n          opacity: 0;\n        }\n        .backdrop-noise {\n          background-image: url('https://grainy-gradients.vercel.app/noise.svg');\n          opacity: 0.01;\n          filter: contrast(120%) brightness(120%);\n        }\n      `}</style>\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/app/globals.css",
    "content": "@import \"tailwindcss\";\n\n:root {\n  --background: #ffffff;\n  --foreground: #171717;\n}\n\n@theme inline {\n  --color-background: var(--background);\n  --color-foreground: var(--foreground);\n  --font-sans: var(--font-geist-sans);\n  --font-mono: var(--font-geist-mono);\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --background: #0a0a0a;\n    --foreground: #ededed;\n  }\n}\n\nbody {\n  background: var(--background);\n  color: var(--foreground);\n  font-family: Arial, Helvetica, sans-serif;\n}\n"
  },
  {
    "path": "client/app/layout.js",
    "content": "import { Geist, Geist_Mono } from \"next/font/google\";\nimport \"./globals.css\";\n\nconst geistSans = Geist({\n  variable: \"--font-geist-sans\",\n  subsets: [\"latin\"],\n});\n\nconst geistMono = Geist_Mono({\n  variable: \"--font-geist-mono\",\n  subsets: [\"latin\"],\n});\n\nexport const metadata = {\n  title: \"Vibe-Agents Client\",\n  description: \"Testing Vibe-Agents proxy and frontend package\",\n};\n\nexport default function RootLayout({ children }) {\n  return (\n    <html lang=\"en\">\n      <body\n        className={`${geistSans.variable} ${geistMono.variable} antialiased`}\n      >\n        {children}\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "client/app/page.js",
    "content": "\"use client\";\n\nimport React from \"react\";\nimport Link from \"next/link\";\nimport { RiRobot2Fill, RiTeamLine, RiFlashlightLine, RiNodeTree } from \"react-icons/ri\";\n\nexport default function WelcomePage() {\n  return (\n    <div className=\"relative min-h-screen w-full bg-white text-slate-900 overflow-hidden selection:bg-blue-500/10 font-sans\">\n      {/* Premium Background Effects */}\n      <div className=\"fixed top-[-10%] right-[-5%] w-[50%] h-[50%] bg-blue-500/[0.03] rounded-full blur-[120px] pointer-events-none\" />\n      <div className=\"fixed bottom-[-10%] left-[-5%] w-[50%] h-[50%] bg-purple-500/[0.03] rounded-full blur-[120px] pointer-events-none\" style={{ animationDelay: '2s' }} />\n      <div className=\"fixed inset-0 bg-[linear-gradient(to_right,#00000005_1px,transparent_1px),linear-gradient(to_bottom,#00000005_1px,transparent_1px)] bg-[size:40px_40px] pointer-events-none\" />\n      \n      {/* Subtle Noise Texture */}\n      <div className=\"fixed inset-0 opacity-[0.01] pointer-events-none bg-[url('https://grainy-gradients.vercel.app/noise.svg')] filter contrast(120%) brightness(120%)\" />\n\n      <div className=\"relative z-10 flex flex-col items-center justify-center px-6 pt-20 pb-32 max-w-7xl mx-auto min-h-screen\">\n        {/* Badge */}\n        <div className=\"mb-8 inline-flex items-center gap-2 px-3 py-1 bg-blue-50 border border-blue-100 rounded-full animate-fade-in-up\">\n          <span className=\"flex h-2 w-2 rounded-full bg-blue-500 animate-pulse\" />\n          <span className=\"text-xs font-bold tracking-wide text-blue-600 uppercase\">Next Gen AI Engine</span>\n        </div>\n\n        {/* Hero Title */}\n        <h1 className=\"text-6xl md:text-8xl font-black text-center tracking-tighter leading-[0.9] mb-8 bg-gradient-to-b from-slate-900 via-slate-800 to-slate-500 bg-clip-text text-transparent animate-fade-in-up\" style={{ animationDelay: '0.1s' }}>\n          Vibe-Agents <br />\n          <span className=\"text-blue-600\">Intelligent Workforce</span>\n        </h1>\n\n        {/* Description */}\n        <p className=\"max-w-2xl text-center text-lg md:text-xl text-slate-500 font-medium leading-relaxed mb-12 animate-fade-in-up\" style={{ animationDelay: '0.2s' }}>\n          Unleash autonomous AI agents that think, collaborate, and execute. \n          The ultimate platform for architecting specialized intelligence into your workflows.\n        </p>\n\n        {/* CTA Section */}\n        <div className=\"flex flex-col sm:flex-row gap-4 items-center animate-fade-in-up\" style={{ animationDelay: '0.3s' }}>\n          <Link \n            href=\"/agents\"\n            className=\"group relative px-8 py-4 bg-slate-900 text-white font-bold rounded-2xl transition-all hover:scale-[1.02] active:scale-[0.98] shadow-lg shadow-slate-200 hover:shadow-xl hover:shadow-slate-300 overflow-hidden\"\n          >\n            <div className=\"absolute inset-0 bg-gradient-to-r from-blue-600 to-blue-500 opacity-0 group-hover:opacity-100 transition-opacity\" />\n            <span className=\"relative flex items-center gap-2\">\n              Browse Agent Library\n              <RiRobot2Fill className=\"w-5 h-5 group-hover:rotate-12 transition-transform\" />\n            </span>\n          </Link>\n          <Link \n            href=\"/agents/create\"\n            className=\"px-8 py-4 bg-white border border-slate-200 text-slate-900 font-bold rounded-2xl hover:bg-slate-50 transition-all active:scale-[0.98] shadow-sm\"\n          >\n            Architect New Agent\n          </Link>\n        </div>\n\n        {/* Features Grid */}\n        <div className=\"mt-32 grid grid-cols-1 md:grid-cols-3 gap-6 w-full animate-fade-in-up\" style={{ animationDelay: '0.4s' }}>\n          <div className=\"p-8 rounded-3xl bg-white border border-slate-100 shadow-sm group hover:border-blue-500/30 transition-all\">\n            <div className=\"w-12 h-12 rounded-2xl bg-blue-50 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform\">\n              <RiTeamLine className=\"w-6 h-6 text-blue-600\" />\n            </div>\n            <h3 className=\"text-xl font-bold mb-3 text-slate-900\">Multi-Agent Teams</h3>\n            <p className=\"text-slate-500 leading-relaxed font-medium\">Build swarms of specialized agents that collaborate on complex tasks through natural language.</p>\n          </div>\n\n          <div className=\"p-8 rounded-3xl bg-white border border-slate-100 shadow-sm group hover:border-purple-500/30 transition-all\">\n            <div className=\"w-12 h-12 rounded-2xl bg-purple-50 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform\">\n              <RiFlashlightLine className=\"w-6 h-6 text-purple-600\" />\n            </div>\n            <h3 className=\"text-xl font-bold mb-3 text-slate-900\">Instant Execution</h3>\n            <p className=\"text-slate-500 leading-relaxed font-medium\">From code generation to visual design, agents execute with unprecedented speed and accuracy.</p>\n          </div>\n\n          <div className=\"p-8 rounded-3xl bg-white border border-slate-100 shadow-sm group hover:border-slate-300 transition-all\">\n            <div className=\"w-12 h-12 rounded-2xl bg-slate-100 flex items-center justify-center mb-6 group-hover:scale-110 transition-transform\">\n              <RiNodeTree className=\"w-6 h-6 text-slate-600\" />\n            </div>\n            <h3 className=\"text-xl font-bold mb-3 text-slate-900\">Modular Logic</h3>\n            <p className=\"text-slate-500 leading-relaxed font-medium\">Deeply integrated with Vibe-Workflow for seamless bridging between human intent and automated logic.</p>\n          </div>\n        </div>\n      </div>\n\n      <style jsx global>{`\n        @keyframes fade-in-up {\n          from { opacity: 0; transform: translateY(20px); }\n          to { opacity: 1; transform: translateY(0); }\n        }\n        .animate-fade-in-up {\n          animation: fade-in-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n          opacity: 0;\n        }\n      `}</style>\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/components/AgentClientWrapper.js",
    "content": "\"use client\";\n\nimport { AiAgent } from \"ai-agent\";\nimport \"ai-agent/dist/tailwind.css\";\n\n// Mock user context to pass into AiAgent\nconst mockUseUser = () => ({\n  user: {\n    name: \"Tester\",\n    username: \"dev_user\",\n    profile_photo: \"\",\n  }\n});\n\nexport default function AgentClientWrapper({ initialAgentDetails, initialHistory = null }) {\n  return (\n    <div className=\"h-dvh w-full\">\n      <AiAgent \n        initialAgentDetails={initialAgentDetails} \n        initialHistory={initialHistory} \n        useUser={mockUseUser}\n        usedIn=\"muapiapp\"\n      />\n    </div>\n  );\n}\n"
  },
  {
    "path": "client/context/fetchAgentData.js",
    "content": "export async function fetchAgentData(id, cookieHeader, byName = false) {\n  const endpoint = `http://127.0.0.1:8000/api/agents/by-slug/${id}`;\n  const res = await fetch(endpoint, {\n    cache: 'no-store',\n    headers: {\n      'Cookie': cookieHeader || '',\n    },\n  });\n\n  if (!res.ok) return null;\n\n  return await res.json();\n}\n\nexport async function fetchHistoryData(agentSlug, conversationId, cookieHeader) {\n  const endpoint = `http://127.0.0.1:8000/api/agents/by-slug/${agentSlug}/${conversationId}`;\n  const res = await fetch(endpoint, {\n    cache: 'no-store',\n    headers: {\n      'Cookie': cookieHeader || '',\n    },\n  });\n\n  if (!res.ok) return null;\n  return await res.json();\n}\n"
  },
  {
    "path": "client/jsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@/*\": [\n        \"./*\"\n      ]\n    }\n  }\n}"
  },
  {
    "path": "client/next.config.mjs",
    "content": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  transpilePackages: ['ai-agent'],\n  images: {\n    remotePatterns: [\n      {\n        protocol: 'https',\n        hostname: 'cdn.muapi.ai',\n        port: '',\n        pathname: '/**',\n      },\n    ],\n  },\n  async rewrites() {\n    return [\n      {\n        source: '/api/:path*',\n        destination: 'http://localhost:8000/api/:path*',\n      },\n    ];\n  },\n};\n\nexport default nextConfig;\n"
  },
  {
    "path": "client/package.json",
    "content": "{\n  \"name\": \"vibe-agents-client\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"eslint\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^1.13.2\",\n    \"next\": \"16.1.1\",\n    \"react\": \"19.2.3\",\n    \"react-dom\": \"19.2.3\",\n    \"react-icons\": \"^5.5.0\",\n    \"react-hot-toast\": \"^2.4.1\",\n    \"reactflow\": \"^11.11.4\",\n    \"ai-agent\": \"*\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/postcss\": \"^4\",\n    \"eslint\": \"^9\",\n    \"eslint-config-next\": \"16.1.1\",\n    \"tailwindcss\": \"^4\"\n  }\n}\n"
  },
  {
    "path": "client/postcss.config.mjs",
    "content": "const config = {\n  plugins: {\n    \"@tailwindcss/postcss\": {},\n  },\n};\n\nexport default config;\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"vibe-agents-monorepo\",\n    \"version\": \"1.0.0\",\n    \"private\": true,\n    \"workspaces\": [\n        \"packages/*\",\n        \"client\",\n        \"server\"\n    ],\n    \"scripts\": {\n        \"dev:app\": \"npm run dev -w client\",\n        \"build:app\": \"npm run build -w client\",\n        \"build:lib\": \"npm run build -w packages/agents\",\n        \"install:all\": \"npm install\"\n    }\n}\n"
  },
  {
    "path": "packages/agents/.gitignore",
    "content": "node_modules\npackage-lock.json\ndist"
  },
  {
    "path": "packages/agents/README.md",
    "content": "# AI Agent\n\nA premium React component for AI interactions.\n\n## Installation\n\nTo use this component in another project, run:\n\n```bash\nnpm install git+https://github.com/jaiprasad04/ai-agent.git\n```\n\n## Usage\n\n### 1. Import the Component\n\n```javascript\nimport { AiAgent } from 'ai-agent';\n```\n\n### 2. Import the Styles\n\nYou must import the CSS file for the component to look correct:\n\n```javascript\nimport 'ai-agent/dist/tailwind.css';\n```\n\n### 3. Example\n\n```jsx\nimport React from 'react';\nimport { AiAgent } from 'ai-agent';\nimport 'ai-agent/dist/tailwind.css';\n\nfunction App() {\n  return (\n    <div className=\"App\">\n      <AiAgent />\n    </div>\n  );\n}\n\nexport default App;\n```\n\n## Development\n\nIf you want to modify the component:\n\n1. Clone the repo\n2. Run `npm install`\n3. Run `npm run build` to update the `dist/` folder\n"
  },
  {
    "path": "packages/agents/THEME_SETUP.md",
    "content": "# Theme Setup Guide\n\nThis library uses `next-themes` to manage light and dark modes. For the theme switching buttons to work correctly, you must wrap your application with the provided `AgentThemeProvider`.\n\n## 1. Wrap your Application\nIn your root layout or `App` component, import and use `AgentThemeProvider`.\n\n### Next.js (App Router)\nIn your `layout.js`:\n\n```jsx\nimport { AgentThemeProvider } from 'ai-agent';\n\nexport default function RootLayout({ children }) {\n  return (\n    <html lang=\"en\" suppressHydrationWarning>\n      <body>\n        <AgentThemeProvider>\n          {children}\n        </AgentThemeProvider>\n      </body>\n    </html>\n  )\n}\n```\n> [!IMPORTANT]\n> Adding `suppressHydrationWarning` to the `<html>` tag is required by `next-themes` to avoid hydration mismatch errors.\n\n### Other React Apps\nWrap your main component:\n```jsx\nimport { AgentThemeProvider } from 'ai-agent';\n\nReactDOM.render(\n  <AgentThemeProvider>\n    <App />\n  </AgentThemeProvider>,\n  document.getElementById('root')\n);\n```\n\n## 2. Tailwind Configuration\nEnsure your `tailwind.config.js` in the **consuming project** includes `darkMode: 'class'`:\n```javascript\nmodule.exports = {\n  darkMode: 'class',\n  // ... rest of your config\n}\n```\n\n## 3. Usage\nOnce the provider is in place, the theme switching logic inside `HomepageNavbar` (and other components) will work automatically, toggling the `.dark` class on the `<html>` element.\n"
  },
  {
    "path": "packages/agents/babel.config.json",
    "content": "{\n  \"presets\": [\n    \"@babel/preset-env\",\n    [\"@babel/preset-react\", { \"runtime\": \"automatic\" }]\n  ]\n}\n"
  },
  {
    "path": "packages/agents/package.json",
    "content": "{\n  \"name\": \"ai-agent\",\n  \"version\": \"1.0.0\",\n  \"description\": \"AI Agent\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build:css\": \"tailwindcss -i ./src/tailwind.css -o ./dist/tailwind.css --minify\",\n    \"build\": \"npm run build:css && babel src --out-dir dist --extensions .js,.jsx\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"axios\": \"^1.7.0\",\n    \"next-themes\": \"^0.4.6\",\n    \"react-hot-toast\": \"^2.5.2\",\n    \"react-icons\": \"^5.0.1\",\n    \"react-markdown\": \"^9.0.0\",\n    \"react-toastify\": \"^11.0.5\",\n    \"reactflow\": \"^11.11.4\",\n    \"remark-gfm\": \"^4.0.0\"\n  },\n  \"peerDependencies\": {\n    \"react\": \">=18.0.0\",\n    \"react-dom\": \">=18.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.28.3\",\n    \"@babel/preset-env\": \"^7.28.5\",\n    \"@babel/preset-react\": \"^7.28.5\",\n    \"autoprefixer\": \"^10.4.14\",\n    \"postcss\": \"^8.4.24\",\n    \"tailwindcss\": \"^3.3.3\"\n  }\n}\n"
  },
  {
    "path": "packages/agents/postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "packages/agents/src/AgentProfile.jsx",
    "content": "\"use client\";\n\nimport { Toaster } from \"react-hot-toast\";\nimport ProfileAgent from \"./components/ProfileAgent\";\n\nconst AgentProfile = ({ useUser, usedIn = \"muapiapp\" }) => {\n  return (\n    <div className=\"h-screen w-full flex flex-col bg-blue-50/50 transition-all duration-300 ease-in-out\">\n      <Toaster position=\"top-center\" reverseOrder={false} />\n      <main className=\"flex flex-col items-center gap-2 w-full h-full overflow-y-auto pt-8\">\n        <ProfileAgent useUser={useUser} usedIn={usedIn} />\n      </main>\n    </div>\n  );\n};\n\nexport default AgentProfile;\n"
  },
  {
    "path": "packages/agents/src/AiAgent.jsx",
    "content": "\"use client\";\n\nimport React, { useState, useEffect, useRef } from \"react\";\nimport { useParams, useRouter, useSearchParams } from \"next/navigation\";\nimport axios from \"axios\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { IoSend, IoChevronBack, IoColorPalette, IoAdd, IoHeart, IoHeartOutline, IoChatbubbleEllipsesSharp } from \"react-icons/io5\";\nimport { HiLightBulb } from \"react-icons/hi2\";\nimport { MdTerminal, MdPerson, MdClose, MdEdit, MdContentCopy, MdCheck, MdFullscreen, MdFileDownload, MdImage } from \"react-icons/md\";\nimport { RiRobot2Fill } from \"react-icons/ri\";\nimport { HiOutlinePencilAlt } from \"react-icons/hi\";\nimport { BiLoaderAlt } from \"react-icons/bi\";\nimport { VscDebugAlt } from \"react-icons/vsc\";\nimport { themes } from \"./components/themes\";\nimport { FaAngleRight } from \"react-icons/fa6\";\n\nconst BASE_URL = \"/api/agents\"; // \"https://api.muapi.ai/agents\";\n\nconst formatMessageTime = (date) => {\n  if (!date) return \"\";\n  return new Intl.DateTimeFormat(\"en-US\", {\n    hour: \"numeric\",\n    minute: \"2-digit\",\n    hour12: true,\n  }).format(new Date(date));\n};\n\nconst getDateHeader = (date) => {\n  const d = new Date(date);\n  const now = new Date();\n  const yesterday = new Date(now);\n  yesterday.setDate(now.getDate() - 1);\n\n  if (d.toDateString() === now.toDateString()) return \"Today\";\n  if (d.toDateString() === yesterday.toDateString()) return \"Yesterday\";\n\n  return d.toLocaleDateString(\"en-US\", {\n    month: \"short\",\n    day: \"numeric\",\n    year: d.getFullYear() !== now.getFullYear() ? \"numeric\" : undefined,\n  });\n};\n\nconst parseMessageContent = (text) => {\n  if (!text) return [];\n  const urlRegex = /(https?:\\/\\/[^\\s]+)/g;\n  const parts = [];\n  let lastIndex = 0;\n  let match;\n\n  while ((match = urlRegex.exec(text)) !== null) {\n    const start = match.index;\n    const end = start + match[0].length;\n    const url = match[0];\n\n    if (start > lastIndex) {\n      parts.push({ type: \"text\", content: text.substring(lastIndex, start) });\n    }\n\n    const cleanUrl = url.split(\"?\")[0].toLowerCase();\n    const isImage = /\\.(jpg|jpeg|png|gif|webp|svg)$/i.test(cleanUrl);\n    const isVideo = /\\.(mp4|webm|mov|ogg)$/i.test(cleanUrl);\n    const isAudio = /\\.(mp3|wav|mpeg)$/i.test(cleanUrl);\n\n    if (isImage) {\n      parts.push({ type: \"image\", url });\n    } else if (isVideo) {\n      parts.push({ type: \"video\", url });\n    } else if (isAudio) {\n      parts.push({ type: \"audio\", url });\n    } else {\n      parts.push({ type: \"text\", content: url });\n    }\n\n    lastIndex = end;\n  }\n\n  if (lastIndex < text.length) {\n    parts.push({ type: \"text\", content: text.substring(lastIndex) });\n  }\n\n  return parts;\n};\n\nconst CopyButton = ({ text }) => {\n  const [copied, setCopied] = useState(false);\n\n  const handleCopy = async () => {\n    try {\n      await navigator.clipboard.writeText(text);\n      setCopied(true);\n      setTimeout(() => setCopied(false), 2000);\n    } catch (err) {\n      console.error(\"Failed to copy text: \", err);\n    }\n  };\n\n  return (\n    <button\n      onClick={handleCopy}\n      className=\"p-1.5 rounded-lg border transition-all group relative border-[var(--border-color)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--component-hover)]\"\n      title=\"Copy to clipboard\"\n      type=\"button\"\n    >\n      {copied ? (\n        <MdCheck className=\"w-3.5 h-3.5 text-green-400\" />\n      ) : (\n        <MdContentCopy className=\"w-3.5 h-3.5\" />\n      )}\n      <span\n        className={`absolute -top-8 left-1/2 -translate-x-1/2 px-2 py-1 bg-slate-800 text-white text-[10px] rounded pointer-events-none transition-opacity duration-200 ${copied ? \"opacity-100\" : \"opacity-0\"\n          }`}\n      >\n        Copied!\n      </span>\n    </button>\n  );\n};\n\nconst ChatPage = ({ \n  initialAgentDetails, \n  useUser, \n  usedIn = \"muapiapp\",\n  useSidebar,\n  searchQuery = \"\",\n  setSearchQuery = () => {},\n  getSearchItems = () => {},\n  initialHistory = null,\n}) => {\n  const { id: routeAgentId, agent_id, agent_name, conversation_id: routeConversationId } = useParams();\n  const effectiveAgentId = agent_id || agent_name || routeAgentId;\n  const lowerAgentSlug = effectiveAgentId?.toLowerCase();\n  \n  const effectiveConversationId = routeConversationId;\n  const router = useRouter();\n  \n  const userContext = useUser ? useUser() : {};\n  let userName = \"User\";\n  let userProfile = null;\n\n  if (usedIn === \"vadoo\") {\n    const { serverDetails } = userContext;\n    userName = serverDetails?.user_details?.name || \"User\";\n    userProfile = serverDetails?.user_details?.profile;\n  } else if (usedIn === \"muapiapp\") {\n    // muapiapp\n    const { user } = userContext;\n    userName = user?.username || user?.name || \"User\";\n    userProfile = user?.profile_photo;\n  }\n\n  const [messages, setMessages] = useState(() => {\n    if (initialHistory && initialHistory.history) {\n      return initialHistory.history.map((msg, i) => {\n        let ts = msg.timestamp || initialHistory.created_at || new Date();\n        if (typeof ts === 'string' && ts.includes('T') && !ts.endsWith('Z') && !ts.includes('+')) {\n          ts += 'Z';\n        }\n        return {\n          ...msg,\n          id: msg.id || `${msg.role}_${Date.now()}_${i}`,\n          timestamp: ts\n        };\n      });\n    }\n    return [];\n  });\n  const [input, setInput] = useState(\"\");\n  const [isStreaming, setIsStreaming] = useState(() => {\n    if (typeof window !== 'undefined' && effectiveConversationId) {\n      return !!sessionStorage.getItem('pending_first_msg');\n    }\n    return false;\n  });\n  const [agentDetails, setAgentDetails] = useState(initialAgentDetails || null);\n  const [error, setError] = useState(null);\n  const [debugLogs, setDebugLogs] = useState([]);\n  const [showDebug, setShowDebug] = useState(false);\n  const conversationIdRef = useRef(null);\n  const [showDropdown, setShowDropdown] = useState(false);\n  const [showThemeDropdown, setShowThemeDropdown] = useState(false);\n  const [selectedMedia, setSelectedMedia] = useState(null);\n  const [downloadingUrl, setDownloadingUrl] = useState(null);\n  const [currentTheme, setCurrentTheme] = useState(() => {\n    const themeData = initialAgentDetails?.theme;\n    if (typeof themeData === 'string' && themes[themeData]) {\n      return themes[themeData];\n    }\n    if (themeData && typeof themeData === 'object' && themeData.colors) {\n      return themeData;\n    }\n    return themes.cosmic;\n  });\n  const textareaRef = useRef(null);\n  const scrollRef = useRef(null);\n  const [attachments, setAttachments] = useState([]);\n  const [isUploading, setIsUploading] = useState(false);\n  const [uploadProgress, setUploadProgress] = useState(0);\n  const [isDragging, setIsDragging] = useState(false);\n  const fileInputRef = useRef(null);\n  const currentAssistantMsgRef = useRef({\n    content: \"\",\n    thoughts: \"\",\n    status: [],\n    suggestions: [],\n  });\n  const [showCustomColorPanel, setShowCustomColorPanel] = useState(false);\n  const [isMounted, setIsMounted] = useState(false);\n  const [liked, setLiked] = useState(agentDetails ? agentDetails?.has_liked : false);\n  const [likeCount, setLikeCount] = useState(agentDetails ? agentDetails?.like_count : 0);\n\n  useEffect(() => {\n    setIsMounted(true);\n  }, []);\n\n  useEffect(() => {\n    const fetchHistory = async () => {\n      if (messages.length > 0) {\n        conversationIdRef.current = effectiveConversationId;\n        return;\n      }\n\n      if (effectiveConversationId && lowerAgentSlug) {\n        const pending = sessionStorage.getItem('pending_first_msg');\n        if (pending) {\n          try {\n            const { convId } = JSON.parse(pending);\n            if (convId === effectiveConversationId) {\n              return;\n            }\n          } catch (e) {}\n        }\n\n        try {\n          let endpoint = `${BASE_URL}/by-slug/${lowerAgentSlug}/${effectiveConversationId}`;\n          const res = await axios.get(endpoint);\n          if (res.data && res.data.history) {\n            const hydratedMessages = res.data.history.map((msg, i) => {\n              let ts = msg.timestamp || res.data.created_at || new Date();\n              if (typeof ts === 'string' && ts.includes('T') && !ts.endsWith('Z') && !ts.includes('+')) {\n                ts += 'Z';\n              }\n              return {\n                ...msg,\n                id: msg.id || `${msg.role}_${Date.now()}_${i}`,\n                timestamp: ts\n              };\n            });\n\n            if (hydratedMessages.length > 0) {\n              setMessages(hydratedMessages);\n            }\n            conversationIdRef.current = effectiveConversationId;\n          }\n        } catch (err) {\n          console.error(\"Failed to fetch conversation history:\", err);\n        }\n      }\n    };\n    fetchHistory();\n  }, [effectiveConversationId, lowerAgentSlug]);\n\n  const handleCustomColorChange = (part, color) => {\n    const updatedTheme = {\n      ...currentTheme,\n      id: 'custom',\n      name: 'Custom Theme',\n      colors: {\n        ...currentTheme.colors,\n        [part]: color\n      }\n    };\n    setCurrentTheme(updatedTheme);\n  };\n\n  const handleThemeSync = async (theme) => {\n    try {\n      await axios.put(`${BASE_URL}/by-slug/${lowerAgentSlug}`, { theme: theme });\n    } catch (err) {\n      console.error(\"Failed to save theme:\", err);\n    }\n    setShowCustomColorPanel(false);\n  };\n\n  const generateCssVariables = (theme) => {\n    const c = theme?.colors || themes.cosmic.colors;\n    return {\n      \"--bg-primary\": c.background,\n      \"--text-primary\": c.foreground,\n      \"--text-secondary\": c.muted,\n      \"--border-color\": c.border,\n      \"--component-bg\": c.componentBg,\n      \"--component-hover\": c.componentHover,\n      \"--header-bg\": c.headerBg,\n      \"--user-bubble\": c.userBubble,\n      \"--user-text\": c.userText,\n      \"--agent-bubble\": c.agentBubble,\n      \"--agent-text\": c.agentText,\n      \"--input-bg\": c.inputBg,\n      \"--accent\": c.accent,\n      \"--accent-text\": c.accentText,\n      \"--font-family\": \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif\",\n    };\n  };\n\n  const handleDownloadFile = async (file_url, filename = \"download\") => {\n    if (!file_url) {\n      toast.error(\"File URL not found\");\n      return;\n    }\n\n    setDownloadingUrl(file_url);\n    try {\n      const response = await axios.post(\"/api/workflow/cloudfront-signed-url\",\n        {\n          url: file_url\n        }\n      );\n\n      const signed_url = response.data.signed_url;\n      const fetchResponse = await fetch(signed_url, { mode: \"cors\" });\n      const blob = await fetchResponse.blob();\n      const url = window.URL.createObjectURL(blob);\n\n      const link = document.createElement(\"a\");\n      link.href = url;\n      link.download = filename;\n      document.body.appendChild(link);\n      link.click();\n      document.body.removeChild(link);\n\n      window.URL.revokeObjectURL(url);\n    } catch (err) {\n      console.error(\"Download failed:\", err);\n      toast.error(`Download failed: ${err.message}`);\n    } finally {\n      setDownloadingUrl(null);\n    }\n  };\n\n  useEffect(() => {\n    if (agentDetails?.theme && themes[agentDetails.theme]) {\n      setCurrentTheme(themes[agentDetails.theme]);\n    }\n  }, [agentDetails]);\n\n  useEffect(() => {\n    if (initialAgentDetails) {\n      setAgentDetails(initialAgentDetails);\n    } else {\n      // fetchAgentDetails();\n    }\n  }, [lowerAgentSlug, initialAgentDetails]);\n\n  useEffect(() => {\n    const checkPendingMessage = async () => {\n      if (effectiveConversationId) {\n        const pending = sessionStorage.getItem('pending_first_msg');\n        if (pending) {\n          try {\n            const { convId, text, attachments: pendingAttachments } = JSON.parse(pending);\n            if (convId === effectiveConversationId) {\n              sessionStorage.removeItem('pending_first_msg');\n              setTimeout(() => {\n                handleSendMessage(null, text, pendingAttachments);\n              }, 100);\n            }\n          } catch (e) {\n            console.error(\"Failed to parse pending message\", e);\n          }\n        }\n      }\n    };\n    checkPendingMessage();\n  }, [effectiveConversationId]);\n\n  useEffect(() => {\n    if (textareaRef.current) {\n      textareaRef.current.style.height = 'auto';\n      textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n    }\n  }, [input]);\n\n  useEffect(() => {\n    if (scrollRef.current) {\n      scrollRef.current.scrollTo({\n        top: scrollRef.current.scrollHeight,\n        behavior: \"smooth\",\n      });\n    }\n  }, [messages]);\n\n  const fetchAgentDetails = async () => {\n    try {\n      const endpoint = `${BASE_URL}/by-slug/${lowerAgentSlug}`;\n      const response = await axios.get(endpoint);\n      setAgentDetails(response.data);\n    } catch (err) {\n      setAgentDetails({\n        name: \"Autonomous Agent\",\n        description: \"MuAPI Powered Intelligence.\",\n      });\n    }\n  };\n\n  const uploadFile = async (file) => {\n    if (!file) return;\n\n    if (file.size > 10 * 1024 * 1024) {\n      setError(\"File size too large (max 10MB)\");\n      return;\n    }\n\n    try {\n      setUploadProgress(0);\n      setIsUploading(true);\n\n      const response = await axios.get(\"/api/app/get_file_upload_url\", {\n        params: { filename: file.name }\n      });\n      const { url, fields } = response.data;\n\n      const formData = new FormData();\n      Object.entries(fields).forEach(([key, value]) => {\n        formData.append(key, value);\n      });\n      formData.append(\"file\", file);\n\n      await axios.post(url, formData, {\n        headers: { \"Content-Type\": \"multipart/form-data\" },\n        onUploadProgress: (progressEvent) => {\n          const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);\n          setUploadProgress(percent);\n        }\n      });\n      const prefix = \"https://cdn.muapi.ai/\";\n      const uploadedUrl = prefix + fields.key;\n      setAttachments(prev => [...prev, uploadedUrl]);\n    } catch (err) {\n      console.error(\"Upload failed\", err);\n      setError(\"Failed to upload image.\");\n    } finally {\n      setIsUploading(false);\n      setUploadProgress(0);\n      if (fileInputRef.current) fileInputRef.current.value = \"\";\n    }\n  };\n\n  const handleFileUpload = (e) => {\n    const file = e.target.files[0];\n    uploadFile(file);\n  };\n\n  const handleDragOver = (e) => {\n    e.preventDefault();\n    setIsDragging(true);\n  };\n\n  const handleDragLeave = (e) => {\n    e.preventDefault();\n    setIsDragging(false);\n  };\n\n  const handleDrop = (e) => {\n    e.preventDefault();\n    setIsDragging(false);\n    \n    const file = e.dataTransfer.files[0];\n    if (file && file.type.startsWith(\"image/\")) {\n      uploadFile(file);\n    } else if (file) {\n      setError(\"Please only upload image files.\");\n    }\n  };\n\n  const removeAttachment = (url) => {\n    setAttachments(prev => prev.filter(item => item !== url));\n  };\n\n  const handleThemeChange = async (theme) => {\n    setCurrentTheme(theme);\n    handleThemeSync(theme);\n  };\n\n  const handleLike = async () => {\n    const newLiked = !liked;\n    const prevLikeCount = likeCount;\n    \n    // Optimistic update\n    setLiked(newLiked);\n    setLikeCount(prev => newLiked ? prev + 1 : prev - 1);\n\n    try {\n      const res = await axios.post(`/api/agents/by-slug/${lowerAgentSlug}/like?is_like=${newLiked}`);\n      setLiked(res.data.has_liked);\n      setLikeCount(res.data.like_count);\n    } catch (err) {\n      console.error(\"Failed to sync like:\", err);\n      // Rollback\n      setLiked(!newLiked);\n      setLikeCount(prevLikeCount);\n    }\n  };\n\n  const handleNewChat = () => {\n    if (lowerAgentSlug) {\n      router.push(`/agents/${lowerAgentSlug}`);\n    }\n  };\n\n  const handleSendMessage = async (e, overrideText = null, overrideAttachments = null) => {\n    if (e) e.preventDefault();\n    \n    const userText = overrideText || input;\n    const currentAttachments = overrideAttachments || (overrideText ? [] : attachments);\n\n    if (!userText.trim()) return;\n    if (isStreaming && !overrideText) return;\n    \n    if (overrideText) setIsStreaming(false);\n\n    const userMessage = {\n      role: \"user\",\n      content: userText,\n      attachments: [...currentAttachments],\n      timestamp: new Date(),\n    };\n    setMessages((prev) => [...prev, userMessage]);\n    \n    if (!overrideText) {\n      setAttachments([]);\n      setInput(\"\");\n    }\n    \n    setIsStreaming(true);\n    setError(null);\n    setDebugLogs([]);\n\n    const assistantMsgId = `asst_${Date.now()}`;\n    currentAssistantMsgRef.current = {\n      id: assistantMsgId,\n      role: \"assistant\",\n      content: \"\",\n      thoughts: \"\",\n      status: [],\n      suggestions: [],\n      timestamp: new Date(),\n    };\n\n    setMessages((prev) => [...prev, { ...currentAssistantMsgRef.current }]);\n\n    try {\n      let currentConvId = conversationIdRef.current || effectiveConversationId;\n      \n      if (!currentConvId && !overrideText) {\n        const newConvId = crypto.randomUUID();\n        conversationIdRef.current = newConvId;\n        \n        sessionStorage.setItem('pending_first_msg', JSON.stringify({\n          convId: newConvId,\n          text: userText,\n          attachments: currentAttachments,\n          timestamp: new Date().toISOString()\n        }));\n\n        if (lowerAgentSlug) {\n           router.replace(`/agents/${lowerAgentSlug}/${newConvId}`);\n        }\n        \n        return;\n      }\n\n      const initialRes = await axios.post(\n        `${BASE_URL}/by-slug/${lowerAgentSlug}/chat`,\n        {\n          message: userText,\n          stream: false,\n          conversation_id: currentConvId,\n          attachments: userMessage.attachments,\n        }\n      );\n\n      const { request_id } = initialRes.data;\n      if (!request_id) throw new Error(\"No Request ID returned from agent\");\n\n      const pollInterval = 1000;\n      let isComplete = false;\n      let errors = 0;\n\n      while (!isComplete && errors < 5) {\n        try {\n          const pollRes = await axios.get(`/api/api/v1/predictions/${request_id}/result`);\n          const data = pollRes.data;\n\n          // data format from backend execute_agent_chat_background:\n          // { \n          //   conversation_id, \n          //   messages: [{role, content...}, {type:'pulse'...}],\n          //   status_text, \n          //   is_complete, \n          //   suggestions,\n          //   error\n          // }\n\n          if (data.conversation_id) conversationIdRef.current = data.conversation_id;\n\n          const incomingMessages = data.messages || [];\n\n          let newContent = \"\";\n          let newThoughts = \"\";\n          let newStatus = [];\n\n          incomingMessages.forEach(msg => {\n            if (msg.role === \"assistant\" && msg.content) {\n              newContent = msg.content;\n            }\n            if (msg.type === \"pulse\" && msg.content) {\n              newStatus.push(msg.content);\n            }\n            if (msg.role === \"assistant\" && msg.thoughts) {\n              newThoughts = msg.thoughts;\n            }\n          });\n\n          currentAssistantMsgRef.current.content = newContent;\n          currentAssistantMsgRef.current.status = newStatus;\n          currentAssistantMsgRef.current.suggestions = data.suggestions || [];\n          setMessages((prev) => {\n            const index = prev.findIndex((m) => m.id === assistantMsgId);\n            if (index !== -1) {\n              const newMessages = [...prev];\n              newMessages[index] = {\n                ...newMessages[index],\n                content: newContent,\n                status: newStatus,\n                suggestions: data.suggestions || [],\n              };\n              return newMessages;\n            }\n            return prev;\n          });\n\n          if (data.status === \"failed\") {\n            throw new Error(data.error || \"Agent execution failed\");\n          }\n\n          if (data.status === \"completed\" || data.status === \"succeeded\" || data.is_complete) {\n            isComplete = true;\n          } else {\n            await new Promise(r => setTimeout(r, pollInterval));\n          }\n\n        } catch (pollErr) {\n          console.error(\"Polling error\", pollErr);\n          errors++;\n          await new Promise(r => setTimeout(r, 2000));\n        }\n      }\n\n      if (errors >= 5) throw new Error(\"Lost connection to agent process\");\n\n    } catch (err) {\n      console.log(\"Agent error:\", err);\n      let errorMessage = err.message || \"Something went wrong. Check browser console\";\n      if (err.response) {\n        const { status, data } = err.response;\n        errorMessage = data?.error || \"Not enough credits\";\n      } else {\n        errorMessage = err.message;\n      }\n      setError(errorMessage);\n      if (!currentAssistantMsgRef.current.content) {\n        setMessages((prev) => prev.filter((m) => m.id !== assistantMsgId));\n      }\n    } finally {\n      setIsStreaming(false);\n    }\n  };\n\n  return (\n    <main\n      className=\"h-dvh flex flex-col selection:bg-blue-500/30 relative\"\n      style={{\n        ...generateCssVariables(currentTheme),\n        background: \"var(--bg-primary)\",\n        color: \"var(--text-primary)\",\n        fontFamily: \"var(--font-family)\",\n      }}\n    >\n      {isMounted && (\n        <style dangerouslySetInnerHTML={{ __html: `\n          @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');\n          \n          main {\n            font-family: var(--font-family) !important;\n          }\n          \n          .prose, .prose p, .prose h1, .prose h2, .prose h3, .prose h4, .prose li {\n            font-family: var(--font-family) !important;\n          }\n        ` }} />\n      )}\n      <header className=\"flex-shrink-0 border-b backdrop-blur-2xl px-6 py-4 flex items-center justify-center z-10 shadow-lg transition-colors duration-300 bg-[var(--header-bg)] border-[var(--border-color)]\">\n        <div className=\"flex items-center justify-between gap-4 w-full lg:max-w-[80%]\">\n          <div className=\"flex items-center gap-4\">\n            <button\n              onClick={() => window.history.back()}\n              className=\"flex items-center justify-center transition-all group\"\n            >\n              <IoChevronBack className=\"w-5 h-5 text-[var(--text-secondary)] group-hover:text-[var(--text-primary)] transition-colors\" />\n            </button>\n            <div className=\"flex items-center gap-3\">\n              {agentDetails?.icon_url ? (\n                <img\n                  src={agentDetails.icon_url}\n                  alt={agentDetails.name}\n                  className=\"w-9 h-9 rounded-lg object-cover border border-[var(--border-color)]\"\n                />\n              ) : (\n                <div className=\"w-9 h-9 rounded-lg flex items-center justify-center\" style={{ background: 'var(--accent)', color: 'var(--accent-text)' }}>\n                  <RiRobot2Fill className=\"w-5 h-5\" />\n                </div>\n              )}\n              <div className=\"relative\">\n                <button\n                  onClick={() => setShowDropdown(!showDropdown)}\n                  className=\"flex items-center gap-2 px-2 py-1 rounded-lg transition-all hover:bg-[var(--component-hover)]\"\n                >\n                  <div className=\"flex flex-col items-start leading-tight\">\n                    <h1 className=\"text-base font-semibold text-[var(--text-primary)] truncate\">\n                      {agentDetails?.name || \"Loading...\"}\n                    </h1>\n                    {agentDetails && !agentDetails.is_owner && (agentDetails.owner_username || agentDetails.owner_email) && (\n                      <span className=\"text-[10px] text-[var(--text-secondary)] font-medium\">\n                        by {agentDetails.owner_username || agentDetails.owner_email?.split('@')[0]}\n                      </span>\n                    )}\n                  </div>\n                  <IoChevronBack\n                    className={`w-4 h-4 text-[var(--text-secondary)] transition-transform ${showDropdown ? \"rotate-90\" : \"-rotate-180\"\n                      }`}\n                  />\n                </button>\n                {showDropdown && (\n                  <div className=\"absolute top-10 left-0 border rounded-lg shadow-xl z-50 animate-in fade-in slide-in-from-top-2 duration-200 min-w-[200px] bg-[var(--header-bg)] border-[var(--border-color)]\">\n                    <button\n                      onClick={() => {\n                        setShowDropdown(false);\n                        router.push(`/agents/${lowerAgentSlug}/profile`);\n                      }}\n                      type=\"button\"\n                      className=\"w-full flex items-center gap-3 px-3 py-2 transition-all hover:bg-[var(--component-hover)] rounded-t-lg\"\n                    >\n                      <RiRobot2Fill size={16} className=\"text-[var(--text-secondary)]\" />\n                      <span className=\"text-sm text-[var(--text-primary)]\">View Profile</span>\n                    </button>\n                    {agentDetails?.is_owner && (\n                      <>\n                        <button\n                          onClick={() => {\n                            setShowDropdown(false);\n                            router.push(`/agents/edit/${agent_id}`);\n                          }}\n                          type=\"button\"\n                          className=\"w-full flex items-center gap-3 px-3 py-2 transition-all hover:bg-[var(--component-hover)] border-t border-[var(--border-color)]\"\n                        >\n                          <MdEdit size={16} className=\"text-[var(--text-secondary)]\" />\n                          <span className=\"text-sm text-[var(--text-primary)]\">Edit agent</span>\n                        </button>\n                        <div className=\"relative group/submenu\">\n                          <button\n                            onMouseEnter={() => setShowThemeDropdown(true)}\n                            onClick={() => setShowThemeDropdown(!showThemeDropdown)}\n                            type=\"button\"\n                            className={`w-full flex items-center gap-3 px-3 py-2 transition-all hover:bg-[var(--component-hover)] border-t border-[var(--border-color)] rounded-b-lg ${showThemeDropdown ? 'bg-[var(--component-hover)]' : ''}`}\n                          >\n                            <IoColorPalette size={16} className=\"text-[var(--text-secondary)]\" />\n                            <span className=\"text-sm text-[var(--text-primary)]\">Themes</span>\n                            <FaAngleRight size={14} className=\"ml-auto text-[var(--text-secondary)]\" />\n                          </button>\n                          {showThemeDropdown && (\n                            <div\n                              className=\"md:absolute relative md:left-full left-0 md:top-0 top-0 md:ml-1 ml-0 md:border border-none md:rounded-xl rounded-none md:shadow-2xl shadow-none overflow-hidden z-[60] animate-in fade-in md:slide-in-from-left-2 slide-in-from-top-2 duration-200 min-w-[200px] bg-[var(--header-bg)] md:border-[var(--border-color)] p-2\"\n                              onMouseEnter={() => setShowThemeDropdown(true)}\n                              onMouseLeave={() => setShowThemeDropdown(false)}\n                            >\n                              <div className=\"text-[10px] font-bold text-[var(--text-secondary)] mb-2 px-2 uppercase tracking-[0.2em]\">Select Theme</div>\n                              <div className=\"space-y-1 max-h-80 overflow-y-auto custom-scrollbar pr-1\">\n                                {Object.values(themes).map((theme) => (\n                                  <button\n                                    key={theme.id}\n                                    onClick={() => {\n                                      handleThemeChange(theme);\n                                      setShowThemeDropdown(false);\n                                      setShowDropdown(false);\n                                    }}\n                                    type=\"button\"\n                                    className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm transition-all group/theme ${currentTheme.id === theme.id\n                                        ? \"bg-[var(--accent)] text-[var(--accent-text)] shadow-md\"\n                                        : \"text-[var(--text-secondary)] hover:bg-[var(--component-hover)]\"\n                                      }`}\n                                  >\n                                    <div\n                                      className=\"w-4 h-4 rounded-full border border-white/20 shadow-inner flex-shrink-0\"\n                                      style={{ background: theme.colors.background }}\n                                    ></div>\n                                    <span className=\"font-medium\">{theme.name}</span>\n                                    {currentTheme.id === theme.id && (\n                                      <MdCheck className=\"ml-auto w-4 h-4\" />\n                                    )}\n                                  </button>\n                                ))}\n                                <button\n                                  onClick={() => {\n                                    setShowCustomColorPanel(true);\n                                    setShowThemeDropdown(false);\n                                    setShowDropdown(false);\n                                  }}\n                                  type=\"button\"\n                                  className=\"w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm text-[var(--text-secondary)] hover:bg-[var(--component-hover)] border-t border-[var(--border-color)] mt-1\"\n                                >\n                                  <MdEdit className=\"w-4 h-4\" />\n                                  <span className=\"font-medium\">Customize Colors</span>\n                                </button>\n                              </div>\n                            </div>\n                          )}\n                        </div>\n                      </>\n                    )}\n                  </div>\n                )}\n              </div>\n            </div>\n          </div>\n          <div className=\"flex items-center gap-2\">\n            <button\n              type=\"button\"\n              onClick={handleLike}\n              className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-lg transition-all border border-[var(--border-color)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--component-hover)]\"\n              title={liked ? \"Unlike agent\" : \"Like agent\"}\n            >\n              {liked ? (\n                <IoHeart className=\"w-4 h-4 text-red-500\" />\n              ) : (\n                <IoHeartOutline className=\"w-4 h-4\" />\n              )}\n              <span className=\"text-xs font-semibold\">{likeCount || 0}</span>\n            </button>\n\n            {effectiveConversationId && (\n              <button\n                type=\"button\"\n                onClick={handleNewChat}\n                className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-lg transition-all border border-[var(--border-color)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--component-hover)]\"\n                title=\"Start new chat\"\n              >\n                <HiOutlinePencilAlt className=\"w-4 h-4\" />\n                <span className=\"text-xs hidden md:flex font-semibold\">New Chat</span>\n              </button>\n            )}\n          </div>\n        </div>\n      </header>\n      <div className=\"flex-1 flex overflow-y-auto\">\n        <div\n          ref={scrollRef}\n          className=\"flex-1 overflow-y-auto px-4 py-8 custom-scrollbar\"\n        >\n          <div className=\"max-w-3xl mx-auto space-y-6\">\n            {messages.length === 0 && agentDetails && (\n              <div className=\"space-y-6\">\n                <div className=\"flex justify-center\">\n                  <div className=\"px-4 py-1.5 rounded-full border text-[10px] uppercase tracking-widest font-bold bg-[var(--component-bg)] border-[var(--border-color)] text-[var(--text-secondary)]\">\n                    Today\n                  </div>\n                </div>\n                <div className=\"flex flex-col items-start animate-in fade-in slide-in-from-bottom-2 duration-300\">\n                  <div className=\"flex items-center gap-2 mb-1 ml-11\">\n                    <div className=\"text-xs font-bold text-[var(--text-primary)]\">\n                      {agentDetails?.name}\n                    </div>\n                  </div>\n\n                  <div className=\"flex gap-3 items-end max-w-[85%] group/msg\">\n                    {agentDetails?.icon_url ? (\n                      <img\n                        src={agentDetails.icon_url}\n                        alt={agentDetails.name}\n                        className=\"w-8 h-8 rounded-full object-cover border flex-shrink-0 border-[var(--border-color)] transition-all duration-500 ease-in-out\"\n                      />\n                    ) : (\n                      <div className=\"w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-500 ease-in-out\" style={{ background: 'var(--accent)', color: 'var(--accent-text)' }}>\n                        <RiRobot2Fill className=\"w-4 h-4\" />\n                      </div>\n                    )}\n                    <div className=\"flex-1 space-y-3\">\n                      <div className=\"flex items-end gap-2\">\n                        <div\n                          className=\"backdrop-blur-sm rounded-2xl rounded-tl-md px-4 py-3 shadow-xl border inline-block\"\n                          style={{\n                            background: 'var(--agent-bubble)',\n                            color: 'var(--agent-text)',\n                            borderColor: 'var(--border-color)'\n                          }}\n                        >\n                          <div className=\"prose prose-sm max-w-none\" style={{ color: 'var(--agent-text)' }}>\n                            <p>\n                              {agentDetails.welcome_message ||\n                                `Hello! I am ${agentDetails.name}. ${agentDetails.description ||\n                                \"How can I assist you today?\"\n                                }`}\n                            </p>\n                          </div>\n                        </div>\n                        <div className=\"opacity-0 group-hover/msg:opacity-100 transition-opacity\">\n                          <CopyButton text={agentDetails?.welcome_message || `Hello! I am ${agentDetails.name}. ${agentDetails.description || \"How can I assist you today?\"}`} />\n                        </div>\n                      </div>\n                      {agentDetails.initial_suggestions?.length > 0 && (\n                        <div className=\"flex flex-wrap gap-2 pt-2\">\n                          {agentDetails.initial_suggestions.map((sug, i) => (\n                            <button\n                              key={i}\n                              type=\"button\"\n                              onClick={() => {\n                                setInput(sug.prompt);\n                                if (textareaRef.current) {\n                                  textareaRef.current.focus();\n                                }\n                              }}\n                              className=\"flex items-center gap-2 text-xs font-medium border px-3 py-2 rounded-lg transition-all group hover:opacity-80\"\n                              style={{\n                                background: 'var(--component-bg)',\n                                borderColor: 'var(--border-color)',\n                                color: 'var(--text-primary)'\n                              }}\n                            >\n                              <HiLightBulb className=\"w-3.5 h-3.5 text-yellow-500 group-hover:scale-110 transition-transform\" />\n                              {sug.label}\n                            </button>\n                          ))}\n                        </div>\n                      )}\n                    </div>\n                  </div>\n                </div>\n              </div>\n            )}\n            {messages.map((msg, idx) => {\n              const prevMsg = messages[idx - 1];\n              const showDateHeader =\n                !prevMsg ||\n                new Date(msg.timestamp).toDateString() !==\n                new Date(prevMsg.timestamp).toDateString();\n\n              return (\n                <div key={idx} className=\"space-y-6\">\n                  {showDateHeader && msg.timestamp && (\n                    <div className=\"flex justify-center\">\n                      <div className=\"px-4 py-1.5 rounded-full border text-[10px] uppercase tracking-widest font-bold bg-[var(--component-bg)] border-[var(--border-color)] text-[var(--text-secondary)]\">\n                        {getDateHeader(msg.timestamp)}\n                      </div>\n                    </div>\n                  )}\n                  <div\n                    className={`flex ${msg.role === \"user\" ? \"justify-end\" : \"justify-start\"\n                      } animate-in fade-in slide-in-from-bottom-2 duration-300`}\n                  >\n                    {msg.role === \"user\" ? (\n                      <div className=\"flex flex-col items-end max-w-[80%] group/msg\">\n                        <div className=\"flex items-center gap-2 mb-1 mr-11\">\n                          {msg.timestamp && (\n                            <div className=\"text-[10px] font-medium text-[var(--text-secondary)]\">\n                              {formatMessageTime(msg.timestamp)}\n                            </div>\n                          )}\n                          <div className=\"text-xs font-bold text-[var(--text-primary)]\">\n                            {userName}\n                          </div>\n                        </div>\n\n                        <div className=\"flex gap-3 items-end w-full justify-end\">\n                          <div className=\"flex-1 space-y-1 text-right\">\n                            <div className=\"flex items-end justify-end gap-2\">\n                              <div className=\"opacity-0 group-hover/msg:opacity-100 transition-opacity\">\n                                <CopyButton text={msg.content} />\n                              </div>\n                              <div\n                                className=\"px-4 py-3 rounded-2xl rounded-tr-md shadow-xl inline-block text-left\"\n                                style={{\n                                  background: 'var(--user-bubble)',\n                                  color: 'var(--user-text)',\n                                }}\n                              >\n                                {msg.attachments?.length > 0 && (\n                                  <div className=\"mb-3 flex flex-wrap justify-end gap-2\">\n                                    {msg.attachments.map((url, i) => (\n                                      <div key={i} className=\"relative group/user-att\">\n                                        <img\n                                          src={url}\n                                          alt=\"Uploaded Attachment\"\n                                          className=\"w-24 h-24 sm:w-32 sm:h-32 rounded-xl object-cover border border-white/20 shadow-md cursor-pointer hover:scale-[1.02] transition-transform\"\n                                          onClick={() => setSelectedMedia({ type: \"image\", url })}\n                                        />\n                                      </div>\n                                    ))}\n                                  </div>\n                                )}\n                                <p className=\"text-sm leading-relaxed font-medium whitespace-pre-wrap\">\n                                  {msg.content}\n                                </p>\n                              </div>\n                            </div>\n                          </div>\n                          {userProfile ? (\n                            <img\n                              src={userProfile}\n                              alt={userName}\n                              className=\"w-8 h-8 rounded-full object-cover border flex-shrink-0 border-[var(--border-color)] transition-all duration-500 ease-in-out\"\n                            />\n                          ) : (\n                            <div className=\"w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-500 ease-in-out\" style={{ background: 'var(--accent)', color: 'var(--accent-text)' }}>\n                              <MdPerson className=\"w-4 h-4\" />\n                            </div>\n                          )}\n                        </div>\n                      </div>\n                    ) : (\n                      <div className=\"flex flex-col items-start max-w-[85%] group/msg\">\n                        <div className=\"flex items-center gap-2 mb-1 ml-11\">\n                          <div className=\"text-xs font-bold text-[var(--text-primary)]\">\n                            {agentDetails?.name}\n                          </div>\n                          {msg.timestamp && (\n                            <div className=\"text-[10px] font-medium text-[var(--text-secondary)]\">\n                              {formatMessageTime(msg.timestamp)}\n                            </div>\n                          )}\n                        </div>\n\n                        <div className=\"flex gap-3 items-end w-full\">\n                          {agentDetails?.icon_url ? (\n                            <img\n                              src={agentDetails.icon_url}\n                              alt={agentDetails.name}\n                              className=\"w-8 h-8 rounded-full object-cover border flex-shrink-0 border-[var(--border-color)] transition-all duration-500 ease-in-out\"\n                            />\n                          ) : (\n                            <div className=\"w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 transition-all duration-500 ease-in-out\" style={{ background: 'var(--accent)', color: 'var(--accent-text)' }}>\n                              <RiRobot2Fill className=\"w-4 h-4\" />\n                            </div>\n                          )}\n\n                          <div className=\"flex-1 space-y-3\">\n                            {msg.status?.length > 0 && (\n                              <div className=\"flex flex-wrap gap-2\">\n                                {msg.status.map((st, i) => (\n                                  <div\n                                    key={i}\n                                    className=\"flex items-center gap-1.5 text-xs px-3 py-1 rounded-full border\"\n                                    style={{\n                                      background: 'var(--component-bg)',\n                                      borderColor: 'var(--border-color)',\n                                      color: 'var(--accent)'\n                                    }}\n                                  >\n                                    <MdTerminal className=\"w-3 h-3\" />\n                                    <span>{st}</span>\n                                  </div>\n                                ))}\n                              </div>\n                            )}\n\n                            {msg.thoughts && (\n                              <div className=\"border rounded-xl p-4 space-y-2 bg-[var(--component-bg)] border-[var(--border-color)]\">\n                                <div className=\"flex items-center gap-2 text-xs font-medium text-[var(--text-secondary)]\">\n                                  <RiRobot2Fill className=\"w-3.5 h-3.5\" />\n                                  <span>Thinking process</span>\n                                </div>\n                                <p className=\"text-xs leading-relaxed italic text-[var(--text-secondary)]\">\n                                  {msg.thoughts}\n                                </p>\n                              </div>\n                            )}\n\n                            {(msg.content || (isStreaming && idx === messages.length - 1)) && (\n                              <div className=\"flex items-end gap-2\">\n                                <div\n                                  className=\"backdrop-blur-sm rounded-2xl rounded-tl-md px-4 py-3 shadow-xl border inline-block\"\n                                  style={{\n                                    background: 'var(--agent-bubble)',\n                                    color: 'var(--agent-text)',\n                                    borderColor: 'var(--border-color)',\n                                  }}\n                                >\n                                  <div className=\"prose prose-sm max-w-none\" style={{ color: 'var(--agent-text)' }}>\n                                    {parseMessageContent(msg.content || \" \").map((part, i) => (\n                                      <div key={i}>\n                                        {part.type === \"text\" && (\n                                          <ReactMarkdown remarkPlugins={[remarkGfm]}>\n                                            {part.content}\n                                          </ReactMarkdown>\n                                        )}\n                                        {part.type === \"image\" && (\n                                          <div className=\"my-3 rounded-xl overflow-hidden border shadow-lg relative w-fit group/media bg-[var(--component-bg)] border-[var(--border-color)]\">\n                                            <img\n                                              src={part.url}\n                                              alt=\"Generated Media\"\n                                              className=\"w-full h-auto max-h-[300px] object-contain transition-transform duration-500 group-hover/media:scale-[1.02]\"\n                                              loading=\"lazy\"\n                                            />\n                                            <div className=\"absolute inset-0 bg-black/40 opacity-0 group-hover/media:opacity-100 transition-opacity duration-300 flex items-center justify-center gap-4\">\n                                              <button\n                                                onClick={() => setSelectedMedia({ type: \"image\", url: part.url })}\n                                                type=\"button\"\n                                                className=\"p-3 rounded-full bg-white/10 hover:bg-white/20 text-white backdrop-blur-md border border-white/20 transition-all hover:scale-110\"\n                                                title=\"View Full Screen\"\n                                              >\n                                                <MdFullscreen className=\"w-6 h-6\" />\n                                              </button>\n                                              <button\n                                                onClick={() => handleDownloadFile(part.url, `image-${Date.now()}.png`)}\n                                                type=\"button\"\n                                                className=\"p-3 rounded-full bg-white/10 hover:bg-white/20 text-white backdrop-blur-md border border-white/20 transition-all hover:scale-110 disabled:opacity-50\"\n                                                title=\"Download\"\n                                                disabled={downloadingUrl === part.url}\n                                              >\n                                                {downloadingUrl === part.url ? (\n                                                  <BiLoaderAlt className=\"w-6 h-6 animate-spin\" />\n                                                ) : (\n                                                  <MdFileDownload className=\"w-6 h-6\" />\n                                                )}\n                                              </button>\n                                            </div>\n                                          </div>\n                                        )}\n                                        {part.type === \"video\" && (\n                                          <div className=\"my-3 rounded-xl overflow-hidden border shadow-lg relative w-fit group/media bg-[var(--component-bg)] border-[var(--border-color)]\">\n                                            <video\n                                              src={part.url}\n                                              className=\"w-full h-auto max-h-[300px] transition-transform duration-500 group-hover/media:scale-[1.02]\"\n                                            />\n                                            <div className=\"absolute top-4 right-4 flex flex-col gap-2 opacity-0 group-hover/media:opacity-100 transition-opacity duration-300 z-10\">\n                                              <button\n                                                onClick={() => setSelectedMedia({ type: \"video\", url: part.url })}\n                                                className=\"p-2 rounded-lg bg-black/60 hover:bg-black/80 text-white backdrop-blur-md border border-white/20 transition-all hover:scale-105\"\n                                                title=\"View Full Screen\"\n                                              >\n                                                <MdFullscreen className=\"w-5 h-5\" />\n                                              </button>\n                                              <button\n                                                onClick={() => handleDownloadFile(part.url, `video-${Date.now()}.mp4`)}\n                                                className=\"p-2 rounded-lg bg-black/60 hover:bg-black/80 text-white backdrop-blur-md border border-white/20 transition-all hover:scale-105 disabled:opacity-50\"\n                                                title=\"Download\"\n                                                disabled={downloadingUrl === part.url}\n                                              >\n                                                {downloadingUrl === part.url ? (\n                                                  <BiLoaderAlt className=\"w-5 h-5 animate-spin\" />\n                                                ) : (\n                                                  <MdFileDownload className=\"w-5 h-5\" />\n                                                )}\n                                              </button>\n                                            </div>\n                                          </div>\n                                        )}\n                                        {part.type === \"audio\" && (\n                                          <div className=\"my-3 flex items-center gap-3 p-3 rounded-xl border backdrop-blur-sm bg-[var(--component-bg)] border-[var(--border-color)]\">\n                                            <div\n                                              className=\"w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0\"\n                                              style={{ background: 'var(--component-hover)', color: 'var(--accent)' }}\n                                            >\n                                              <svg\n                                                xmlns=\"http://www.w3.org/2000/svg\"\n                                                fill=\"none\"\n                                                viewBox=\"0 0 24 24\"\n                                                strokeWidth={1.5}\n                                                stroke=\"currentColor\"\n                                                className=\"w-5 h-5\"\n                                              >\n                                                <path\n                                                  strokeLinecap=\"round\"\n                                                  strokeLinejoin=\"round\"\n                                                  d=\"M19.114 5.636a9 9 0 0 1 0 12.728M16.463 8.288a5.25 5.25 0 0 1 0 7.424M6.75 8.25l4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z\"\n                                                />\n                                              </svg>\n                                            </div>\n                                            <audio src={part.url} controls className=\"w-full h-8\" />\n                                          </div>\n                                        )}\n                                      </div>\n                                    ))}\n                                  </div>\n                                  {isStreaming && idx === messages.length - 1 && (\n                                    <div className=\"flex gap-1 mt-2\">\n                                      <div\n                                        className=\"w-2 h-2 rounded-full animate-bounce\"\n                                        style={{ background: 'var(--accent)', animationDelay: \"0ms\" }}\n                                      ></div>\n                                      <div\n                                        className=\"w-2 h-2 rounded-full animate-bounce\"\n                                        style={{ background: 'var(--accent)', animationDelay: \"150ms\" }}\n                                      ></div>\n                                      <div\n                                        className=\"w-2 h-2 rounded-full animate-bounce\"\n                                        style={{ background: 'var(--accent)', animationDelay: \"300ms\" }}\n                                      ></div>\n                                    </div>\n                                  )}\n                                </div>\n                                <div className=\"opacity-0 group-hover/msg:opacity-100 transition-opacity\">\n                                  <CopyButton text={msg.content} />\n                                </div>\n                              </div>\n                            )}\n\n                            {msg.suggestions?.length > 0 && (\n                              <div className=\"flex flex-wrap gap-2\">\n                                {msg.suggestions.map((sug, i) => (\n                                  <button\n                                    key={i}\n                                    onClick={() => setInput(sug.prompt)}\n                                    className=\"flex items-center gap-2 text-xs font-medium border px-3 py-2 rounded-lg transition-all hover:opacity-80\"\n                                    style={{\n                                      background: 'var(--component-bg)',\n                                      borderColor: 'var(--border-color)',\n                                      color: 'var(--text-primary)'\n                                    }}\n                                  >\n                                    <HiLightBulb className=\"w-3.5 h-3.5 text-yellow-500\" />\n                                    {sug.label}\n                                  </button>\n                                ))}\n                              </div>\n                            )}\n                          </div>\n                        </div>\n                      </div>\n                    )}\n                  </div>\n                </div>\n              );\n            })}\n          </div>\n        </div>\n        {/* {showDebug && (\n          <div className=\"w-80 border-l backdrop-blur-xl overflow-y-auto p-4 custom-scrollbar animate-in slide-in-from-right duration-300 bg-[var(--header-bg)] border-[var(--border-color)]\">\n            <div className=\"flex items-center justify-between mb-4 pb-3 border-b border-[var(--border-color)]\">\n              <h3 className=\"text-xs font-semibold uppercase tracking-wider text-[var(--text-secondary)]\">\n                Debug Logs\n              </h3>\n              <button\n                type=\"button\"\n                onClick={() => setShowDebug(false)}\n                className=\"text-[var(--text-secondary)] hover:text-[var(--text-primary)]\"\n              >\n                <MdClose className=\"w-4 h-4\" />\n              </button>\n            </div>\n            <div className=\"space-y-2\">\n              {debugLogs.length === 0 && (\n                <p className=\"text-xs italic text-[var(--text-secondary)]\">\n                  No logs yet...\n                </p>\n              )}\n              {debugLogs.map((log, i) => (\n                <div\n                  key={i}\n                  className={`p-2 rounded-lg border text-xs font-mono ${log.type === \"error\"\n                      ? \"bg-red-500/10 border-red-500/20 text-red-400\"\n                      : log.type === \"warn\"\n                        ? \"bg-yellow-500/10 border-yellow-500/20 text-yellow-400\"\n                        : \"bg-[var(--component-bg)] border-[var(--border-color)] text-[var(--text-secondary)]\"\n                    }`}\n                >\n                  <span className=\"text-[10px] opacity-50 mr-2\">\n                    [{log.time}]\n                  </span>\n                  {log.msg}\n                </div>\n              ))}\n            </div>\n          </div>\n        )} */}\n      </div>\n      <footer className=\"flex-shrink-0 p-4\">\n        <div className=\"max-w-3xl mx-auto\">\n          {error && (\n            <div className=\"mb-3 p-3 bg-red-500/10 border border-red-500/20 rounded-xl flex items-center justify-between\">\n              <span className=\"text-xs text-red-400 font-medium\">\n                Error: {error}\n              </span>\n              <button\n                onClick={() => setError(null)}\n                className=\"text-red-400 hover:text-red-300\"\n              >\n                <MdClose className=\"w-4 h-4\" />\n              </button>\n            </div>\n          )}\n          <form\n            onSubmit={handleSendMessage}\n            onDragOver={handleDragOver}\n            onDragLeave={handleDragLeave}\n            onDrop={handleDrop}\n            className={`relative border rounded-2xl flex items-end gap-2 p-2 transition-all shadow-inner focus-within:border-[var(--accent)] ${\n              isDragging ? \"ring-2 ring-[var(--accent)] border-[var(--accent)] bg-[var(--accent)]/5\" : \"\"\n            }`}\n            style={{\n              background: 'var(--input-bg)',\n              borderColor: 'var(--border-color)'\n            }}\n          >\n            {isDragging && (\n              <div className=\"absolute inset-0 z-50 flex items-center justify-center bg-[var(--accent)]/10 backdrop-blur-[2px] rounded-2xl pointer-events-none border-2 border-dashed border-[var(--accent)] animate-in fade-in duration-200\">\n                <div className=\"flex items-center justify-center gap-2 text-[var(--accent)]\">\n                  <IoAdd className=\"w-8 h-8 animate-bounce\" />\n                  <span className=\"text-sm font-bold uppercase tracking-wider\">Drop image to upload</span>\n                </div>\n              </div>\n            )}\n            {attachments.length > 0 && (\n              <div className=\"absolute bottom-full left-0 right-0 mb-2 flex flex-wrap gap-2 animate-in slide-in-from-bottom-2\">\n                {attachments.map((url, i) => (\n                  <div key={i} className=\"relative group/att\">\n                    <img\n                      src={url}\n                      className=\"w-16 h-16 rounded-xl object-cover border-2 border-[var(--border-color)] shadow-lg\"\n                      alt=\"Attachment Preview\"\n                    />\n                    <button\n                      onClick={() => removeAttachment(url)}\n                      type=\"button\"\n                      className=\"absolute -top-1.5 -right-1.5 p-1 bg-red-500 text-white rounded-full shadow-lg opacity-0 group-hover/att:opacity-100 transition-opacity\"\n                    >\n                      <MdClose className=\"w-3 h-3\" />\n                    </button>\n                  </div>\n                ))}\n              </div>\n            )}\n            <input\n              type=\"file\"\n              ref={fileInputRef}\n              onChange={handleFileUpload}\n              className=\"hidden\"\n              accept=\"image/*\"\n            />\n            <button\n              onClick={() => fileInputRef.current?.click()}\n              type=\"button\"\n              disabled={isUploading || isStreaming}\n              className=\"flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all bg-[var(--component-hover)] text-[var(--text-secondary)] hover:text-[var(--text-primary)] disabled:opacity-50 shadow-sm relative overflow-hidden\"\n              title=\"Upload Image\"\n            >\n              {isUploading ? (\n                <>\n                  <BiLoaderAlt className=\"w-4 h-4 animate-spin opacity-20\" />\n                  <span className=\"absolute inset-0 flex items-center justify-center text-[10px] font-bold text-[var(--accent)]\">\n                    {uploadProgress}%\n                  </span>\n                </>\n              ) : (\n                <IoAdd className=\"w-5 h-5\" />\n              )}\n            </button>\n            <textarea\n              ref={textareaRef}\n              value={input}\n              onChange={(e) => setInput(e.target.value)}\n              onKeyDown={(e) => {\n                if (e.key === \"Enter\" && !e.shiftKey) {\n                  e.preventDefault();\n                  handleSendMessage();\n                }\n              }}\n              disabled={isStreaming}\n              placeholder={isStreaming ? \"Agent is thinking...\" : \"Type here or drop an image...\"}\n              className=\"flex-1 bg-transparent px-3 py-2.5 text-sm focus:outline-none resize-none max-h-32 placeholder:text-gray-500 custom-scrollbar text-[var(--text-primary)]\"\n              rows={1}\n            />\n            <button\n              type=\"submit\"\n              disabled={!input.trim() || isStreaming}\n              className=\"flex-shrink-0 w-9 h-9 rounded-xl flex items-center justify-center transition-all disabled:opacity-50 disabled:cursor-not-allowed shadow-lg\"\n              style={{\n                background: 'var(--accent)',\n                color: 'var(--accent-text)'\n              }}\n            >\n              {isStreaming ? (\n                <BiLoaderAlt className=\"w-4 h-4 animate-spin\" />\n              ) : (\n                <IoSend className=\"w-4 h-4\" />\n              )}\n            </button>\n          </form>\n        </div>\n      </footer>\n      {selectedMedia && (\n        <div\n          className=\"fixed inset-0 z-[100] flex items-center justify-center bg-black/95 backdrop-blur-sm animate-in fade-in duration-300\"\n          onClick={() => setSelectedMedia(null)}\n        >\n          <button\n            type=\"button\"\n            className=\"absolute top-6 right-6 p-2 rounded-full bg-white/5 hover:bg-white/10 text-white transition-all border border-white/10 z-[110]\"\n            onClick={() => setSelectedMedia(null)}\n          >\n            <MdClose className=\"w-6 h-6\" />\n          </button>\n          <div\n            className=\"max-w-[90vw] max-h-[90vh] relative animate-in zoom-in-95 duration-300\"\n            onClick={(e) => e.stopPropagation()}\n          >\n            {selectedMedia.type === \"image\" ? (\n              <img\n                src={selectedMedia.url}\n                alt=\"Full Screen\"\n                className=\"w-full h-auto max-h-[90vh] object-contain rounded-lg shadow-2xl border border-white/10\"\n              />\n            ) : (\n              <video\n                src={selectedMedia.url}\n                controls\n                autoPlay\n                className=\"w-full h-auto max-h-[90vh] rounded-lg shadow-2xl border border-white/10\"\n              />\n            )}\n            <div className=\"flex justify-center\">\n              <button\n                onClick={() =>\n                  handleDownloadFile(\n                    selectedMedia.url,\n                    `${selectedMedia.type}-${Date.now()}.${selectedMedia.type === \"image\" ? \"png\" : \"mp4\"\n                    }`\n                  )\n                }\n                type=\"button\"\n                className=\"flex items-center gap-2 px-6 py-2.5 rounded-full bg-blue-600 hover:bg-blue-700 text-white font-medium transition-all shadow-lg shadow-blue-500/20 disabled:opacity-50\"\n                disabled={downloadingUrl === selectedMedia.url}\n              >\n                {downloadingUrl === selectedMedia.url ? (\n                  <>\n                    <BiLoaderAlt className=\"w-5 h-5 animate-spin\" />\n                    Preparing...\n                  </>\n                ) : (\n                  <>\n                    <MdFileDownload className=\"w-5 h-5\" />\n                    Download\n                  </>\n                )}\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n      {showCustomColorPanel && (\n        <div className=\"absolute inset-0 z-[100] flex items-center justify-center p-4\">\n          <div \n            className=\"absolute inset-0 bg-black/10 backdrop-blur-sm transition-opacity\"\n            onClick={() => setShowCustomColorPanel(false)}\n          />\n          <div className=\"relative w-full max-w-md bg-[var(--header-bg)] border border-[var(--border-color)] rounded-2xl shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-200\">\n            <div className=\"flex items-center justify-between px-6 py-4 border-b border-[var(--border-color)]\">\n              <div className=\"flex items-center gap-2\">\n                <IoColorPalette className=\"w-5 h-5 text-[var(--accent)]\" />\n                <h3 className=\"font-bold text-[var(--text-primary)]\">Customize Theme</h3>\n              </div>\n              <button \n                onClick={() => setShowCustomColorPanel(false)}\n                className=\"p-1 rounded-lg hover:bg-[var(--component-hover)] text-[var(--text-secondary)] transition-colors\"\n              >\n                <MdClose className=\"w-6 h-6\" />\n              </button>\n            </div>\n            \n            <div className=\"p-6 max-h-[70vh] overflow-y-auto custom-scrollbar space-y-4\">\n              {[\n                { label: 'Background', key: 'background' },\n                { label: 'Text Primary', key: 'foreground' },\n                { label: 'Text Secondary', key: 'muted' },\n                { label: 'Border Color', key: 'border' },\n                { label: 'Panel Background', key: 'componentBg' },\n                { label: 'Header Background', key: 'headerBg' },\n                { label: 'User Bubble', key: 'userBubble' },\n                { label: 'User Text', key: 'userText' },\n                { label: 'Agent Bubble', key: 'agentBubble' },\n                { label: 'Agent Text', key: 'agentText' },\n                { label: 'Input Background', key: 'inputBg' },\n                { label: 'Accent Color', key: 'accent' },\n                { label: 'Accent Text', key: 'accentText' },\n              ].map((item) => (\n                <div key={item.key} className=\"flex items-center justify-between p-3 rounded-xl border border-[var(--border-color)] bg-[var(--component-bg)]/50\">\n                  <span className=\"text-sm font-medium text-[var(--text-primary)]\">{item.label}</span>\n                  <div className=\"flex items-center gap-3\">\n                    <span className=\"text-[10px] font-mono text-[var(--text-secondary)] uppercase\">\n                      {currentTheme.colors[item.key]}\n                    </span>\n                    <input \n                      type=\"color\" \n                      value={currentTheme.colors[item.key]?.startsWith('#') ? currentTheme.colors[item.key] : '#000000'} \n                      onChange={(e) => handleCustomColorChange(item.key, e.target.value)}\n                      className=\"w-10 h-10 rounded-lg cursor-pointer border-none bg-transparent\"\n                    />\n                  </div>\n                </div>\n              ))}\n            </div>\n\n            <div className=\"p-4 bg-[var(--component-bg)]/50 border-t border-[var(--border-color)]\">\n              <button \n                onClick={() => handleThemeSync(currentTheme)}\n                className=\"w-full py-3 rounded-xl font-bold transition-all shadow-lg active:scale-95\"\n                style={{ background: 'var(--accent)', color: 'var(--accent-text)' }}\n              >\n                Apply Changes\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n    </main>\n  );\n};\n\nexport default ChatPage;\n"
  },
  {
    "path": "packages/agents/src/CreatePage.jsx",
    "content": "\"use client\";\n\nimport CreateAgent from \"./components/CreateAgent\";\nimport { Toaster } from \"react-hot-toast\";\n\nconst CreateAgentPage = ({ useUser, usedIn = \"muapiapp\" }) => {\n  return (\n    <div className=\"h-screen w-full flex flex-col bg-gray-100 transition-all duration-300 ease-in-out\">\n      <main className=\"flex flex-col items-center gap-2 w-full h-full overflow-y-auto pt-8\">\n        <CreateAgent useUser={useUser} usedIn={usedIn} />\n      </main>\n      <Toaster position=\"top-center\" reverseOrder={false} />\n    </div>\n  );\n};\n\nexport default CreateAgentPage;\n"
  },
  {
    "path": "packages/agents/src/EditPage.jsx",
    "content": "\"use client\";\n\nimport EditAgent from \"./components/EditAgent\";\nimport { Toaster } from \"react-hot-toast\";\n\nconst EditAgentPage = ({ useUser, usedIn = \"muapiapp\" }) => {\n  return (\n    <div className=\"h-dvh w-full flex flex-col bg-blue-50/50 transition-all duration-300 ease-in-out\">\n      <Toaster position=\"top-center\" reverseOrder={false} />\n      <main className=\"flex flex-col items-center gap-2 w-full h-full overflow-y-auto pt-8\">\n        <EditAgent useUser={useUser} usedIn={usedIn} />\n      </main>\n    </div>\n  );\n};\n\nexport default EditAgentPage;\n"
  },
  {
    "path": "packages/agents/src/components/AgentThemeProvider.jsx",
    "content": "'use client'\n\nimport React from 'react'\nimport { ThemeProvider } from 'next-themes'\n\nexport const AgentThemeProvider = ({ children }) => {\n  return (\n    <ThemeProvider \n      attribute=\"class\" \n      defaultTheme=\"system\" \n      enableSystem\n      disableTransitionOnChange\n    >\n      {children}\n    </ThemeProvider>\n  )\n}\n\nexport default AgentThemeProvider\n"
  },
  {
    "path": "packages/agents/src/components/CreateAgent.jsx",
    "content": "import React, { useEffect, useState } from \"react\";\nimport Link from \"next/link\";\nimport axios from \"axios\";\nimport { BiLoaderAlt } from \"react-icons/bi\";\nimport { RiRobot2Fill } from \"react-icons/ri\";\nimport { IoArrowBackOutline } from \"react-icons/io5\";\nimport { useRouter } from \"next/navigation\";\n\nconst BASE_URL = \"/api/agents\";\n\nconst CreateAgent = ({ useUser, usedIn }) => {\n  const userContext = useUser ? useUser() : {};\n  let user = null;\n\n  if (usedIn === \"vadoo\") {\n    const { serverDetails } = userContext;\n    user = serverDetails?.user_details\n      ? { email: serverDetails.user_details.email, name: serverDetails.user_details.name }\n      : null;\n  } else {\n    // muapiapp\n    user = userContext.user || null;\n  }\n  const router = useRouter();\n  const [prompt, setPrompt] = useState(\"\");\n  const [loading, setLoading] = useState(false);\n  const [error, setError] = useState(null);\n\n  const handleArchitectAgent = async (e) => {\n    e.preventDefault();\n    if (!prompt.trim()) return;\n\n    try {\n      setLoading(true);\n      setError(null);\n\n      const suggestResponse = await axios.post(`${BASE_URL}/suggest`, {\n        prompt,\n      });\n      const suggestion = suggestResponse.data;\n      const createPayload = {\n        name: suggestion.name || \"Unnamed Agent\",\n        description: suggestion.description || \"\",\n        system_prompt: suggestion.system_prompt || \"\",\n        skill_ids: suggestion.recommended_skill_ids || [],\n        welcome_message: suggestion.welcome_message || \"\",\n        initial_suggestions: suggestion.initial_suggestions || [],\n        is_published: false,\n        is_template: false,\n      };\n\n      const createResponse = await axios.post(`${BASE_URL}`, createPayload);\n      if (createResponse.status === 200 || createResponse.status === 201) {\n        const createdAgent = createResponse.data;\n        router.push(`/agents/edit/${createdAgent.agent_id}`);\n      }\n    } catch (err) {\n      console.error(\"Agent creation failed:\", err);\n      setError(\n        err.response?.data?.message ||\n        err.response?.data?.detail ||\n        err.message ||\n        \"Failed to architect agent. Please try again.\",\n      );\n    } finally {\n      setLoading(false);\n    }\n  };\n\n  return (\n    <div className=\"flex-1 flex flex-col gap-8 items-center w-full max-w-[95%] sm:max-w-[90%] lg:max-w-[80%] relative pb-12\">\n      <div className=\"flex items-start gap-2 w-full\">\n        <Link\n          href=\"/agents\"\n          className=\"p-2 hover:bg-gray-100 dark:hover:bg-secondary-bg rounded-full transition-colors group\"\n        >\n          <IoArrowBackOutline className=\"w-4 h-4 text-gray-800 dark:text-primary-text group-hover:scale-110 transition-transform\" />\n        </Link>\n        <div className=\"flex flex-col gap-2 w-full\">\n          <h1 className=\"text-2xl font-bold text-black dark:text-white\">\n            Prompt Any Assistant\n          </h1>\n          <p className=\"text-gray-500 dark:text-secondary-text text-sm font-medium\">\n            Use this to prompt up an assistant to help you with any topic!\n          </p>\n        </div>\n      </div>\n      <form onSubmit={handleArchitectAgent} className=\"space-y-8 w-full\">\n        <div className=\"space-y-4\">\n          <label className=\"text-lg font-semibold text-black dark:text-white block\">\n            What should your assistant be able to do and be knowledgeable in?\n          </label>\n          <div className=\"relative\">\n            <textarea\n              value={prompt}\n              autoFocus\n              onChange={(e) => setPrompt(e.target.value)}\n              placeholder=\"Ex: A helpful travel agent that finds the best destinations in Italy...\"\n              className=\"w-full bg-white dark:bg-secondary-bg border border-gray-200 dark:border-divider rounded-xl p-4 text-gray-900 dark:text-primary-text text-sm focus:outline-none focus:ring-2 focus:ring-black/10 dark:focus:ring-primary/10 focus:border-gray-400 dark:focus:border-primary transition-all resize-none min-h-[140px] shadow-sm\"\n              disabled={loading}\n            />\n          </div>\n        </div>\n        \n        <div className=\"flex items-center gap-6\">\n        </div>\n\n        <div className=\"flex flex-col gap-4\">\n          <button\n            type=\"submit\"\n            disabled={loading || !prompt.trim()}\n            className=\"w-full py-3 bg-blue-500 dark:bg-primary hover:bg-blue-600 dark:hover:bg-primary/90 disabled:bg-gray-200 dark:disabled:bg-divider disabled:text-gray-400 dark:disabled:text-secondary-text disabled:cursor-not-allowed text-white text-base font-semibold rounded-xl transition-all flex items-center justify-center gap-3 active:scale-[0.98]\"\n          >\n            {loading ? (\n              <>\n                <BiLoaderAlt className=\"w-6 h-6 animate-spin\" />\n                <span>Creating agent...</span>\n              </>\n            ) : (\n              \"Create agent\"\n            )}\n          </button>\n          {loading && (\n            <p className=\"text-center text-gray-400 dark:text-secondary-text text-sm animate-pulse\">\n              Analyzing prompt and building capabilities...\n            </p>\n          )}\n          {error && (\n            <div className=\"p-4 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/30 rounded-xl text-red-600 dark:text-red-400 text-sm flex items-center gap-3 animate-in fade-in duration-300\">\n              <svg\n                className=\"w-5 h-5 flex-shrink-0\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                viewBox=\"0 0 24 24\"\n              >\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth=\"2\"\n                  d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n                />\n              </svg>\n              {error}\n            </div>\n          )}\n        </div>\n      </form>\n    </div>\n  )\n};\n\nexport default CreateAgent;\n"
  },
  {
    "path": "packages/agents/src/components/EditAgent.jsx",
    "content": "import React, { useState, useEffect, useRef } from \"react\";\nimport { useParams, useRouter } from \"next/navigation\";\nimport Link from \"next/link\";\nimport axios from \"axios\";\nimport { IoChevronBack, IoPencilOutline, IoShareOutline, IoTrashOutline, IoCloseOutline, IoImageOutline, IoSparklesOutline, IoChatbubblesOutline } from \"react-icons/io5\";\nimport { BiLoaderAlt } from \"react-icons/bi\";\nimport { RiRobot2Fill } from \"react-icons/ri\";\nimport toast from \"react-hot-toast\";\nimport { FaRegTrashCan } from \"react-icons/fa6\";\nimport { MdClose } from \"react-icons/md\";\nimport { themes } from \"./themes\";\n\nconst BASE_URL = \"/api/agents\";\n\nconst EditAgent = ({ useUser, usedIn }) => {\n  // Project-specific user detail extraction\n  const userContext = useUser ? useUser() : {};\n  let user = null;\n\n  if (usedIn === \"vadoo\") {\n    const { serverDetails } = userContext;\n    user = serverDetails?.user_details\n      ? { email: serverDetails.user_details.email, name: serverDetails.user_details.name }\n      : null;\n  } else {\n    // muapiapp\n    user = userContext.user || null;\n  }\n  const { id } = useParams();\n  const router = useRouter();\n  const fileInputRef = useRef(null);\n  \n  const [formData, setFormData] = useState({\n    name: \"\",\n    description: \"\",\n    system_prompt: \"\",\n    icon_url: \"\",\n    skill_ids: [],\n    theme: \"cosmic\",\n    is_published: false,\n    is_template: false,\n  });\n  \n  const [availableSkills, setAvailableSkills] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [saving, setSaving] = useState(false);\n  const [uploading, setUploading] = useState(false);\n  const [uploadProgress, setUploadProgress] = useState(0);\n  const [searchTerm, setSearchTerm] = useState(\"\");\n  const [error, setError] = useState(null);\n  const [success, setSuccess] = useState(false);\n  const [initialSkills, setInitialSkills] = useState([]);\n  const [realignedPrompt, setRealignedPrompt] = useState(\"\");\n  const [isRealigning, setIsRealigning] = useState(false);\n  const [showRealignModal, setShowRealignModal] = useState(false);\n  const [generatingIcon, setGeneratingIcon] = useState(false);\n  const [showIconPromptModal, setShowIconPromptModal] = useState(false);\n  const [showIconSelectionModal, setShowIconSelectionModal] = useState(false);\n  const [iconPrompt, setIconPrompt] = useState(\"\");\n\n  useEffect(() => {\n    if (id) {\n      fetchData();\n    }\n  }, [id]);\n\n  const fetchData = async () => {\n    try {\n      setLoading(true);\n      setError(null);\n      \n      const [agentRes, skillsRes] = await Promise.all([\n        axios.get(`${BASE_URL}/by-slug/${id}`),\n        axios.get(`${BASE_URL}/skills`)\n      ]);\n      \n      const agent = agentRes.data;\n      if (!agent.is_owner) {\n        setError(\"You are not authorized to edit this agent.\");\n        setLoading(false);\n        return;\n      }\n      setFormData({\n        name: agent.name,\n        description: agent.description || \"\",\n        system_prompt: agent.system_prompt,\n        icon_url: agent.icon_url || \"\",\n        skill_ids: agent.skills.map(s => s.id),\n        theme: agent.theme || \"cosmic\",\n        is_published: agent.is_published || false,\n        is_template: agent.is_template || false,\n      });\n      setInitialSkills(agent.skills.map(s => s.id));\n      setAvailableSkills(skillsRes.data);\n    } catch (err) {\n      console.error(\"Error fetching data:\", err);\n      setError(\n        err.response?.data?.message || \n        err.response?.data?.detail || \n        \"Failed to load agent details.\"\n      );\n    } finally {\n      setLoading(false);\n    }\n  };\n  \n  const handleInputChange = (e) => {\n    const { name, value } = e.target;\n    setFormData(prev => ({ ...prev, [name]: value }));\n  };\n\n  const handleSkillToggle = (skillId) => {\n    setFormData(prev => {\n      const isSelected = prev.skill_ids.includes(skillId);\n      if (isSelected) {\n        return { ...prev, skill_ids: prev.skill_ids.filter(id => id !== skillId) };\n      } else {\n        return { ...prev, skill_ids: [...prev.skill_ids, skillId] };\n      }\n    });\n  };\n\n  const handleDelete = async () => {\n    if (!window.confirm(\"Are you sure you want to delete this agent? This action cannot be undone.\")) {\n      return;\n    }\n\n    try {\n      setSaving(true);\n      await axios.delete(`${BASE_URL}/by-slug/${id}`);\n      toast.success(\"Agent deleted successfully\");\n      router.push(\"/agents\");\n    } catch (err) {\n      console.error(\"Delete error:\", err);\n      toast.error(\"Failed to delete agent\");\n      setError(err.response?.data?.detail || \"Delete failed\");\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  const handleShare = () => {\n    const url = `${window.location.origin}/agents/${id}`;\n    navigator.clipboard.writeText(url);\n    toast.success(\"Chat link copied to clipboard!\");\n  };\n\n  const handleFileUpload = async (e) => {\n    const file = e.target.files?.[0];\n    if (!file) return;\n\n    if (!file.type.startsWith(\"image/\")) {\n      toast.error(\"Please upload an image file\");\n      return;\n    }\n\n    try {\n      setUploading(true);\n      setUploadProgress(0);\n      const { data: uploadParams } = await axios.get(\"/api/app/get_file_upload_url\", {\n        params: { filename: file.name }\n      });\n\n      const { url, fields } = uploadParams;\n      const uploadData = new FormData();\n      Object.entries(fields).forEach(([key, value]) => {\n        uploadData.append(key, value);\n      });\n      uploadData.append(\"file\", file);\n\n      await axios.post(url, uploadData, {\n        headers: { \"Content-Type\": \"multipart/form-data\" },\n        onUploadProgress: (progressEvent) => {\n          const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);\n          setUploadProgress(percent);\n        }\n      });\n      const prefix = usedIn === \"vadoo\" ? \"https://d3adwkbyhxyrtq.cloudfront.net/\": \"https://cdn.muapi.ai/\";\n      const uploadedUrl = `${prefix}${fields.key}`;\n      setFormData(prev => ({ ...prev, icon_url: uploadedUrl }));\n      toast.success(\"Profile image updated\");\n    } catch (err) {\n      console.error(\"Upload failed:\", err);\n      toast.error(\"Failed to upload image\");\n    } finally {\n      setUploading(false);\n      setUploadProgress(0);\n    }\n  };\n\n  const handleGenerateIcon = async (customPrompt) => {\n    if (!formData.name && !customPrompt) {\n      toast.error(\"Please enter an agent name first\");\n      return;\n    }\n\n    try {\n      setGeneratingIcon(true);\n      const prompt = customPrompt || `A professional, clean profile icon for an AI agent named \"${formData.name}\". Description: ${formData.description || \"An AI assistant\"}. Minimalist, high-quality, circular composition.`;\n      \n      const response = await axios.post(\"/api/api/v1/flux-schnell-image\", {\n        prompt,\n        width: 1024,\n        height: 1024,\n        num_images: 1,\n        sync: true\n      });\n\n      if (response.data && response.data.outputs && response.data.outputs.length > 0) {\n        const generatedUrl = response.data.outputs[0];\n        setFormData(prev => ({ ...prev, icon_url: generatedUrl }));\n        setShowIconPromptModal(false);\n        toast.success(\"AI icon generated!\");\n      } else {\n        throw new Error(\"No image generated\");\n      }\n    } catch (err) {\n      console.error(\"Icon generation failed:\", err);\n      toast.error(err.response?.data?.detail || \"Failed to generate AI icon\");\n    } finally {\n      setGeneratingIcon(false);\n    }\n  };\n\n  const handleRealign = async () => {\n    try {\n      setIsRealigning(true);\n      const res = await axios.post(`${BASE_URL}/by-slug/${id}/preview-realign`, {\n        current_prompt: formData.system_prompt,\n        new_skill_ids: formData.skill_ids\n      });\n      setRealignedPrompt(res.data.proposed_prompt);\n      setShowRealignModal(true);\n      toast.success(\"Prompt realigned! Please review.\");\n    } catch (err) {\n      console.error(\"Realign failed:\", err);\n      toast.error(\"Failed to realign prompt\");\n    } finally {\n      setIsRealigning(false);\n    }\n  };\n\n  const applyRealignedPrompt = () => {\n    setFormData(prev => ({ ...prev, system_prompt: realignedPrompt }));\n    setShowRealignModal(false);\n    toast.success(\"New instructions applied!\");\n  };\n\n  const handleSubmit = async (e) => {\n    e.preventDefault();\n    try {\n      setSaving(true);\n      setError(null);\n      setSuccess(false);\n      \n      await axios.put(`${BASE_URL}/by-slug/${id}`, formData);\n      \n      setSuccess(true);\n      toast.success(\"Agent profile updated successfully!\");\n      setTimeout(() => {\n        router.push(\"/agents\");\n      }, 1500);\n    } catch (err) {\n      console.error(\"Error updating agent:\", err);\n      setError(\n        err.response?.data?.message || \n        err.response?.data?.detail || \n        \"Failed to update agent.\"\n      );\n      toast.error(\"Failed to save changes\");\n    } finally {\n      setSaving(false);\n    }\n  };\n\n  if (loading) {\n    return (\n      <main className=\"flex-1 flex items-center justify-center\">\n        <div className=\"flex flex-col items-center gap-2\">\n          <BiLoaderAlt className=\"w-12 h-12 text-blue-600 animate-spin\" />\n          <p className=\"text-gray-500 font-medium animate-pulse\">Loading Identity Data...</p>\n        </div>\n      </main>\n    );\n  }\n  \n  if (error) {\n    return (\n      <main className=\"flex-1 flex flex-col items-center justify-center h-full gap-4 text-center p-8\">\n        <div className=\"w-16 h-16 bg-red-100 dark:bg-red-900/30 rounded-full flex items-center justify-center mb-2\">\n          <IoCloseOutline className=\"w-10 h-10 text-red-500 dark:text-red-400\" />\n        </div>\n        <h2 className=\"text-2xl font-bold text-gray-900 dark:text-white\">Access Denied</h2>\n        <p className=\"text-gray-600 dark:text-secondary-text max-w-md font-medium\">\n          {error}\n        </p>\n        <Link \n          href=\"/agents\"\n          className=\"mt-4 px-8 py-3 bg-gray-900 dark:bg-primary text-white font-bold rounded-xl hover:bg-gray-800 dark:hover:bg-primary/90 transition-all shadow-lg active:scale-95\"\n        >\n          Return to My Agents\n        </Link>\n      </main>\n    );\n  }\n\n  return (\n    <div className=\"flex-1 flex flex-col gap-8 items-center w-full max-w-[95%] sm:max-w-[90%] lg:max-w-[80%] relative\">\n      <div className=\"flex items-center justify-between pb-2 border-b border-gray-50 dark:border-divider w-full\">\n        <Link \n          href=\"/agents\"\n          className=\"flex items-center gap-2 text-gray-500 hover:text-gray-900 dark:text-secondary-text dark:hover:text-primary-text transition-colors text-sm font-medium\"\n        >\n          <IoChevronBack className=\"w-4 h-4\" />\n          Back\n        </Link>\n        <div className=\"flex items-center gap-3\">\n          <Link \n            href={`${window.location.origin}/agents/${id}`}\n            className=\"flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-xl text-sm font-bold text-white transition-all active:scale-95 shadow-sm\"\n          >\n            <IoChatbubblesOutline className=\"w-4 h-4\" />\n            Chat\n          </Link>\n          <button \n            type=\"button\"\n            onClick={handleShare}\n            className=\"flex items-center gap-2 px-4 py-2 border border-gray-100 dark:border-divider rounded-xl text-sm font-bold text-gray-600 dark:text-primary-text hover:bg-gray-50 dark:hover:bg-secondary-bg transition-all active:scale-95\"\n          >\n            <IoShareOutline className=\"w-4 h-4\" />\n          </button>\n          <button \n            type=\"button\"\n            onClick={handleDelete}\n            disabled={saving}\n            className=\"flex items-center gap-2 px-4 py-2 border border-red-50 dark:border-red-900/30 rounded-xl text-sm font-bold text-red-500 hover:bg-red-50 dark:hover:bg-red-900/10 transition-all active:scale-95 disabled:opacity-50\"\n          >\n            <IoTrashOutline className=\"w-4 h-4\" />\n          </button>\n          <Link \n            href=\"/docs/agents\"\n            target=\"_blank\"\n            className=\"flex items-center gap-2 px-3 py-1.5 bg-gray-50 dark:bg-secondary-bg border border-gray-100 dark:border-divider rounded-lg text-xs font-bold text-blue-600 dark:text-primary hover:bg-blue-50 dark:hover:bg-primary-bg transition-all active:scale-95 shadow-sm\"\n          >\n            Docs\n          </Link>\n        </div>\n      </div>\n      <div className=\"flex flex-col items-center gap-2 w-full\">\n        <form id=\"edit-agent-form\" onSubmit={handleSubmit} className=\"flex flex-col gap-12 w-full\">\n          <div className=\"flex flex-col md:flex-row md:items-center gap-8 w-full\">\n            <div className=\"flex items-center gap-8 w-full\">\n              <div className=\"relative\">\n                <div \n                  onClick={() => setShowIconSelectionModal(true)}\n                  className=\"w-28 h-28 rounded-full bg-gray-100 dark:bg-secondary-bg overflow-hidden ring-4 ring-white dark:ring-primary-bg shadow-sm border border-gray-100 dark:border-divider cursor-pointer group transition-all hover:ring-blue-500/30\"\n                >\n                  {formData.icon_url ? (\n                    <img src={formData.icon_url} alt=\"Profile\" className=\"w-full h-full object-cover transition-transform group-hover:scale-110\" />\n                  ) : (\n                    <div className=\"w-full h-full flex items-center justify-center bg-gray-50 dark:bg-primary-bg transition-colors group-hover:bg-gray-100 dark:group-hover:bg-secondary-bg\">\n                      <RiRobot2Fill className=\"w-12 h-12 text-gray-300 dark:text-divider group-hover:text-blue-500 transition-colors\" />\n                    </div>\n                  )}\n                  <div className=\"absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity rounded-full\">\n                    <IoPencilOutline className=\"w-6 h-6 text-white\" />\n                  </div>\n                  {uploading && (\n                    <div className=\"absolute inset-0 bg-white/95 dark:bg-primary-bg/95 flex items-center justify-center rounded-full z-10 backdrop-blur-[1px]\">\n                      <div className=\"relative w-16 h-16\">\n                        <svg className=\"w-full h-full -rotate-90\" viewBox=\"0 0 36 36\">\n                          <circle\n                            cx=\"18\"\n                            cy=\"18\"\n                            r=\"16\"\n                            fill=\"none\"\n                            className=\"stroke-gray-100 dark:stroke-divider\"\n                            strokeWidth=\"3.5\"\n                          />\n                          <circle\n                            cx=\"18\"\n                            cy=\"18\"\n                            r=\"16\"\n                            fill=\"none\"\n                            className=\"stroke-black dark:stroke-primary transition-all duration-500 ease-out\"\n                            strokeWidth=\"3.5\"\n                            strokeDasharray=\"100.53\"\n                            strokeDashoffset={100.53 * (1 - uploadProgress / 100)}\n                            strokeLinecap=\"round\"\n                          />\n                        </svg>\n                        <div className=\"absolute inset-0 flex items-center justify-center\">\n                          <span className=\"text-xs font-bold text-gray-900 dark:text-white\">\n                            {uploadProgress}%\n                          </span>\n                        </div>\n                      </div>\n                    </div>\n                  )}\n                </div>\n                <input type=\"file\" ref={fileInputRef} onChange={handleFileUpload} className=\"hidden\" accept=\"image/*\" />\n              </div>\n              <div className=\"flex flex-col gap-2 w-full\">\n                <div className=\"flex items-center gap-2 group/title w-full\">\n                  <input\n                    type=\"text\"\n                    name=\"name\"\n                    value={formData.name}\n                    onChange={handleInputChange}\n                    className=\"text-3xl font-bold text-gray-900 dark:text-white leading-tight tracking-tight truncate bg-transparent border-none p-0 focus:ring-0 w-full\"\n                    placeholder=\"Unnamed Agent\"\n                    required\n                  />\n                  <IoPencilOutline className=\"w-5 h-5 text-gray-300 dark:text-divider opacity-0 group-hover/title:opacity-100 transition-opacity\" />\n                </div>\n                <div className=\"flex items-center gap-3 mt-1 mr-auto\">\n                  {/* Toggles moved to better location */}\n                </div>\n              </div>\n            </div>\n            <div className=\"flex flex-col gap-4\">\n              <button\n                type=\"submit\"\n                form=\"edit-agent-form\"\n                disabled={saving}\n                className=\"px-6 py-3 whitespace-nowrap bg-black dark:bg-primary hover:bg-gray-800 dark:hover:bg-primary/90 disabled:opacity-50 text-white font-bold rounded-xl transition-all shadow-lg text-sm active:scale-95\"\n              >\n                {saving ? \"Saving...\" : \"Save Changes\"}\n              </button>\n              <div className=\"flex items-center gap-1.5 p-1 bg-gray-100 dark:bg-secondary-bg rounded-2xl border border-gray-200 dark:border-divider w-fit\">\n                <div \n                  onClick={() => setFormData(prev => ({ ...prev, is_published: !prev.is_published }))}\n                  className={`flex items-center gap-2 px-4 py-2.5 rounded-xl cursor-pointer transition-all duration-300 ${\n                    formData.is_published \n                      ? \"bg-white dark:bg-primary-bg shadow-sm text-blue-600 dark:text-primary\" \n                      : \"text-gray-400 hover:text-gray-600 dark:text-secondary-text dark:hover:text-primary-text\"\n                  }`}\n                >\n                  <div className={`w-2 h-2 rounded-full transition-all duration-500 ${formData.is_published ? \"bg-blue-500 shadow-[0_0_8px_rgba(59,130,246,0.5)]\" : \"bg-gray-300 dark:bg-gray-600\"}`} />\n                  <span className=\"text-xs font-bold tracking-wider\">Publish</span>\n                </div>\n              </div>\n            </div>\n          </div>\n          <div className=\"flex flex-col gap-12\">\n            <div className=\"flex flex-col gap-6\">\n              <div className=\"flex flex-col gap-2\">\n                <h2 className=\"text-xl font-bold text-gray-900 dark:text-white\">Behavior & Identity</h2>\n                <p className=\"text-sm text-gray-500 dark:text-secondary-text font-medium\">\n                  Shape how your agent thinks, responds, and describes itself\n                </p>\n              </div>\n              <div className=\"flex flex-col gap-6\">\n                <div className=\"flex flex-col gap-2\">\n                  <div className=\"flex items-center justify-between border-l-4 border-black dark:border-primary pl-3 ml-1 mb-1\">\n                    <label className=\"text-base font-bold text-gray-900 dark:text-white\">Instructions</label>\n                    <button\n                      type=\"button\"\n                      onClick={handleRealign}\n                      disabled={isRealigning || JSON.stringify(formData.skill_ids.sort()) === JSON.stringify(initialSkills.sort())}\n                      className=\"flex items-center gap-2 px-3 py-1.5 bg-violet-600 hover:bg-violet-700 disabled:bg-gray-100 disabled:text-gray-400 text-white text-xs font-bold rounded-lg transition-all active:scale-95 shadow-sm\"\n                      title={JSON.stringify(formData.skill_ids.sort()) === JSON.stringify(initialSkills.sort()) ? \"No changes to skills\" : \"Sync instructions with current skills\"}\n                    >\n                      {isRealigning ? <BiLoaderAlt className=\"animate-spin\" /> : \"✨ Realign with Skills\"}\n                    </button>\n                  </div>\n                  <div className=\"relative group\">\n                    <textarea\n                      name=\"system_prompt\"\n                      value={formData.system_prompt}\n                      onChange={handleInputChange}\n                      className=\"w-full bg-white dark:bg-secondary-bg border border-gray-100 dark:border-divider rounded-2xl px-6 py-6 text-gray-800 dark:text-primary-text text-sm focus:ring-4 focus:ring-black/5 dark:focus:ring-primary/5 focus:border-black dark:focus:border-primary transition-all outline-none min-h-[200px] leading-relaxed shadow-sm font-medium\"\n                      placeholder=\"Define how your agent thinks and communicates...\"\n                      required\n                    />\n                    <p className=\"text-xs text-gray-400 dark:text-secondary-text font-medium ml-1\">\n                      Define how your agent thinks and communicates. Start with &quot;You are...&quot; and include specific examples.\n                    </p>\n                  </div>\n                </div>\n                <div className=\"flex flex-col gap-2\">\n                  <label className=\"text-base font-bold text-gray-900 dark:text-white border-l-4 border-black dark:border-primary pl-3 ml-1\">Description</label>\n                  <textarea\n                    name=\"description\"\n                    value={formData.description}\n                    onChange={handleInputChange}\n                    className=\"w-full bg-white dark:bg-secondary-bg border border-gray-100 dark:border-divider rounded-2xl px-6 py-4 text-gray-800 dark:text-primary-text text-sm focus:ring-4 focus:ring-black/5 dark:focus:ring-primary/5 focus:border-black dark:focus:border-primary transition-all outline-none min-h-[100px] leading-relaxed shadow-sm font-medium\"\n                    placeholder=\"Add a description that describes your agent to others...\"\n                  />\n                  <p className=\"text-xs text-gray-400 dark:text-secondary-text font-medium ml-1\">\n                    This will be visible to users when they discover your agent.\n                  </p>\n                </div>\n              </div>\n            </div>\n            <div className=\"flex flex-col gap-6 border-t border-gray-50 dark:border-divider pt-12\">\n              <div className=\"flex flex-col gap-2\">\n                <h2 className=\"text-base font-bold text-gray-900 dark:text-white border-l-4 border-black dark:border-primary pl-3 ml-1\">Theme & Appearance</h2>\n                <p className=\"text-sm text-gray-500 dark:text-secondary-text font-medium ml-1\">\n                  Customize how your agent looks in the chat interface\n                </p>\n              </div>\n              \n              <div className=\"bg-white dark:bg-secondary-bg shadow-lg rounded-3xl p-8 border border-gray-100 dark:border-divider flex flex-col lg:flex-row gap-8\">\n                {/* Theme Selection */}\n                <div className=\"flex-1 flex flex-col gap-4\">\n                  <h4 className=\"text-xs text-gray-400 dark:text-secondary-text font-bold uppercase tracking-wider ml-1\">Select Theme</h4>\n                  <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-3\">\n                    {Object.values(themes || {}).map((theme) => (\n                      <button\n                        key={theme.id}\n                        type=\"button\"\n                        onClick={() => setFormData(prev => ({ ...prev, theme: theme.id }))}\n                        className={`group relative flex flex-col items-center gap-2 p-3 rounded-2xl border-2 transition-all ${\n                          formData.theme === theme.id \n                            ? \"border-black dark:border-primary bg-gray-50 dark:bg-primary-bg shadow-md scale-[1.02]\" \n                            : \"border-gray-100 dark:border-divider hover:border-gray-200 dark:hover:border-primary bg-white dark:bg-primary-bg/50\"\n                        }`}\n                      >\n                        <div \n                          className=\"w-full aspect-video rounded-xl shadow-inner border border-black/5 flex items-center justify-center relative overflow-hidden\"\n                          style={{ background: theme.colors.background }}\n                        >\n                          <div className=\"flex flex-col gap-1 w-[60%]\">\n                            <div className=\"h-1.5 w-[80%] rounded-full opacity-40\" style={{ background: theme.colors.foreground }}></div>\n                            <div className=\"h-1.5 w-[50%] rounded-full opacity-40 ml-auto\" style={{ background: theme.colors.userBubble }}></div>\n                          </div>\n                        </div>\n                        <span className={`text-xs font-bold transition-colors ${\n                          formData.theme === theme.id ? \"text-black dark:text-white\" : \"text-gray-500 dark:text-secondary-text group-hover:text-gray-700 dark:group-hover:text-primary-text\"\n                        }`}>\n                          {theme.name}\n                        </span>\n                        {formData.theme === theme.id && (\n                          <div className=\"absolute -top-2 -right-2 w-5 h-5 bg-black dark:bg-primary text-white rounded-full flex items-center justify-center shadow-lg\">\n                            <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                              <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"3\" d=\"M5 13l4 4L19 7\" />\n                            </svg>\n                          </div>\n                        )}\n                      </button>\n                    ))}\n                  </div>\n                </div>\n                <div className=\"flex-1 flex flex-col gap-4\">\n                  <h4 className=\"text-xs text-gray-400 dark:text-secondary-text font-bold uppercase tracking-wider ml-1\">Chat Preview</h4>\n                  <div \n                    className=\"w-full h-[300px] rounded-3xl overflow-hidden shadow-2xl border border-gray-100 dark:border-divider relative\"\n                    style={{\n                      background: (themes[formData.theme] || themes.cosmic)?.colors.background,\n                      color: (themes[formData.theme] || themes.cosmic)?.colors.foreground\n                    }}\n                  >\n                    <div \n                      className=\"px-4 py-3 flex items-center gap-2 border-b\"\n                      style={{ \n                        background: (themes[formData.theme] || themes.cosmic)?.colors.headerBg,\n                        borderColor: (themes[formData.theme] || themes.cosmic)?.colors.border\n                      }}\n                    >\n                      <div className=\"w-8 h-8 rounded-full bg-gray-400 overflow-hidden\">\n                        {formData.icon_url ? (\n                          <img src={formData.icon_url} className=\"w-full h-full object-cover\" />\n                        ) : (\n                          <RiRobot2Fill className=\"w-full h-full p-1.5 text-white/50\" />\n                        )}\n                      </div>\n                      <div className=\"flex flex-col\">\n                        <span className=\"text-xs font-bold truncate\">{formData.name || \"Agent Name\"}</span>\n                        <span className=\"text-[10px] opacity-60\">Online</span>\n                      </div>\n                    </div>\n                    <div className=\"p-4 flex flex-col gap-4 h-[180px] overflow-y-auto\">\n                      <div className=\"flex flex-col items-end gap-1 max-w-[85%] ml-auto\">\n                        <div \n                          className=\"px-3 py-2 rounded-2xl text-xs font-medium shadow-sm\"\n                          style={{ \n                            background: (themes[formData.theme] || themes.cosmic)?.colors.userBubble,\n                            color: (themes[formData.theme] || themes.cosmic)?.colors.userText\n                          }}\n                        >\n                          Hi! How can you help me today?\n                        </div>\n                      </div>\n                      <div className=\"flex flex-col items-start gap-1 max-w-[85%]\">\n                        <div \n                          className=\"px-3 py-2 rounded-2xl text-xs font-medium border shadow-sm\"\n                          style={{ \n                            background: (themes[formData.theme] || themes.cosmic)?.colors.agentBubble,\n                            color: (themes[formData.theme] || themes.cosmic)?.colors.agentText,\n                            borderColor: (themes[formData.theme] || themes.cosmic)?.colors.border\n                          }}\n                        >\n                          I can help you with tasks, answer questions, and much more using {formData.skill_ids.length} configured skills!\n                        </div>\n                      </div>\n                    </div>\n                    <div className=\"absolute bottom-0 w-full p-4\">\n                      <div \n                        className=\"h-10 rounded-xl flex items-center px-4 gap-2 border shadow-inner\"\n                        style={{ \n                          background: (themes[formData.theme] || themes.cosmic)?.colors.inputBg,\n                          borderColor: (themes[formData.theme] || themes.cosmic)?.colors.border\n                        }}\n                      >\n                        <span className=\"text-xs opacity-30 flex-1\">Type a message...</span>\n                        <div \n                          className=\"w-6 h-6 rounded-lg flex items-center justify-center\"\n                          style={{ background: (themes[formData.theme] || themes.cosmic)?.colors.accent }}\n                        >\n                          <div className=\"w-1.5 h-1.5 rounded-full\" style={{ background: (themes[formData.theme] || themes.cosmic)?.colors.accentText }}></div>\n                        </div>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n              <p className=\"text-xs text-gray-400 dark:text-secondary-text font-medium ml-1\">\n                This theme will be automatically applied to the chat interface for all users.\n              </p>\n            </div>\n\n            <div className=\"flex flex-col gap-6 border-t border-gray-50 dark:border-divider pt-12\">\n              <h2 className=\"text-base font-bold text-gray-900 dark:text-white border-l-4 border-black dark:border-primary pl-3 ml-1\">Capabilities</h2>\n              <div className=\"bg-white dark:bg-secondary-bg shadow-lg rounded-3xl p-8 border border-gray-100 dark:border-divider flex flex-col gap-4\">\n                <div className=\"relative\">\n                  <input\n                    type=\"text\"\n                    placeholder=\"Type to search and add skills (e.g. image generation, web search)...\"\n                    value={searchTerm}\n                    onChange={(e) => setSearchTerm(e.target.value)}\n                    className=\"w-full bg-white dark:bg-primary-bg border border-gray-100 dark:border-divider rounded-xl px-5 py-3.5 text-sm dark:text-white focus:ring-4 focus:ring-black/5 dark:focus:ring-primary/5 focus:border-black dark:focus:border-primary transition-all outline-none shadow-sm\"\n                  />\n                </div>\n                <div className=\"flex flex-col gap-4\">\n                  <h4 className=\"text-xs text-gray-400 dark:text-secondary-text ml-1\">\n                    Active Agent Skills ({formData.skill_ids.length})\n                  </h4>\n                  <div className=\"grid grid-cols-1 md:grid-cols-2 gap-3\">\n                    {formData.skill_ids.length > 0 ? (\n                      formData.skill_ids.map((id) => {\n                        const skill = availableSkills.find(s => s.id === id);\n                        if (!skill) return null;\n                        return (\n                          <button\n                            key={skill.id}\n                            type=\"button\"\n                            onClick={() => handleSkillToggle(skill.id)}\n                            className=\"relative p-4 flex items-center justify-between rounded-2xl bg-white dark:bg-primary-bg border border-gray-100 dark:border-divider shadow-sm transition-all hover:border-black dark:hover:border-primary group\"\n                          >\n                            <div className=\"flex flex-col text-left\">\n                              <span title={skill.name} className=\"text-base font-bold text-gray-900 dark:text-white line-clamp-1\">\n                                {skill.name}\n                              </span>\n                              <span title={skill.description} className=\"text-xs text-gray-400 dark:text-secondary-text line-clamp-2\">\n                                {skill.description}\n                              </span>\n                            </div>\n                            <FaRegTrashCan size={18} className=\"absolute right-4 opacity-0 group-hover:opacity-100 transition-all duration-300 ease-in-out bg-white dark:bg-primary-bg text-red-500\" />\n                          </button>\n                        );\n                      })\n                    ) : (\n                      <div className=\"col-span-full p-12 rounded-2xl border border-dashed border-gray-200 dark:border-divider text-center bg-white/50 dark:bg-primary-bg/50\">\n                        <p className=\"text-sm text-gray-400 dark:text-secondary-text\">No skills configured yet</p>\n                      </div>\n                    )}\n                  </div>\n                    <div className=\"border-t border-gray-200/50 dark:border-divider pt-4\">\n                      <h4 className=\"text-xs text-gray-400 dark:text-secondary-text ml-1 mb-2\">\n                        Available in Registry\n                      </h4>\n                      <div className=\"grid grid-cols-1 md:grid-cols-2 gap-3 max-h-[400px] overflow-y-auto pr-2 custom-scrollbar\">\n                        {availableSkills\n                          .filter(skill => \n                            !formData.skill_ids.includes(skill.id) && \n                            (skill.name.toLowerCase().includes(searchTerm.toLowerCase()) || \n                              skill.id.toLowerCase().includes(searchTerm.toLowerCase()))\n                          )\n                          .map((skill) => (\n                            <button\n                              key={skill.id}\n                              type=\"button\"\n                              onClick={() => {\n                                handleSkillToggle(skill.id);\n                                setSearchTerm(\"\");\n                              }}\n                              className=\"p-4 flex items-center justify-between rounded-2xl border border-gray-100 dark:border-divider bg-white dark:bg-primary-bg hover:border-black dark:hover:border-primary transition-all shadow-sm hover:shadow-md group\"\n                            >\n                              <div className=\"flex flex-col text-left\">\n                                <span title={skill.name} className=\"text-base font-bold text-gray-900 dark:text-white line-clamp-1\">\n                                  {skill.name}\n                                </span>\n                                <span title={skill.description} className=\"text-xs text-gray-400 dark:text-secondary-text line-clamp-2\">\n                                  {skill.description}\n                                </span>\n                              </div>\n                              <span className=\"text-lg text-white bg-black dark:bg-primary rounded-full p-0.5 w-5 h-5 flex items-center justify-center flex-shrink-0\">+</span>\n                            </button>\n                          ))\n                        }\n                      </div>\n                    </div>\n                </div>\n              </div>\n              <p className=\"text-xs text-gray-400 dark:text-secondary-text font-medium ml-1\">\n                Manage tools and skills your agent can use to perform tasks\n              </p>\n            </div>\n          </div>\n          {error && (\n            <div className=\"p-4 bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-900/30 rounded-xl text-red-600 dark:text-red-400 text-sm flex items-center gap-3 animate-shake\">\n              <svg className=\"w-5 h-5 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n              </svg>\n              <span className=\"font-medium\">{error}</span>\n            </div>\n          )}\n        </form>\n      </div>\n      {showRealignModal && (\n        <div className=\"fixed inset-0 bg-black/60 backdrop-blur-sm z-[100] flex items-center justify-center p-4 animate-in fade-in duration-200\">\n          <div className=\"bg-white dark:bg-secondary-bg rounded-3xl w-full max-w-4xl max-h-[90vh] overflow-hidden shadow-2xl flex flex-col animate-in zoom-in-95 duration-200\">\n            <div className=\"px-8 py-6 border-b border-gray-100 dark:border-divider flex items-center justify-between bg-violet-50/50 dark:bg-violet-900/10\">\n              <div className=\"flex items-center gap-3\">\n                <div className=\"w-10 h-10 rounded-xl bg-violet-600 flex items-center justify-center text-white shadow-lg shadow-violet-200 dark:shadow-none\">\n                  <RiRobot2Fill className=\"w-6 h-6\" />\n                </div>\n                <div>\n                  <h3 className=\"text-xl font-bold text-gray-900 dark:text-white\">Review Brain Realignment</h3>\n                  <p className=\"text-xs text-gray-500 dark:text-secondary-text font-medium\">The AI has refactored your instructions to match your new skills.</p>\n                </div>\n              </div>\n              <button\n                onClick={() => setShowRealignModal(false)}\n                className=\"p-2 hover:bg-white dark:hover:bg-primary-bg rounded-full transition-colors text-gray-400 dark:text-secondary-text hover:text-gray-900 dark:hover:text-white\"\n              >\n                <MdClose className=\"w-6 h-6\" />\n              </button>\n            </div>\n\n            <div className=\"flex-1 overflow-y-auto p-8 flex flex-col md:flex-row gap-6 custom-scrollbar\">\n              <div className=\"flex-1 flex flex-col gap-3\">\n                <label className=\"text-xs font-bold text-gray-400 dark:text-secondary-text uppercase tracking-wider ml-1\">Current Instructions</label>\n                <div className=\"flex-1 p-5 bg-gray-50 dark:bg-primary-bg border border-gray-100 dark:border-divider rounded-2xl text-sm text-gray-600 dark:text-secondary-text font-medium whitespace-pre-wrap overflow-y-auto max-h-[400px]\">\n                  {formData.system_prompt}\n                </div>\n              </div>\n              <div className=\"hidden md:flex items-center justify-center text-violet-300 dark:text-violet-500\">\n                <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M13 5l7 7-7 7M5 5l7 7-7 7\" />\n                </svg>\n              </div>\n              <div className=\"flex-1 flex flex-col gap-3\">\n                <label className=\"text-xs font-bold text-violet-600 dark:text-violet-400 uppercase tracking-wider ml-1\">Proposed Instructions</label>\n                <textarea\n                  value={realignedPrompt}\n                  onChange={(e) => setRealignedPrompt(e.target.value)}\n                  className=\"flex-1 p-5 bg-violet-50/30 dark:bg-violet-900/10 border-2 border-violet-100 dark:border-violet-800/50 rounded-2xl text-sm text-gray-800 dark:text-primary-text font-medium leading-relaxed focus:ring-4 focus:ring-violet-500/10 focus:border-violet-500 outline-none transition-all resize-none min-h-[400px]\"\n                />\n              </div>\n            </div>\n\n            <div className=\"px-8 py-6 bg-gray-50 dark:bg-primary-bg border-t border-gray-100 dark:border-divider flex items-center justify-end gap-3\">\n              <button\n                onClick={() => setShowRealignModal(false)}\n                className=\"px-6 py-2.5 text-sm font-bold text-gray-600 dark:text-secondary-text hover:text-gray-900 dark:hover:text-white transition-colors\"\n              >\n                Discard Changes\n              </button>\n              <button\n                onClick={applyRealignedPrompt}\n                className=\"px-8 py-2.5 bg-violet-600 hover:bg-violet-700 text-white text-sm font-bold rounded-xl transition-all shadow-lg shadow-violet-200 dark:shadow-none active:scale-95\"\n              >\n                Accept & Apply\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n      {showIconPromptModal && (\n        <div className=\"fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200\">\n          <div className=\"bg-white dark:bg-secondary-bg w-full max-w-lg rounded-3xl shadow-2xl border border-gray-100 dark:border-divider overflow-hidden transform animate-in zoom-in-95 duration-200\">\n            <div className=\"p-6 border-b border-gray-100 dark:border-divider flex items-center justify-between bg-gray-50/50 dark:bg-primary-bg/50\">\n              <h3 className=\"text-xl font-bold dark:text-white flex items-center gap-2\">\n                <span className=\"text-2xl\">✨</span> Customize AI Icon Prompt\n              </h3>\n              <button\n                onClick={() => setShowIconPromptModal(false)}\n                className=\"p-2 hover:bg-white dark:hover:bg-secondary-bg rounded-full transition-colors text-gray-400 hover:text-gray-600 dark:hover:text-primary-text\"\n              >\n                <IoCloseOutline className=\"w-6 h-6\" />\n              </button>\n            </div>\n\n            <div className=\"p-8\">\n              <p className=\"text-sm text-gray-500 dark:text-secondary-text mb-6\">\n                Tell the AI what kind of icon you want. You can describe style, colors, and specific elements.\n              </p>\n\n              <div className=\"space-y-4\">\n                <textarea\n                  value={iconPrompt}\n                  onChange={(e) => setIconPrompt(e.target.value)}\n                  placeholder=\"Describe your agent's icon...\"\n                  className=\"w-full h-40 p-5 bg-gray-50 dark:bg-primary-bg border border-gray-200 dark:border-divider rounded-2xl text-sm focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 outline-none transition-all resize-none dark:text-white placeholder:text-gray-400\"\n                />\n\n                <div className=\"flex gap-3 pt-4\">\n                  <button\n                    onClick={() => setShowIconPromptModal(false)}\n                    className=\"flex-1 px-6 py-4 border border-gray-200 dark:border-divider rounded-2xl text-sm font-bold text-gray-600 dark:text-primary-text hover:bg-gray-50 dark:hover:bg-primary-bg transition-all active:scale-[0.98]\"\n                  >\n                    Cancel\n                  </button>\n                  <button\n                    onClick={() => handleGenerateIcon(iconPrompt)}\n                    disabled={generatingIcon || !iconPrompt.trim()}\n                    className=\"flex-[2] px-6 py-4 bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white font-bold rounded-2xl transition-all shadow-lg shadow-blue-500/20 active:scale-[0.98] flex items-center justify-center gap-2\"\n                  >\n                    {generatingIcon ? (\n                      <>\n                        <BiLoaderAlt className=\"w-5 h-5 animate-spin\" />\n                        Generating...\n                      </>\n                    ) : (\n                      <>\n                        <span className=\"text-lg\">✨</span>\n                        Generate Icon\n                      </>\n                    )}\n                  </button>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      )}\n      {showIconSelectionModal && (\n        <div className=\"fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200\">\n          <div className=\"bg-white dark:bg-secondary-bg w-full max-w-md rounded-[2.5rem] shadow-2xl border border-gray-100 dark:border-divider overflow-hidden transform animate-in zoom-in-95 duration-200\">\n            <div className=\"p-8 border-b border-gray-50 dark:border-divider flex items-center justify-between\">\n              <div>\n                <h3 className=\"text-2xl font-black dark:text-white leading-tight\">Profile Icon</h3>\n                <p className=\"text-sm text-gray-500 dark:text-secondary-text mt-1 font-medium\">Choose how to update your agent's look</p>\n              </div>\n              <button \n                onClick={() => setShowIconSelectionModal(false)}\n                className=\"w-10 h-10 flex items-center justify-center bg-gray-50 dark:bg-primary-bg rounded-full text-gray-400 hover:text-black dark:hover:text-white transition-colors\"\n              >\n                <IoCloseOutline className=\"w-6 h-6\" />\n              </button>\n            </div>\n            \n            <div className=\"p-8 grid grid-cols-1 gap-4\">\n              <button\n                onClick={() => {\n                  setShowIconSelectionModal(false);\n                  fileInputRef.current?.click();\n                }}\n                className=\"group flex flex-col items-center gap-4 p-8 bg-gray-50 dark:bg-primary-bg rounded-[2rem] border border-gray-100 dark:border-divider hover:border-blue-500/50 hover:bg-white dark:hover:bg-secondary-bg transition-all duration-300 hover:shadow-xl hover:shadow-blue-500/5 active:scale-[0.98]\"\n              >\n                <div className=\"w-16 h-16 rounded-2xl bg-white dark:bg-secondary-bg shadow-sm flex items-center justify-center text-gray-400 group-hover:text-blue-500 transition-colors duration-300\">\n                  <IoImageOutline className=\"w-8 h-8\" />\n                </div>\n                <div className=\"text-center\">\n                  <h4 className=\"font-bold text-gray-900 dark:text-white text-lg\">Upload Photo</h4>\n                  <p className=\"text-sm text-gray-500 dark:text-secondary-text mt-1\">Pick a file from your device</p>\n                </div>\n              </button>\n\n              <button\n                onClick={() => {\n                  setShowIconSelectionModal(false);\n                  setIconPrompt(`A professional, clean profile icon for an AI agent named \"${formData.name}\". Description: ${formData.description || \"An AI assistant\"}. Minimalist, high-quality, circular composition.`);\n                  setShowIconPromptModal(true);\n                }}\n                className=\"group flex flex-col items-center gap-4 p-8 bg-blue-50/30 dark:bg-blue-500/5 rounded-[2rem] border border-blue-100/50 dark:border-blue-500/20 hover:border-blue-500 hover:bg-white dark:hover:bg-secondary-bg transition-all duration-300 hover:shadow-xl hover:shadow-blue-500/10 active:scale-[0.98]\"\n              >\n                <div className=\"w-16 h-16 rounded-2xl bg-blue-600 shadow-lg shadow-blue-500/30 flex items-center justify-center text-white transform transition-transform duration-500 group-hover:rotate-12 group-hover:scale-110\">\n                  <IoSparklesOutline className=\"w-8 h-8\" />\n                </div>\n                <div className=\"text-center\">\n                  <h4 className=\"font-bold text-blue-600 dark:text-primary text-lg\">Generate with AI</h4>\n                  <p className=\"text-sm text-blue-500/70 dark:text-primary/70 mt-1\">Create unique icon from prompt</p>\n                </div>\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\nexport default EditAgent\n"
  },
  {
    "path": "packages/agents/src/components/ProfileAgent.jsx",
    "content": "\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport axios from \"axios\";\nimport { RiRobot2Fill } from \"react-icons/ri\";\nimport { BiLoaderAlt } from \"react-icons/bi\";\nimport {\n  IoChatbubbleEllipsesSharp,\n  IoShareOutline,\n  IoHeartOutline,\n  IoHeart,\n} from \"react-icons/io5\";\nimport { FiClock, FiZap } from \"react-icons/fi\";\nimport { MdOutlineVerified } from \"react-icons/md\";\nimport { HiPlus } from \"react-icons/hi2\";\nimport { useParams } from \"next/navigation\";\n\nconst BASE_URL = \"/api/agents\";\n\nfunction timeAgo(dateStr) {\n  if (!dateStr) return \"\";\n  const utcStr =\n    dateStr.endsWith(\"Z\") || dateStr.includes(\"+\") ? dateStr : dateStr + \"Z\";\n  const now = new Date();\n  const d = new Date(utcStr);\n  const diff = Math.floor((now - d) / 1000);\n  if (diff < 60) return \"just now\";\n  if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;\n  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;\n  if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`;\n  const months = Math.floor(diff / 2592000);\n  if (months < 12) return `${months} mo. ago`;\n  return `${Math.floor(months / 12)} yr. ago`;\n}\n\nfunction formatCount(n) {\n  if (!n && n !== 0) return \"–\";\n  if (n >= 1000000) return (n / 1000000).toFixed(1) + \"M\";\n  if (n >= 1000) return (n / 1000).toFixed(1) + \"K\";\n  return n.toLocaleString();\n}\n\n/**\n * ProfileAgent — Agent profile content component.\n * Supports light (muapiapp default) and dark (vadoo / dark-mode) themes via\n * Tailwind's `dark:` prefix + CSS variables set by the host app.\n *\n * Props:\n *   useUser  {function} — hook to get the current logged-in user\n *   usedIn   {string}   — \"muapiapp\" | \"vadoo\"\n */\nexport default function ProfileAgent({ useUser, usedIn = \"muapiapp\" }) {\n  const { agent_id } = useParams();\n\n  const [profile, setProfile] = useState(null);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState(null);\n  const [liked, setLiked] = useState(false);\n  const [copied, setCopied] = useState(false);\n\n  const fetchProfile = useCallback(async () => {\n    try {\n      setLoading(true);\n      const res = await axios.get(`${BASE_URL}/${agent_id}/profile`);\n      setProfile(res.data);\n      if (res.data?.agent) {\n        setLiked(res.data.agent.has_liked || false);\n      }\n      setError(null);\n    } catch (err) {\n      setError(\n        err.response?.data?.detail || err.message || \"Failed to load agent profile\"\n      );\n    } finally {\n      setLoading(false);\n    }\n  }, [agent_id]);\n\n  useEffect(() => {\n    if (agent_id) fetchProfile();\n  }, [agent_id, fetchProfile]);\n\n  const handleShare = () => {\n    const url = window.location.href;\n    navigator.clipboard.writeText(url).then(() => {\n      setCopied(true);\n      setTimeout(() => setCopied(false), 2000);\n    });\n  };\n\n  const handleLike = async () => {\n    const newLiked = !liked;\n    setLiked(newLiked);\n    try {\n      const res = await axios.post(`/api/agents/by-slug/${agent.agent_id || agent.id}/like?is_like=${newLiked}`);\n      \n      // Update the local state properly to trigger re-render\n      if (profile) {\n        setProfile({\n          ...profile,\n          agent: {\n            ...profile.agent,\n            like_count: res.data.like_count,\n            has_liked: res.data.has_liked\n          }\n        });\n        // Also ensure the 'liked' state is in sync with the real source of truth\n        setLiked(res.data.has_liked);\n      }\n    } catch (err) {\n      console.error(\"Failed to sync like:\", err);\n      // Rollback on error\n      setLiked(!newLiked);\n    }\n  };\n\n  if (loading) {\n    return (\n      <div className=\"flex flex-col items-center justify-center py-32 gap-3 w-full\">\n        <BiLoaderAlt className=\"w-8 h-8 text-gray-400 dark:text-secondary-text animate-spin\" />\n        <p className=\"text-gray-400 dark:text-secondary-text text-sm\">Loading agent profile...</p>\n      </div>\n    );\n  }\n\n  if (error || !profile) {\n    return (\n      <div className=\"flex flex-col items-center justify-center py-32 gap-2 w-full\">\n        <RiRobot2Fill className=\"w-12 h-12 text-gray-300 dark:text-secondary-text mx-auto\" />\n        <p className=\"text-gray-800 dark:text-primary-text font-bold\">Agent not found</p>\n        <p className=\"text-gray-500 dark:text-secondary-text text-sm\">{error}</p>\n      </div>\n    );\n  }\n\n  const { agent, total_messages, total_chats, recent_chats } = profile;\n\n  const chatUrl = agent.agent_id\n    ? `/agents/${agent.agent_id}`\n    : `/agents/${agent.id}`;\n\n  return (\n    <div className=\"w-full max-w-5xl mx-auto px-4 sm:px-6 pb-16\">\n      <div className=\"border-b border-gray-200 dark:border-divider py-6\">\n        <div className=\"flex flex-col md:flex-row md:items-start gap-5\">\n          <div className=\"flex items-center gap-5\">\n            <div className=\"relative w-16 h-16 rounded-full overflow-hidden bg-gray-100 dark:bg-secondary-bg border-2 border-gray-200 dark:border-divider shrink-0\">\n              {agent.icon_url ? (\n                <Image src={agent.icon_url} alt={agent.name} fill className=\"object-cover\" />\n              ) : (\n                <div className=\"w-full h-full flex items-center justify-center\">\n                  <RiRobot2Fill className=\"w-8 h-8 text-gray-400 dark:text-secondary-text\" />\n                </div>\n              )}\n            </div>\n            <div className=\"flex-1 min-w-0\">\n              <div className=\"flex items-center gap-2 flex-wrap\">\n                <h1 className=\"text-2xl font-bold text-black dark:text-white\">\n                  {agent.name}\n                </h1>\n                {agent.is_published && (\n                  <span className=\"flex items-center gap-1 text-xs font-bold px-2 py-0.5 rounded-full bg-blue-50 dark:bg-white/10 text-blue-600 dark:text-gray-300 border border-blue-100 dark:border-white/10\">\n                    <MdOutlineVerified className=\"w-3 h-3\" /> Public\n                  </span>\n                )}\n              </div>\n              {agent.description && (\n                <p className=\"text-gray-500 dark:text-secondary-text text-sm mt-1 leading-relaxed max-w-xl\">\n                  {agent.description}\n                </p>\n              )}\n              { (agent.owner_username || agent.owner_email) && (\n                <p className=\"text-xs text-gray-400 dark:text-secondary-text mt-1.5\">\n                  by{\" \"}\n                  <span className=\"text-gray-600 dark:text-gray-300 font-medium\">\n                    {agent.owner_username || agent.owner_email.split(\"@\")[0]}\n                  </span>\n                </p>\n              )}\n            </div>\n          </div>\n          <div className=\"flex items-center gap-2 shrink-0\">\n            <button\n              type=\"button\"\n              onClick={handleLike}\n              className=\"flex items-center gap-2 px-3 py-2 rounded-lg bg-gray-100 dark:bg-secondary-bg hover:bg-gray-200 dark:hover:bg-white/10 border border-gray-200 dark:border-divider text-sm transition-all\"\n            >\n              {liked ? (\n                <IoHeart className=\"w-4 h-4 text-red-500\" />\n              ) : (\n                <IoHeartOutline className=\"w-4 h-4 text-gray-500 dark:text-secondary-text\" />\n              )}\n              <span className=\"font-medium text-gray-700 dark:text-gray-300\">\n                {agent.like_count || 0}\n              </span>\n            </button>\n            <button\n              onClick={handleShare}\n              title={copied ? \"Copied!\" : \"Share link\"}\n              className=\"flex items-center gap-1.5 px-3 py-2 rounded-lg bg-gray-100 dark:bg-secondary-bg hover:bg-gray-200 dark:hover:bg-white/10 border border-gray-200 dark:border-divider text-sm transition-all\"\n            >\n              <IoShareOutline className=\"w-4 h-4 text-gray-500 dark:text-secondary-text\" />\n              {copied && <span className=\"text-xs text-green-500 dark:text-green-400\">Copied!</span>}\n            </button>\n            <Link\n              href={chatUrl}\n              className=\"flex items-center gap-2 px-4 py-2 bg-violet-600 hover:bg-violet-500 text-white text-sm font-bold rounded-lg transition-all shadow-sm\"\n            >\n              <IoChatbubbleEllipsesSharp className=\"w-4 h-4\" />\n              Chat\n            </Link>\n          </div>\n        </div>\n      </div>\n      <div className=\"grid grid-cols-1 lg:grid-cols-[1fr_280px] gap-8 mt-8\">\n        <div className=\"space-y-8\">\n          {agent.skills && agent.skills.length > 0 && (\n            <section>\n              <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest mb-3\">\n                Workflows\n              </p>\n              <div className=\"flex flex-wrap gap-2\">\n                {agent.skills.map((skill) => (\n                  <span\n                    key={skill.id}\n                    className=\"flex items-center gap-1.5 px-3 py-1.5 bg-gray-100 dark:bg-secondary-bg border border-gray-200 dark:border-divider rounded-lg text-xs text-gray-600 dark:text-gray-300 font-medium hover:bg-gray-200 dark:hover:bg-white/10 transition-colors\"\n                  >\n                    <FiZap className=\"w-3 h-3 text-violet-500 dark:text-violet-400\" />\n                    {skill.name}\n                  </span>\n                ))}\n              </div>\n            </section>\n          )}\n          {agent.description && (\n            <section>\n              <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest mb-3\">\n                About {agent.name}\n              </p>\n              <p className=\"text-gray-700 dark:text-gray-300 text-sm leading-relaxed\">\n                {agent.description}\n              </p>\n            </section>\n          )}\n          {agent.welcome_message && (\n            <section className=\"bg-gray-50 dark:bg-secondary-bg border border-gray-200 dark:border-divider rounded-xl p-4\">\n              <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest mb-2\">\n                Greeting\n              </p>\n              <p className=\"text-gray-600 dark:text-gray-300 text-sm italic leading-relaxed\">\n                \"{agent.welcome_message}\"\n              </p>\n            </section>\n          )}\n          <section>\n            <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest mb-3\">\n              Details\n            </p>\n            <div className=\"space-y-2.5\">\n              <DetailRow label=\"Messages\" value={formatCount(total_messages)} />\n              <DetailRow label=\"Chats\"    value={formatCount(total_chats)} />\n              <DetailRow label=\"Created\"  value={timeAgo(agent.created_at)} />\n              {agent.skills && agent.skills.length > 0 && (\n                <DetailRow label=\"Skills\" value={agent.skills.length.toString()} />\n              )}\n            </div>\n          </section>\n        </div>\n        <div className=\"space-y-4\">\n          {recent_chats && recent_chats.length > 0 && (\n            <div className=\"bg-gray-50 dark:bg-secondary-bg border border-gray-200 dark:border-divider rounded-2xl p-4\">\n              <div className=\"flex items-center gap-2 mb-4\">\n                <FiClock className=\"w-3.5 h-3.5 text-gray-400 dark:text-secondary-text\" />\n                <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest\">\n                  Recent chats with this agent\n                </p>\n              </div>\n              <div className=\"space-y-1\">\n                {recent_chats.map((chat) => (\n                  <Link\n                    key={chat.id}\n                    href={\n                      chat.agent_slug\n                        ? `/agents/${chat.agent_slug}/${chat.id}`\n                        : `/agents/${chat.agent_id}/${chat.id}`\n                    }\n                    className=\"flex items-center gap-3 p-2.5 rounded-xl hover:bg-gray-100 dark:hover:bg-white/5 transition-colors group\"\n                  >\n                    <div className=\"w-8 h-8 rounded-lg bg-gray-200 dark:bg-gray-700 flex items-center justify-center shrink-0\">\n                      <IoChatbubbleEllipsesSharp className=\"w-4 h-4 text-gray-500 dark:text-gray-400 group-hover:text-gray-800 dark:group-hover:text-white transition-colors\" />\n                    </div>\n                    <div className=\"flex-1 min-w-0\">\n                      <p className=\"text-sm font-medium text-gray-800 dark:text-gray-200 truncate group-hover:text-black dark:group-hover:text-white transition-colors\">\n                        {chat.title || \"New Chat\"}\n                      </p>\n                      <p className=\"text-[11px] text-gray-400 dark:text-secondary-text\">\n                        {chat.message_count} msg{chat.message_count !== 1 ? \"s\" : \"\"} · {timeAgo(chat.updated_at)}\n                      </p>\n                    </div>\n                  </Link>\n                ))}\n              </div>\n              <Link\n                href={chatUrl}\n                className=\"mt-3 flex items-center justify-center gap-2 w-full py-2.5 rounded-xl bg-gray-100 dark:bg-white/5 hover:bg-gray-200 dark:hover:bg-white/10 border border-gray-200 dark:border-divider text-sm text-gray-600 dark:text-gray-300 hover:text-black dark:hover:text-white transition-all font-medium\"\n              >\n                <HiPlus className=\"w-4 h-4\" />\n                New chat\n              </Link>\n            </div>\n          )}\n          {agent.initial_suggestions && agent.initial_suggestions.length > 0 && (\n            <div className=\"bg-gray-50 dark:bg-secondary-bg border border-gray-200 dark:border-divider rounded-2xl p-4\">\n              <p className=\"text-[11px] font-bold text-gray-400 dark:text-secondary-text uppercase tracking-widest mb-3\">\n                Try asking\n              </p>\n              <div className=\"space-y-2\">\n                {agent.initial_suggestions.slice(0, 4).map((s, i) => (\n                  <Link\n                    key={i}\n                    href={`${chatUrl}?prompt=${encodeURIComponent(s.prompt || s.label || \"\")}`}\n                    className=\"block text-sm text-gray-600 dark:text-gray-300 hover:text-black dark:hover:text-white bg-white dark:bg-white/5 hover:bg-gray-100 dark:hover:bg-white/10 border border-gray-200 dark:border-divider rounded-xl px-3 py-2 transition-all truncate\"\n                  >\n                    {s.label || s.prompt}\n                  </Link>\n                ))}\n              </div>\n            </div>\n          )}\n        </div>\n      </div>\n    </div>\n  );\n}\n\nfunction DetailRow({ label, value }) {\n  return (\n    <div className=\"flex items-center gap-4\">\n      <span className=\"text-sm text-gray-400 dark:text-secondary-text w-24 shrink-0\">{label}</span>\n      <span className=\"text-sm text-gray-800 dark:text-primary-text font-medium\">{value}</span>\n    </div>\n  );\n}\n"
  },
  {
    "path": "packages/agents/src/components/themes.jsx",
    "content": "\nexport const themes = {\n  cosmic: {\n    id: 'cosmic',\n    name: 'Cosmic',\n    colors: {\n      background: 'radial-gradient(circle at 50% -20%, #1e293b 0%, #0b0f1a 80%)',\n      foreground: '#ffffff',\n      muted: '#94a3b8',\n      border: 'rgba(255, 255, 255, 0.1)',\n      componentBg: 'rgba(255, 255, 255, 0.05)',\n      componentHover: 'rgba(255, 255, 255, 0.1)',\n      headerBg: 'rgba(19, 24, 38, 0.8)',\n      userBubble: 'linear-gradient(135deg, #2563eb 0%, #4338ca 100%)',\n      userText: '#ffffff',\n      agentBubble: 'rgba(30, 41, 59, 0.6)',\n      agentText: '#cbd5e1',\n      inputBg: 'rgba(30, 41, 59, 0.5)',\n      accent: '#3b82f6',\n      accentText: '#ffffff',\n    }\n  },\n  midnight: {\n    id: 'midnight',\n    name: 'Midnight',\n    colors: {\n      background: '#000000',\n      foreground: '#ededed',\n      muted: '#737373',\n      border: '#262626',\n      componentBg: '#171717',\n      componentHover: '#262626',\n      headerBg: 'rgba(0, 0, 0, 0.8)',\n      userBubble: '#262626',\n      userText: '#ffffff',\n      agentBubble: '#0a0a0a',\n      agentText: '#d4d4d4',\n      inputBg: '#0a0a0a',\n      accent: '#ffffff',\n      accentText: '#000000',\n    }\n  },\n  light: {\n    id: 'light',\n    name: 'Clean Light',\n    colors: {\n      background: 'linear-gradient(to bottom, #f8fafc, #ffffff)',\n      foreground: '#1e293b',\n      muted: '#64748b',\n      border: '#e2e8f0',\n      componentBg: '#f1f5f9',\n      componentHover: '#e2e8f0',\n      headerBg: 'rgba(255, 255, 255, 0.8)',\n      userBubble: '#1e293b',\n      userText: '#ffffff',\n      agentBubble: '#ffffff',\n      agentText: '#334155',\n      inputBg: '#ffffff',\n      accent: '#475569',\n      accentText: '#ffffff',\n    }\n  },\n  cyberpunk: {\n    id: 'cyberpunk',\n    name: 'Cyberpunk',\n    colors: {\n      background: 'linear-gradient(45deg, #050505 0%, #12031c 100%)',\n      foreground: '#00ff41',\n      muted: '#d300c5',\n      border: '#00ff41',\n      componentBg: 'rgba(255, 0, 187, 0.1)',\n      componentHover: 'rgba(0, 255, 65, 0.1)',\n      headerBg: 'rgba(5, 5, 5, 0.9)',\n      userBubble: 'linear-gradient(90deg, #ff00ea, #5500ff)',\n      userText: '#ffffff',\n      agentBubble: '#000000',\n      agentText: '#00ff41',\n      inputBg: '#050505',\n      accent: '#d300c5',\n      accentText: '#ffffff',\n    }\n  },\n  glossy: {\n    id: 'glossy',\n    name: 'Glossy',\n    colors: {\n      background: 'linear-gradient(120deg, #e0c3fc 0%, #8ec5fc 100%)',\n      foreground: '#2d3748',\n      muted: '#64748b',\n      border: 'rgba(255, 255, 255, 0.4)',\n      componentBg: 'rgba(255, 255, 255, 0.3)',\n      componentHover: 'rgba(255, 255, 255, 0.5)',\n      headerBg: 'rgba(255, 255, 255, 0.2)',\n      userBubble: 'rgba(255, 255, 255, 0.8)',\n      userText: '#2d3748',\n      agentBubble: 'rgba(255, 255, 255, 0.4)',\n      agentText: '#2d3748',\n      inputBg: 'rgba(255, 255, 255, 0.5)',\n      accent: '#63b3ed',\n      accentText: '#ffffff',\n    }\n  },\n  ocean: {\n    id: 'ocean',\n    name: 'Ocean Depth',\n    colors: {\n      background: 'linear-gradient(to bottom, #0f172a, #082f49)',\n      foreground: '#e0f2fe',\n      muted: '#7dd3fc',\n      border: '#0c4a6e',\n      componentBg: '#0c4a6e',\n      componentHover: '#075985',\n      headerBg: 'rgba(12, 74, 110, 0.8)',\n      userBubble: '#0ea5e9',\n      userText: '#ffffff',\n      agentBubble: '#164e63',\n      agentText: '#e0f2fe',\n      inputBg: '#082f49',\n      accent: '#38bdf8',\n      accentText: '#082f49',\n    }\n  },\n  forest: {\n    id: 'forest',\n    name: 'Dark Forest',\n    colors: {\n      background: '#052e16',\n      foreground: '#dcfce7',\n      muted: '#86efac',\n      border: '#14532d',\n      componentBg: '#14532d',\n      componentHover: '#166534',\n      headerBg: 'rgba(5, 46, 22, 0.9)',\n      userBubble: '#22c55e',\n      userText: '#064e3b',\n      agentBubble: '#064e3b',\n      agentText: '#dcfce7',\n      inputBg: '#064e3b',\n      accent: '#4ade80',\n      accentText: '#064e3b',\n    }\n  },\n  sunset: {\n    id: 'sunset',\n    name: 'Sunset',\n    colors: {\n      background: 'linear-gradient(to top right, #4a1d1d, #7c2d12)',\n      foreground: '#ffedd5',\n      muted: '#fdba74',\n      border: '#9a3412',\n      componentBg: '#7c2d12',\n      componentHover: '#9a3412',\n      headerBg: 'rgba(124, 45, 18, 0.8)',\n      userBubble: 'linear-gradient(90deg, #f97316, #ea580c)',\n      userText: '#ffffff',\n      agentBubble: '#431407',\n      agentText: '#ffedd5',\n      inputBg: '#431407',\n      accent: '#fb923c',\n      accentText: '#431407',\n    }\n  },\n  dracula: {\n    id: 'dracula',\n    name: 'Vampire',\n    colors: {\n      background: '#282a36',\n      foreground: '#f8f8f2',\n      muted: '#6272a4',\n      border: '#44475a',\n      componentBg: '#44475a',\n      componentHover: '#6272a4',\n      headerBg: '#282a36',\n      userBubble: '#ff79c6',\n      userText: '#282a36',\n      agentBubble: '#44475a',\n      agentText: '#f8f8f2',\n      inputBg: '#44475a',\n      accent: '#bd93f9',\n      accentText: '#282a36',\n    }\n  },\n  coffee: {\n    id: 'coffee',\n    name: 'Coffee Shop',\n    colors: {\n      background: '#2e2622',\n      foreground: '#d6ccc2',\n      muted: '#b0a695',\n      border: '#4a3b32',\n      componentBg: '#3d322b',\n      componentHover: '#4a3b32',\n      headerBg: 'rgba(46, 38, 34, 0.9)',\n      userBubble: '#c3a185',\n      userText: '#2e2622',\n      agentBubble: '#1f1a17',\n      agentText: '#d6ccc2',\n      inputBg: '#1f1a17',\n      accent: '#d4a373',\n      accentText: '#2e2622',\n    }\n  },\n  terminal: {\n    id: 'terminal',\n    name: 'Hacker Terminal',\n    colors: {\n      background: '#0d1117',\n      foreground: '#00ff00',\n      muted: '#2ea043', // Lighter green for better visibility\n      border: '#30363d', // Subtle border\n      componentBg: '#161b22',\n      componentHover: '#21262d',\n      headerBg: '#0d1117',\n      userBubble: '#238636', // GitHub-like green button\n      userText: '#ffffff',\n      agentBubble: '#161b22',\n      agentText: '#00ff00',\n      inputBg: '#0d1117',\n      accent: '#2f81f7', // Blue accent for variety or keep green #2ea043\n      accentText: '#ffffff',\n    }\n  },\n  royal: {\n    id: 'royal',\n    name: 'Royal',\n    colors: {\n      background: '#1a0b2e',\n      foreground: '#e9d5ff',\n      muted: '#a855f7',\n      border: '#4c1d95',\n      componentBg: '#2e1065',\n      componentHover: '#4c1d95',\n      headerBg: 'rgba(26, 11, 46, 0.9)',\n      userBubble: 'linear-gradient(to right, #7e22ce, #6b21a8)',\n      userText: '#ffffff',\n      agentBubble: '#3b0764',\n      agentText: '#e9d5ff',\n      inputBg: '#3b0764',\n      accent: '#d8b4fe',\n      accentText: '#3b0764',\n    }\n  },\n  custom: {\n    id: 'custom',\n    name: 'Custom Theme',\n    colors: {\n      background: '#ffffff',\n      foreground: '#1e293b',\n      muted: '#64748b',\n      border: '#e2e8f0',\n      componentBg: '#f1f5f9',\n      componentHover: '#e2e8f0',\n      headerBg: 'rgba(255, 255, 255, 0.8)',\n      userBubble: '#1e293b',\n      userText: '#ffffff',\n      agentBubble: '#ffffff',\n      agentText: '#334155',\n      inputBg: '#ffffff',\n      accent: '#475569',\n      accentText: '#ffffff',\n    }\n  }\n};\n"
  },
  {
    "path": "packages/agents/src/index.js",
    "content": "export { default as AiAgent } from \"./AiAgent\";\nexport { getAgentDetails } from \"./utils/server\";\nexport { themes } from \"./components/themes\";\nexport { default as CreateAgentPage } from \"./CreatePage\";\nexport { default as EditAgentPage } from \"./EditPage\";\nexport { default as AgentThemeProvider } from \"./components/AgentThemeProvider\";\nexport { default as AgentProfile } from \"./AgentProfile\";\n\n"
  },
  {
    "path": "packages/agents/src/tailwind.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer components {\n  .premium-bg {\n    @apply bg-white dark:bg-[#09090b];\n    background-image: radial-gradient(circle at 0% 0%, rgba(79, 70, 229, 0.03) 0%, transparent 25%),\n                      radial-gradient(circle at 100% 100%, rgba(59, 130, 246, 0.03) 0%, transparent 25%);\n  }\n\n  .premium-sidebar-blur {\n    @apply backdrop-blur-xl bg-white/80 dark:bg-[#09090b]/80;\n  }\n\n  .premium-glass {\n    @apply backdrop-blur-md bg-white/70 dark:bg-zinc-900/60 border border-black/5 dark:border-white/10;\n  }\n\n  .scrollbar-hide::-webkit-scrollbar {\n    display: none;\n  }\n\n  .scrollbar-hide {\n    -ms-overflow-style: none;\n    scrollbar-width: none;\n  }\n}\n\n.skeleton {\n  background: linear-gradient(\n    90deg,\n    #2a2a2a 25%,\n    #3a3a3a 50%,\n    #2a2a2a 75%\n  );\n  background-size: 200% 100%;\n  animation: wave 1.5s ease-in-out infinite;\n}\n\n@keyframes wave {\n  0% {\n    background-position: 200% 0;\n  }\n  100% {\n    background-position: -200% 0;\n  }\n}\n\n/* Basic Markdown Spacing Fixes */\n.prose p {\n  margin-bottom: 1rem;\n}\n.prose p:last-child {\n  margin-bottom: 0;\n}\n.prose ul {\n  list-style-type: disc;\n  margin-left: 1.5rem;\n  margin-bottom: 1rem;\n}\n.prose ol {\n  list-style-type: decimal;\n  margin-left: 1.5rem;\n  margin-bottom: 1rem;\n}\n.prose li {\n  margin-bottom: 0.25rem;\n}\n.prose h1, .prose h2, .prose h3, .prose h4 {\n  font-weight: 600;\n  margin-top: 1.5rem;\n  margin-bottom: 0.75rem;\n  color: white;\n}\n.prose h1 { font-size: 1.5rem; }\n.prose h2 { font-size: 1.25rem; }\n.prose h3 { font-size: 1.125rem; }\n\n.custom-scrollbar::-webkit-scrollbar {\n  width: 6px;\n}\n.custom-scrollbar::-webkit-scrollbar-track {\n  background: transparent;\n}\n.custom-scrollbar::-webkit-scrollbar-thumb {\n  background: rgba(255, 255, 255, 0.1);\n  border-radius: 10px;\n}\n.custom-scrollbar:hover::-webkit-scrollbar-thumb {\n  background: rgba(255, 255, 255, 0.15);\n}\n"
  },
  {
    "path": "packages/agents/src/utils/server.js",
    "content": "export const getAgentDetails = async (agentId, options = {}) => {\n  const {\n    baseUrl = \"http://127.0.0.1:8000/agents\", // Default relative URL for internal API, or provide full URL\n    fetchOptions = {}\n  } = options;\n\n  if (!agentId) {\n    throw new Error(\"Agent ID is required\");\n  }\n\n  const url = `${baseUrl}/${agentId}`;\n  \n  try {\n    const response = await fetch(url, {\n      ...fetchOptions,\n      cache: fetchOptions.cache || 'no-store', \n    });\n\n    if (!response.ok) {\n      throw new Error(`Failed to fetch agent details: ${response.status} ${response.statusText}`);\n    }\n\n    return await response.json();\n  } catch (error) {\n    console.error(\"Error fetching agent details:\", error);\n    throw error;\n  }\n};\n"
  },
  {
    "path": "packages/agents/tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  darkMode: 'class',\n  content: [\"./src/**/*.{js,jsx}\"],\n  theme: {\n    extend: {\n      colors: {\n        'primary': '#3898ec',\n        'primary-bg': '#121212',\n        'secondary-bg': '#1E1E1E',\n        'primary-text': '#E0E0E0',\n        'secondary-text': '#B0B0B0',\n        'divider': '#333333',\n      },\n    },\n  },\n  plugins: [],\n}\n\n"
  },
  {
    "path": "server/.gitignore",
    "content": "__pycache__/\n*.py[cod]\n*$py.class\n*.so\n.Python\nenv/\nvenv/\nENV/\n.venv\n*.egg-info/\ndist/\nbuild/\n.pytest_cache/\n.coverage\nhtmlcov/\n"
  },
  {
    "path": "server/app/main.py",
    "content": "import os\nfrom dotenv import load_dotenv\n\nenv_path = os.path.join(os.path.dirname(__file__), '..', '.env')\nload_dotenv(env_path)\n\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom .routers import agent_proxy\n\napp = FastAPI(title=\"Vibe-Agents API\", version=\"1.0.0\")\n\n# Configure CORS\napp.add_middleware(\n    CORSMiddleware,\n    allow_origins=[\"http://localhost:3000\"],\n    allow_credentials=True,\n    allow_methods=[\"*\"],\n    allow_headers=[\"*\"],\n)\n\n# Include routers\napp.include_router(agent_proxy.router, prefix=\"/api\", tags=[\"proxy\"])\n\n@app.get(\"/\")\nasync def root():\n    return {\"message\": \"Welcome to Vibe-Agents API\"}\n\n@app.get(\"/api/health\")\nasync def health_check():\n    return {\"status\": \"healthy\"}\n"
  },
  {
    "path": "server/app/routers/__init__.py",
    "content": "from . import agent_proxy\n"
  },
  {
    "path": "server/app/routers/agent_proxy.py",
    "content": "from fastapi import APIRouter, Request, HTTPException\nfrom app.utils.agent_helper import proxy_request\nfrom typing import Optional\nimport os\n\nrouter = APIRouter()\nMUAPI_BASE_URL = os.getenv(\"MUAPI_BASE_URL\", \"https://api.muapi.ai\")\n# --- Agent Library Endpoints ---\n\n@router.get(\"/agents/user/agents\")\nasync def get_user_agents():\n    return await proxy_request(\"GET\", \"/agents/user/agents\")\n\n@router.get(\"/agents/templates/agents\")\nasync def get_template_agents():\n    return await proxy_request(\"GET\", \"/agents/templates/agents\")\n\n@router.get(\"/agents/featured/agents\")\nasync def get_featured_agents():\n    return await proxy_request(\"GET\", \"/agents/featured/agents\")\n\n@router.post(\"/agents/suggest\")\nasync def get_suggested_agents(request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", \"/agents/suggest\", payload=payload)\n\n@router.post(\"/agents\")\nasync def create_agent(request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", \"/agents\", payload=payload)\n\n# --- Agent Detail & Chat Endpoints ---\n@router.get(\"/agents/skills\")\nasync def get_agent_skills():\n    return await proxy_request(\"GET\", f\"/agents/skills\")\n\n@router.get(\"/agents/by-slug/{slug}\")\nasync def get_agent_by_slug(slug: str):\n    return await proxy_request(\"GET\", f\"/agents/by-slug/{slug}\")\n\n@router.get(\"/agents/{slug}/profile\")\nasync def get_agent_profile(slug: str):\n    return await proxy_request(\"GET\", f\"/agents/{slug}/profile\")\n\n@router.put(\"/agents/by-slug/{slug}\")\nasync def update_agent_by_slug(slug: str, request: Request):\n    payload = await request.json()\n    return await proxy_request(\"PUT\", f\"/agents/by-slug/{slug}\", payload=payload)\n\n@router.post(\"/agents/by-slug/{slug}/chat\")\nasync def agent_chat(slug: str, request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", f\"/agents/by-slug/{slug}/chat\", payload=payload)\n\n@router.post(\"/agents/by-slug/{slug}/like\")\nasync def like_agent(slug: str, request: Request):\n    params = dict(request.query_params)\n    return await proxy_request(\"POST\", f\"/agents/by-slug/{slug}/like\", params=params)\n\n@router.get(\"/agents/by-slug/{slug}/{conv_id}\")\nasync def get_conversation_history(slug: str, conv_id: str):\n    return await proxy_request(\"GET\", f\"/agents/by-slug/{slug}/{conv_id}\")\n\n@router.post(\"/agents/by-slug/{slug}/preview-realign\")\nasync def get_agent_preview(slug: str, request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", f\"/agents/by-slug/{slug}/preview-realign\", payload=payload)\n\n# --- Prediction & Image Gen Endpoints ---\n\n@router.get(\"/api/v1/predictions/{request_id}/result\")\nasync def get_prediction_result(request_id: str):\n    return await proxy_request(\"GET\", f\"/api/v1/predictions/{request_id}/result\")\n\n@router.post(\"/api/v1/flux-schnell-image\")\nasync def generate_flux_image(request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", \"/api/v1/flux-schnell-image\", payload=payload)\n\n# --- App & Workflow Utilities ---\n\n@router.get(\"/app/get_file_upload_url\")\nasync def get_upload_url(request: Request):\n    params = dict(request.query_params)\n    return await proxy_request(\"GET\", \"/app/get_file_upload_url\", params=params)\n\n@router.post(\"/workflow/cloudfront-signed-url\")\nasync def get_signed_url(request: Request):\n    payload = await request.json()\n    return await proxy_request(\"POST\", \"/workflow/cloudfront-signed-url\", payload=payload)\n\n"
  },
  {
    "path": "server/app/utils/agent_helper.py",
    "content": "import os\nimport httpx\nimport logging\nfrom fastapi import HTTPException\nfrom typing import Optional\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nMUAPI_BASE_URL = os.getenv(\"MUAPI_BASE_URL\", \"https://api.muapi.ai\")\n\nasync def get_api_key():\n    api_key = os.getenv(\"MU_API_KEY\")\n    if not api_key:\n        raise HTTPException(status_code=400, detail=\"Setup MU_API_KEY in .env to be able to use the agent library\")\n    return api_key\n\nasync def proxy_request(method: str, path: str, payload: Optional[dict] = None, params: Optional[dict] = None):\n    api_key = await get_api_key()\n    url = f\"{MUAPI_BASE_URL}/{path.lstrip('/')}\"\n    \n    headers = {\n        \"Content-Type\": \"application/json\",\n        \"x-api-key\": api_key,\n    }\n\n    async with httpx.AsyncClient() as client:\n        try:\n            response = await client.request(\n                method=method,\n                url=url,\n                json=payload,\n                params=params,\n                headers=headers,\n                timeout=60.0\n            )\n            \n            # For JSON responses, return the parsed data\n            if \"application/json\" in response.headers.get(\"content-type\", \"\"):\n                return response.json()\n            else:\n                # Fallback for other content types\n                return response.content\n                \n        except httpx.RequestError as e:\n            logger.error(f\"Request error: {e}\")\n            raise HTTPException(status_code=500, detail=f\"Error contacting MuAPI: {e}\")\n        except Exception as e:\n            logger.error(f\"Unexpected error: {e}\")\n            raise HTTPException(status_code=500, detail=str(e))\n"
  },
  {
    "path": "server/requirements.txt",
    "content": "fastapi\nuvicorn\nsqlalchemy\nasyncpg\nhttpx\npython-dotenv\nruff\n"
  }
]