# Project export: Mentora

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 12.0
- Tagline: Rewriting the stereotypes of AI with a human-first mentor built to assist you live a better life.
- Devpost: https://devpost.com/software/planevent
- GitHub: https://github.com/EugeneVuong/calhacks12
- Video: https://www.youtube.com/embed/CDGuY-KRXOc?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Result: winner (Letta: Honorable Mention)
- Team: 2 GitHub contributor(s) — Eugene Vuong (16 commits), aneesh-pradhan (2 commits)

## Devpost submission (written by the team)

### Inspiration

"You can learn everything." The direction of AI has been taken down a darker path for a tool originally intended to act as an intelligent computer that aids humans. Tools such as interview cheating assistants or deepfake content generators used to slander others or spread misinformation have slowly started gaining traction and set a scary precedent for the future of AI. Our team wanted to look at ways to give AI a more human-supportive viewpoint. We reflected on our own struggles, and felt that habits are difficult to form. This gave way to Mentora, our project built to help anyone build stronger habits. AI can be a great assistant when prompted correctly. You can ask it for advice, have it generate schedules for you, and can even provide words of support. We utilize this quality of LLMs to create an application that gives users an easy way to interface with AI to build strong habits, tying together multiple strategies and tools.

### What it does

Mentora comprises of a dashboard with a live assistant, skill trees and various skills a user can choose to develop or strengthen. Skill tree roadmaps are generated stemming from the goals or habits the user chooses. We make use of Letta to create a persistent memory for the AI assistant that collects data trends and uses them to craft responses or provide suggestions.

### How we built it

Our project relies mainly on Letta as the backbone. We use TypeScript for the front end and various AI LLMs such as Claude for the brains behind the agent.

### Accomplishments we're proud of

We were able to learn the ins and outs of Letta within a very short time frame and fully implement it within our project, creating an end product very close to prod-level.

### What's next

We want to continue building Mentora to iron out the early-stage code bugs and to add on more features, along with developing it for more platforms such as a mobile web-app capable of sending notifications along with setting calendar reminders.

## README (from the GitHub repository)

# Mentora
Your AI assistant designed to help you build stronger, healthier habits.

# Screenshots

# Setup
Add here

# Project Structure

Add here


## Detected evidence (automated analysis)

Indexed codebase: 84 recognized source files, 302 KB.
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- Firebase (technology) — detected in the code
- Flask (technology) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Vercel AI SDK (technology) — detected in the code

## Codebase structure (from repository index)

### Files (95 of 95)

```
.DS_Store
backend/.env
backend/.env.example
backend/poetry.lock
backend/pyproject.toml
backend/src/backend/__init__.py
backend/src/backend/voice_agent/README.md
backend/tests/__init__.py
frontend/.gitignore
frontend/components.json
frontend/eslint.config.mjs
frontend/next.config.ts
frontend/package.json
frontend/postcss.config.mjs
frontend/README.md
frontend/src/app/api/letta/route.ts
frontend/src/app/chat/page.tsx
frontend/src/app/globals.css
frontend/src/app/layout.tsx
frontend/src/app/page.tsx
frontend/src/components/app-sidebar.tsx
frontend/src/components/chart-area-interactive.tsx
frontend/src/components/chatbox/chat-input.tsx
frontend/src/components/chatbox/chat.tsx
frontend/src/components/chatbox/index.tsx
frontend/src/components/data-table.tsx
frontend/src/components/goals-stats-cards.tsx
frontend/src/components/goals/index.tsx
frontend/src/components/goals/react-flow-skill-tree.tsx
frontend/src/components/goals/skill-tree.tsx
frontend/src/components/goals/stats-cards.tsx
frontend/src/components/letta-test.tsx
frontend/src/components/page-header.tsx
frontend/src/components/section-cards.tsx
frontend/src/components/sidebar/app-sidebar.tsx
frontend/src/components/sidebar/index.tsx
frontend/src/components/sidebar/nav-main.tsx
frontend/src/components/sidebar/nav-user.tsx
frontend/src/components/site-header.tsx
frontend/src/components/streaming-test.tsx
frontend/src/components/ui/avatar.tsx
frontend/src/components/ui/badge.tsx
frontend/src/components/ui/breadcrumb.tsx
frontend/src/components/ui/button.tsx
frontend/src/components/ui/card.tsx
frontend/src/components/ui/carousel.tsx
frontend/src/components/ui/chart.tsx
frontend/src/components/ui/checkbox.tsx
frontend/src/components/ui/collapsible.tsx
frontend/src/components/ui/command.tsx
frontend/src/components/ui/dialog.tsx
frontend/src/components/ui/drawer.tsx
frontend/src/components/ui/dropdown-menu.tsx
frontend/src/components/ui/field.tsx
frontend/src/components/ui/hover-card.tsx
frontend/src/components/ui/input-group.tsx
frontend/src/components/ui/input.tsx
frontend/src/components/ui/label.tsx
frontend/src/components/ui/popover.tsx
frontend/src/components/ui/resizable.tsx
frontend/src/components/ui/scroll-area.tsx
frontend/src/components/ui/select.tsx
frontend/src/components/ui/separator.tsx
frontend/src/components/ui/shadcn-io/ai/actions.tsx
frontend/src/components/ui/shadcn-io/ai/branch.tsx
frontend/src/components/ui/shadcn-io/ai/conversation.tsx
frontend/src/components/ui/shadcn-io/ai/image.tsx
frontend/src/components/ui/shadcn-io/ai/inline-citation.tsx
frontend/src/components/ui/shadcn-io/ai/loader.tsx
frontend/src/components/ui/shadcn-io/ai/message.tsx
frontend/src/components/ui/shadcn-io/ai/prompt-input.tsx
frontend/src/components/ui/shadcn-io/ai/reasoning.tsx
frontend/src/components/ui/shadcn-io/ai/response.tsx
frontend/src/components/ui/shadcn-io/ai/source.tsx
frontend/src/components/ui/shadcn-io/ai/suggestion.tsx
frontend/src/components/ui/shadcn-io/ai/task.tsx
frontend/src/components/ui/shadcn-io/ai/tool.tsx
frontend/src/components/ui/shadcn-io/ai/web-preview.tsx
frontend/src/components/ui/shadcn-io/code-block/index.tsx
frontend/src/components/ui/shadcn-io/code-block/server.tsx
frontend/src/components/ui/sheet.tsx
frontend/src/components/ui/sidebar.tsx
frontend/src/components/ui/skeleton.tsx
frontend/src/components/ui/sonner.tsx
frontend/src/components/ui/switch.tsx
frontend/src/components/ui/table.tsx
frontend/src/components/ui/tabs.tsx
frontend/src/components/ui/textarea.tsx
frontend/src/components/ui/toggle-group.tsx
frontend/src/components/ui/toggle.tsx
frontend/src/components/ui/tooltip.tsx
frontend/src/hooks/use-mobile.ts
frontend/src/lib/utils.ts
frontend/tsconfig.json
README.md
```

### Dependencies

- backend/pyproject.toml: fastapi@(>=0.104.0,<1.0.0), flask@(>=3.1.2,<4.0.0), flask-cors@(>=4.0.0,<5.0.0), httpx@(>=0.25.0,<1.0.0), letta-client@(>=0.1.324,<0.2.0), livekit@(>=1.0.17,<2.0.0), livekit-agents@(>=1.2.15,<2.0.0), livekit-agents[openai]@(>=1.2,<2.0), livekit-api@(>=1.0.7,<2.0.0), livekit-plugins-deepgram@(>=1.2.15,<2.0.0), livekit-plugins-tavus@(>=1.2.15,<2.0.0), openai@(>=2.6.1,<3.0.0), pydantic@(>=2.0.0,<3.0.0), python-dotenv@(>=1.1.1,<2.0.0), requests@(>=2.32.5,<3.0.0), uvicorn@(>=0.24.0,<1.0.0)
- frontend/package.json: @dagrejs/dagre@^1.1.5, @dnd-kit/core@^6.3.1, @dnd-kit/modifiers@^9.0.0, @dnd-kit/sortable@^10.0.0, @dnd-kit/utilities@^3.2.2, @icons-pack/react-simple-icons@^13.8.0, @letta-ai/vercel-ai-sdk-provider@^1.3.0, @radix-ui/react-avatar@^1.1.10, @radix-ui/react-checkbox@^1.3.3, @radix-ui/react-collapsible@^1.1.12, @radix-ui/react-dialog@^1.1.15, @radix-ui/react-dropdown-menu@^2.1.16, @radix-ui/react-hover-card@^1.1.15, @radix-ui/react-label@^2.1.7, @radix-ui/react-popover@^1.1.15, @radix-ui/react-scroll-area@^1.2.10, @radix-ui/react-select@^2.2.6, @radix-ui/react-separator@^1.1.7, @radix-ui/react-slot@^1.2.3, @radix-ui/react-switch@^1.2.6, @radix-ui/react-tabs@^1.1.13, @radix-ui/react-toggle@^1.1.10, @radix-ui/react-toggle-group@^1.1.11, @radix-ui/react-tooltip@^1.2.8, @radix-ui/react-use-controllable-state@^1.2.2, @shikijs/transformers@^3.13.0, @tabler/icons-react@^3.35.0, @tailwindcss/postcss@^4, @tanstack/react-table@^8.21.3, @types/node@^20, @types/react@^19, @types/react-dom@^19, @types/react-syntax-highlighter@^15.5.13, @xyflow/react@^12.9.0, ai@^5.0.78, beautiful-skill-tree@^1.7.1, class-variance-authority@^0.7.1, clsx@^2.1.1, cmdk@^1.1.1, embla-carousel-react@^8.6.0, eslint@^9, eslint-config-next@16.0.0, firebase@^12.4.0, harden-react-markdown@^1.1.5, katex@^0.16.25, lucide-react@^0.548.0, next@16.0.0, next-themes@^0.4.6, react@19.2.0, react-dom@19.2.0, react-markdown@^10.1.0, react-resizable-panels@^3.0.6, react-syntax-highlighter@^16.0.0, recharts@^2.15.4, rehype-katex@^7.0.1, remark-gfm@^4.0.1, remark-math@^6.0.0, shiki@^3.13.0, sonner@^2.0.7, tailwind-merge@^3.3.1, tailwindcss@^4, tw-animate-css@^1.4.0, typescript@^5, use-stick-to-bottom@^1.1.1, vaul@^1.1.2, zod@^3.25.76

### Recent commits (newest first)

- Issue #2: I am so tired lol
- Issue #6: Implemented the Finalized Agent
- Issue #6: Implemented AI Agent
- Issue #1 #2: Implement Backend and Frontend Code
- Merge branch 'main' of github.com:EugeneVuong/calhacks12
- Issue #6: Implemeted Skill Tree Agent
- Add description and sections to README.md
- Add initial README with project title
- Issue #2: Bruh
- Issue #2: Updated Backend
- Initial commit
- Issue #1: Implement Skill Tree
- Issue #1: Implemented Chat Streaming the UI
- Issue #1 #2: Implemented Changes
- Issue #1: New Frontend Componenets
- Issue #3: Implemented Agent Code
- Issue #1: Fixed Frontend Code to Make it More Repsonsive
- Issue #1 #2: Implement the Backend Initalization and Frontend Code
- Merge branch 'main' of github.com:EugeneVuong/calhacks12
- Issue #1 #2: Implement the Backend Initalization and Frontend Code

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/pyproject.toml

```
[project]
name = "backend"
version = "0.1.0"
description = ""
authors = [
    {name = "Eugene Vuong",email = "vuongeugene@gmail.com"}
]
readme = "README.md"
requires-python = ">=3.11,<4.0"
dependencies = [
    "python-dotenv (>=1.1.1,<2.0.0)",
    "livekit-api (>=1.0.7,<2.0.0)",
    "livekit-plugins-tavus (>=1.2.15,<2.0.0)",
    "livekit-agents (>=1.2.15,<2.0.0)",
    "livekit (>=1.0.17,<2.0.0)",
    "letta-client (>=0.1.324,<0.2.0)",
    "livekit-plugins-deepgram (>=1.2.15,<2.0.0)",
    "livekit-agents[openai] (>=1.2,<2.0)",
    "httpx (>=0.25.0,<1.0.0)",
    "requests (>=2.32.5,<3.0.0)",
    "openai (>=2.6.1,<3.0.0)",
    "fastapi (>=0.104.0,<1.0.0)",
    "uvicorn (>=0.24.0,<1.0.0)",
    "pydantic (>=2.0.0,<3.0.0)",
    "flask (>=3.1.2,<4.0.0)",
    "flask-cors (>=4.0.0,<5.0.0)"
]

[tool.poetry]
packages = [{include = "backend", from = "src"}]


[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

```

### frontend/package.json

```
{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
  },
  "dependencies": {
    "@dagrejs/dagre": "^1.1.5",
    "@dnd-kit/core": "^6.3.1",
    "@dnd-kit/modifiers": "^9.0.0",
    "@dnd-kit/sortable": "^10.0.0",
    "@dnd-kit/utilities": "^3.2.2",
    "@icons-pack/react-simple-icons": "^13.8.0",
    "@letta-ai/vercel-ai-sdk-provider": "^1.3.0",
    "@radix-ui/react-avatar": "^1.1.10",
    "@radix-ui/react-checkbox": "^1.3.3",
    "@radix-ui/react-collapsible": "^1.1.12",
    "@radix-ui/react-dialog": "^1.1.15",
    "@radix-ui/react-dropdown-menu": "^2.1.16",
    "@radix-ui/react-hover-card": "^1.1.15",
    "@radix-ui/react-label": "^2.1.7",
    "@radix-ui/react-popover": "^1.1.15",
    "@radix-ui/react-scroll-area": "^1.2.10",
    "@radix-ui/react-select": "^2.2.6",
    "@radix-ui/react-separator": "^1.1.7",
    "@radix-ui/react-slot": "^1.2.3",
    "@radix-ui/react-switch": "^1.2.6",
    "@radix-ui/react-tabs": "^1.1.13",
    "@radix-ui/react-toggle": "^1.1.10",
    "@radix-ui/react-toggle-group": "^1.1.11",
    "@radix-ui/react-tooltip": "^1.2.8",
    "@radix-ui/react-use-controllable-state": "^1.2.2",
    "@shikijs/transformers": "^3.13.0",
    "@tabler/icons-react": "^3.35.0",
    "@tanstack/react-table": "^8.21.3",
    "@xyflow/react": "^12.9.0",
    "ai": "^5.0.78",
    "beautiful-skill-tree": "^1.7.1",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "cmdk": "^1.1.1",
    "embla-carousel-react": "^8.6.0",
    "firebase": "^12.4.0",
    "harden-react-markdown": "^1.1.5",
    "katex": "^0.16.25",
    "lucide-react": "^0.548.0",
    "next": "16.0.0",
    "next-themes": "^0.4.6",
    "react": "19.2.0",
    "react-dom": "19.2.0",
    "react-markdown": "^10.1.0",
    "react-resizable-panels": "^3.0.6",
    "react-syntax-highlighter": "^16.0.0",
    "recharts": "^2.15.4",
    "rehype-katex": "^7.0.1",
    "remark-gfm": "^4.0.1",
    "remark-math": "^6.0.0",
    "shiki": "^3.13.0",
    "sonner": "^2.0.7",
    "tailwind-merge": "^3.3.1",
    "use-stick-to-bottom": "^1.1.1",
    "vaul": "^1.1.2",
    "zod": "^3.25.76"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "@types/react-syntax-highlighter": "^15.5.13",
    "eslint": "^9",
    "eslint-config-next": "16.0.0",
    "tailwindcss": "^4",
    "tw-animate-css": "^1.4.0",
    "typescript": "^5"
  }
}

```

### frontend/src/app/layout.tsx

```typescript
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { ResizablePanel } from "@/components/ui/resizable";
import { Sidebar } from "lucide-react";
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
import { AppSidebar } from "@/components/sidebar";
import { Toaster } from "sonner";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <SidebarProvider>
          <AppSidebar />
          <SidebarInset>
            <main className="">{children}</main>
          </SidebarInset>
        </SidebarProvider>
        <Toaster />
      </body>
    </html>
  );
}

```

### frontend/src/app/page.tsx

```typescript
"use client";

import { useState, useCallback } from "react";
import { ChatInput } from "@/components/chatbox/chat-input";
import { generateRoadmap } from "@/lib/api";
import {
  createRoadmap,
  updateRoadmap,
  updateRoadmapError,
  subscribeToRoadmap,
} from "@/lib/roadmap-service";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Loader2 } from "lucide-react";

export default function Home() {
  const [currentMode, setCurrentMode] = useState<string>("Teacher Mode");
  const [isLoading, setIsLoading] = useState(false);
  const router = useRouter();

  const handleSend = useCallback(
    async (text: string) => {
      if (!text.trim() || isLoading) return;

      setIsLoading(true);
      let roadmapId: string | null = null;

      try {
        // Create pending roadmap in Firebase
        roadmapId = await createRoadmap(text);
        toast.info("Generating your learning roadmap...", {
          description:
            "This may take a moment. You can navigate away and we'll notify you when it's ready.",
        });

        // Subscribe to roadmap changes to detect completion
        const unsubscribe = subscribeToRoadmap(roadmapId, (roadmap) => {
          if (roadmap?.status === "completed") {
            toast.success("Roadmap ready!", {
              description:
                "Your learning roadmap has been generated successfully.",
            });
            unsubscribe();
          } else if (roadmap?.status === "error") {
            toast.error("Failed to generate roadmap", {
              description: roadmap.error || "An error occurred",
            });
            unsubscribe();
          }
        });

        // Call backend to generate roadmap
        const result = await generateRoadmap(text);

        // Update Firebase with generated data
        await updateRoadmap(roadmapId, result.nodes, result.edges);

        // Redirect to roadmap page
        router.push(`/roadmap/${roadmapId}`);
      } catch (error) {
        console.error("Error generating roadmap:", error);

        // Update Firebase with error status
        if (roadmapId) {
          await updateRoadmapError(
            roadmapId,
            error instanceof Error
              ? error.message
              : "Failed to generate roadmap"
          );
        }

        toast.error("Failed to generate roadmap", {
          description:
            error instanceof Error
              ? error.message
              : "An error occurred while generating your roadmap",
        });
      } finally {
        setIsLoading(false);
      }
    },
    [isLoading, router]
  );

  const handleModeChange = (mode: string) => {
    setCurrentMode(mode);
  };

  const getTitle = () => {
    if (currentMode === "Teacher Mode") {
      return "Hello! What do you want to learn today?";
    } else if (currentMode === "Mentor Mode") {
      return "Hello! What are going to be checking on today?";
    }
    return "Hello! What do you want to learn today?";
  };

  return (
    <div className="flex flex-col items-center justify-center w-full max-w-3xl mx-auto min-h-screen">
      <h1 className="text-2xl font-bold mb-4">{getTitle()}</h1>
      <div className="w-full relative">
        <ChatInput onSend={handleSend} onModeChange={handleModeChange} />
        {isLoading && (
          <div className="absolute top-2 right-2">
            <Loader2 className="h-4 w-4 animate-spin text-primary" />
          </div>
        )}
      </div>
    </div>
  );
}

```

### frontend/src/components/chatbox/index.tsx

```typescript
export { default } from "./chat";
export { default as Chatbot } from "./chat";

```

### frontend/src/components/sidebar/index.tsx

```typescript
export { AppSidebar } from "./app-sidebar";
export { NavMain } from "./nav-main";
export { NavUser } from "./nav-user";

```

### frontend/src/app/chat/page.tsx

```typescript
import Chatbot from "@/components/chatbox";

export default function Page() {
  return (
    <div className="flex h-screen w-full">
      <Chatbot />
    </div>
  );
}

```

### frontend/src/components/goals/index.tsx

```typescript
export { GoalsStatsCards, StatCard } from "./stats-cards";
export { SkillTree } from "./skill-tree";
export { ReactFlowSkillTree } from "./react-flow-skill-tree";
export type { StatCardData } from "./stats-cards";
export type { SkillNode, SkillLink } from "./skill-tree";

```

### frontend/src/app/api/letta/route.ts

```typescript
import { lettaCloud } from "@letta-ai/vercel-ai-sdk-provider";
import { streamText, tool } from "ai";
import { z } from "zod";
import { NextRequest } from "next/server";

// Define tools that the LLM can call
const tools = {
  weather: tool({
    description: "Get the weather in a location",
    inputSchema: z.object({
      location: z.string().describe("The location to get the weather for"),
    }),
    execute: async ({ location }) => ({
      location,
      temperature: 72 + Math.floor(Math.random() * 21) - 10,
    }),
  }),
};

export async function POST(request: NextRequest) {
  try {
    const { prompt, agentId } = await request.json();

    console.log("Letta API request:", { prompt, agentId });

    if (!prompt) {
      return new Response(JSON.stringify({ error: "Prompt is required" }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
      });
    }

    if (!agentId) {
      return new Response(JSON.stringify({ error: "Agent ID is required" }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
      });
    }

    console.log("Calling Letta streamText...");
    const result = await streamText({
      model: lettaCloud(), // Model configuration (LLM, temperature, etc.) is managed through your Letta agent
      providerOptions: {
        letta: {
          agent: { id: agentId },
        },
      },
      tools,
      prompt: prompt,
    });

    // Create a readable stream
    const stream = new ReadableStream({
      async start(controller) {
        try {
          // Stream text content
          for await (const textPart of result.textStream) {
            console.log("Streaming text part:", textPart);
            const chunk = JSON.stringify({ content: textPart, done: false });
            controller.enqueue(new TextEncoder().encode(`data: ${chunk}\n\n`));
          }

          // Send tool calls if any
          const toolCalls = await result.toolCalls;
          if (toolCalls && toolCalls.length > 0) {
            console.log("Tool calls:", toolCalls);
            const toolCallsChunk = JSON.stringify({
              toolCalls: toolCalls,
              done: false,
            });
            controller.enqueue(
              new TextEncoder().encode(`data: ${toolCallsChunk}\n\n`)
            );
          }

          // Send final chunk
          const finalChunk = JSON.stringify({ content: "", done: true });
          controller.enqueue(
            new TextEncoder().encode(`data: ${finalChunk}\n\n`)
          );
          controller.close();
        } catch (error) {
          console.error("Error in stream:", error);
          const errorChunk = JSON.stringify({
            error: `Streaming error: ${
              error instanceof Error ? error.message : "Unknown error"
            }`,
            done: true,
          });
          controller.enqueue(
            new TextEncoder().encode(`data: ${errorChunk}\n\n`)
          );
          controller.close();
        }
      },
    });

    return new Response(stream, {
      headers: {
        "Content-Type": "text/plain; charset=utf-8",
        "Cache-Control": "no-cache",
        Connection: "keep-alive",
      },
    });
  } catch (error) {
    console.error("Error setting up stream:", error);
    return new Response(
      JSON.stringify({
        error: `Failed to setup stream: ${
          error instanceof Error ? error.message : "Unknown error"
        }`,
      }),
      {
        status: 500,
        headers: { "Content-Type": "application/json" },
      }
    );
  }
}

```

### frontend/src/components/ui/shadcn-io/code-block/server.tsx

```typescript
import {
  transformerNotationDiff,
  transformerNotationErrorLevel,
  transformerNotationFocus,
  transformerNotationHighlight,
  transformerNotationWordHighlight,
} from "@shikijs/transformers";
import type { HTMLAttributes } from "react";
import {
  type BundledLanguage,
  type CodeOptionsMultipleThemes,
  codeToHtml,
} from "shiki";

export type CodeBlockContentProps = HTMLAttributes<HTMLDivElement> & {
  themes?: CodeOptionsMultipleThemes["themes"];
  language?: BundledLanguage;
  children: string;
  syntaxHighlighting?: boolean;
};

export const CodeBlockContent = async ({
  children,
  themes,
  language,
  syntaxHighlighting = true,
  ...props
}: CodeBlockContentProps) => {
  const html = syntaxHighlighting
    ? await codeToHtml(children as string, {
        lang: language ?? "typescript",
        themes: themes ?? {
          light: "vitesse-light",
          dark: "vitesse-dark",
        },
        transformers: [
          transformerNotationDiff({
            matchAlgorithm: "v3",
          }),
          transformerNotationHighlight({
            matchAlgorithm: "v3",
          }),
          transformerNotationWordHighlight({
            matchAlgorithm: "v3",
          }),
          transformerNotationFocus({
            matchAlgorithm: "v3",
          }),
          transformerNotationErrorLevel({
            matchAlgorithm: "v3",
          }),
        ],
      })
    : children;

  return (
    <div
      // biome-ignore lint/security/noDangerouslySetInnerHtml: "Kinda how Shiki works"
      dangerouslySetInnerHTML={{ __html: html }}
      {...props}
    />
  );
};

```

[71 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]