Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,401 changes: 849 additions & 552 deletions webapp/_webapp/bun.lock

Large diffs are not rendered by default.

88 changes: 41 additions & 47 deletions webapp/_webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,65 +23,59 @@
},
"dependencies": {
"@buf/googleapis_googleapis.bufbuild_es": "^2.2.3-20250211200939-546238c53f73.1",
"@bufbuild/protobuf": "^2.5.1",
"@capacitor-community/apple-sign-in": "^7.0.1",
"@grafana/faro-web-sdk": "^2.0.2",
"@grafana/faro-web-tracing": "^2.0.2",
"@heroui/react": "^2.7.9",
"@iconify/react": "^6.0.0",
"@bufbuild/protobuf": "^2.11.0",
"@grafana/faro-web-sdk": "^2.2.4",
"@grafana/faro-web-tracing": "^2.2.4",
"@heroui/react": "2.8.9",
"@iconify/react": "^6.0.2",
"@lukemorales/query-key-factory": "^1.3.4",
"@r2wc/react-to-web-component": "^2.1.0",
"@streamdown/cjk": "^1.0.1",
"@streamdown/code": "^1.0.1",
"@streamdown/math": "^1.0.1",
"@streamdown/mermaid": "^1.0.1",
"@tanstack/react-query": "^5.79.0",
"@streamdown/cjk": "^1.0.2",
"@streamdown/code": "^1.0.2",
"@streamdown/math": "^1.0.2",
"@streamdown/mermaid": "^1.0.2",
"@tailwindcss/postcss": "^4.2.0",
"@tailwindcss/vite": "^4.2.0",
"@tanstack/react-query": "^5.90.21",
"@types/diff": "^8.0.0",
"@uidotdev/usehooks": "^2.4.1",
"axios": "^1.9.0",
"baseline-browser-mapping": "^2.9.12",
"caniuse-lite": "^1.0.30001762",
"diff": "^8.0.2",
"axios": "^1.13.5",
"diff": "^8.0.3",
"events": "^3.3.0",
"framer-motion": "^12.15.0",
"framer-motion": "12.34.2",
"highlight.js": "^11.11.1",
"immer": "^10.1.1",
"jszip": "^3.10.1",
"markdown-to-jsx": "^7.7.6",
"openai": "^5.0.1",
"postcss": "^8.5.4",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"immer": "11.1.4",
"react": "19.2.4",
"react-dom": "19.2.4",
"react-rnd": "^10.5.2",
"semver": "^7.7.2",
"streamdown": "^2.1.0",
"uuid": "^11.1.0",
"zustand": "^5.0.5"
"semver": "^7.7.4",
"streamdown": "^2.2.0",
"tailwindcss": "^4.2.0",
"tw-shimmer": "^0.4.6",
"uuid": "^13.0.0",
"zustand": "^5.0.11"
},
"devDependencies": {
"@codemirror/state": "^6.5.2",
"@codemirror/view": "^6.37.1",
"@eslint/js": "^9.28.0",
"@grafana/faro-rollup-plugin": "^0.7.0",
"@types/bun": "^1.3.5",
"@codemirror/state": "^6.5.4",
"@codemirror/view": "^6.39.14",
"@eslint/js": "^10.0.1",
"@grafana/faro-rollup-plugin": "^0.8.2",
"@types/bun": "^1.3.9",
"@types/chrome": "^0.0.326",
"@types/codemirror": "^5.60.16",
"@types/codemirror": "^5.60.17",
"@types/events": "^3.0.3",
"@types/node": "^22.15.29",
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.5",
"@types/semver": "^7.7.0",
"@vitejs/plugin-react-swc": "^3.10.0",
"autoprefixer": "^10.4.21",
"@types/node": "^25.2.3",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/semver": "^7.7.1",
"@vitejs/plugin-react-swc": "^4.2.3",
"eslint": "^9.28.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.2.0",
"nodemon": "^3.1.10",
"prettier": "3.5.3",
"tailwindcss": "^3.4.17",
"typescript": "~5.8.3",
"typescript-eslint": "^8.33.0",
"vite": "^6.3.5"
"globals": "^17.3.0",
"nodemon": "^3.1.11",
"prettier": "3.8.1",
"typescript": "~5.9.3",
"typescript-eslint": "^8.56.0",
"vite": "^7.3.1"
}
}
3 changes: 1 addition & 2 deletions webapp/_webapp/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
"@tailwindcss/postcss": {},
},
};
2 changes: 1 addition & 1 deletion webapp/_webapp/src/components/cell-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const CellWrapper = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDi
<div
ref={ref}
className={cn(
"flex items-center justify-between gap-2 rounded-medium bg-content2 !p-2 !pr-[12px] !pl-[20px]",
"flex items-center justify-between gap-2 rounded-medium bg-content2 p-2! pr-[12px]! pl-[20px]!",
className,
)}
{...props}
Expand Down
2 changes: 1 addition & 1 deletion webapp/_webapp/src/components/code-block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const CodeBlock = ({ code, className }: CodeBlockProps) => {

return (
<pre
className={`p-2 rounded-md bg-gray-200 dark:!bg-default-200 text-sm text-wrap break-words ${className}`}
className={`p-2 rounded-md bg-gray-200 dark:!bg-default-200 text-sm text-wrap wrap-break-word ${className}`}
dangerouslySetInnerHTML={{ __html: highlightedCode }}
/>
);
Expand Down
20 changes: 1 addition & 19 deletions webapp/_webapp/src/components/loading-indicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,6 @@ interface LoadingIndicatorProps {
// Constants
// ============================================================================

const STYLES = {
loading: {
animation: {
WebkitTextFillColor: "transparent",
animationDelay: "0.5s",
animationDuration: "3s",
animationIterationCount: "infinite",
animationName: "shimmer",
background: "#cdcdcd -webkit-gradient(linear, 100% 0, 0 0, from(#cdcdcd), color-stop(.5, #1a1a1a), to(#cdcdcd))",
WebkitBackgroundClip: "text",
backgroundRepeat: "no-repeat",
backgroundSize: "50% 200%",
backgroundPositionX: "-100%",
},
},
} as const;

const PHASE_STYLES = {
green: {
background: "linear-gradient(90deg, #35aa6b 0%, #7cc89f 100%)",
Expand Down Expand Up @@ -170,8 +153,7 @@ export const LoadingIndicator = ({ text = "Thinking", estimatedSeconds = 0, erro
<div className="indicator">
{/* Status Text */}
<div
className={`flex space-x-1 text-xs ${!isTimeout && !errorMessage ? "loading-shimmer" : ""}`}
style={!isTimeout && !errorMessage ? STYLES.loading.animation : undefined}
className={`flex space-x-1 text-xs ${!isTimeout && !errorMessage ? "shimmer" : ""}`}
>
<span className={isTimeout || errorMessage ? "text-rose-400" : ""}>{getStatusMessage()}</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion webapp/_webapp/src/components/markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface MarkdownComponentProps {
const MarkdownComponent = memo(({ children, animated }: MarkdownComponentProps) => {
return (
<Streamdown
className="space-y-1 leading-[1.50]"
className="space-y-1 leading-normal"
shikiTheme={["github-light", "ayu-dark"]}
components={{
h1: ({ children }) => (
Expand Down
14 changes: 7 additions & 7 deletions webapp/_webapp/src/components/message-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@ import { DisplayMessage } from "../stores/types";
// Constants
export const STYLES = {
container: {
base: "!flex !flex-row !gap-2",
base: "flex! flex-row! gap-2!",
assistant: "",
indicator: "",
},
messageWrapper: {
base: "!max-w-full !flex !flex-col !gap-4",
assistant: "!max-w-[100%]",
user: "!max-w-[70%]",
indicator: "!w-full",
base: "max-w-full! flex! flex-col! gap-4!",
assistant: "max-w-full!",
user: "max-w-[70%]!",
indicator: "w-full!",
},
messageBox: {
base: cn(),
assistant: "px-3 pt-3 pb-1 my-2 !border !border-transparent",
assistant: "px-3 pt-3 pb-1 my-2 border! border-transparent!",
user: "px-3 py-2 bg-gray-100 dark:!bg-default-200 self-end my-2",
indicator: "px-3",
},
attachment: {
content: "!max-w-[300px] !bg-default-100 dark:!bg-default-100",
content: "max-w-[300px]! !bg-default-100 dark:!bg-default-100",
text: "!text-tiny !text-default-400",
},
} as const;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { cn, Tooltip } from "@heroui/react";
import { GeneralToolCard } from "./tools/general";
import { useCallback, useEffect, useMemo, useState } from "react";
import googleAnalytics from "../../libs/google-analytics";
import { getProjectId } from "../../libs/helpers";
import googleAnalytics from "@/libs/google-analytics";
import { getProjectId } from "@/libs/helpers";
import MarkdownComponent from "../markdown";
import { TextPatches } from "../text-patches";
import { useAuthStore } from "../../stores/auth-store";
import { useAuthStore } from "@/stores/auth-store";
import { Icon } from "@iconify/react/dist/iconify.js";

// Helper functions
Expand Down Expand Up @@ -96,11 +96,11 @@ export const AssistantMessageContainer = ({
<Icon
icon="tabler:pencil"
className={cn(
"!w-4 !h-4 !text-[14px] !text-gray-400 !animate-bounce",
"!transition-all !duration-300 !ease-in-out",
"!inline-block !align-middle !ml-1",
preparing && "!opacity-100",
!preparing && "!opacity-0 !hidden",
"w-4! h-4! text-[14px]! text-gray-400! animate-bounce!",
"transition-all! duration-300! ease-in-out!",
"inline-block! align-middle! ml-1!",
preparing && "opacity-100!",
!preparing && "opacity-0! hidden!",
)}
/>
);
Expand All @@ -118,7 +118,7 @@ export const AssistantMessageContainer = ({
return (
showMessage && (
<div className="chat-message-entry noselect">
<div className={cn("message-box-assistant rnd-cancel", messageId.startsWith("error-") && "!text-red-500")}>
<div className={cn("message-box-assistant rnd-cancel", messageId.startsWith("error-") && "text-red-500!")}>
{/* Reasoning content */}
{reasoningComponent}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { STYLES } from "../message-card";

// Components
export const AttachmentPopover = ({ attachment }: { attachment: string }) => (
<Popover placement="bottom" showArrow={true} className="!mt-1">
<PopoverTrigger className="bg-gray-200 dark:!bg-default-200 !rounded-xl !flex !w-fit mt-1 noselect">
<span className="!text-xs !text-gray-400 dark:text-default-500 border !border-gray-300 dark:!border-default-300 !rounded-lg !px-1">
<Popover placement="bottom" showArrow={true} className="mt-1!">
<PopoverTrigger className="bg-gray-200 dark:!bg-default-200 rounded-xl! flex! w-fit! mt-1 noselect">
<span className="text-xs! text-gray-400! dark:text-default-500 border border-gray-300! dark:!border-default-300 rounded-lg! px-1!">
attachment
</span>
</PopoverTrigger>
<PopoverContent className={STYLES.attachment.content}>
<div className="!px-1 !py-2" style={{ overflowWrap: "anywhere" }}>
<div className="px-1! py-2!" style={{ overflowWrap: "anywhere" }}>
<div className={STYLES.attachment.text}>{attachment}</div>
</div>
</PopoverContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,7 @@ export const ToolCallPrepareMessageContainer = ({
return (
<div className="chat-message-entry">
<span
className="text-xs pl-2 text-gray-400 loading-shimmer"
style={{
WebkitTextFillColor: "transparent",
animationDelay: "0.5s",
animationDuration: "3s",
animationIterationCount: "infinite",
animationName: "shimmer",
background:
"#cdcdcd -webkit-gradient(linear, 100% 0, 0 0, from(#cdcdcd), color-stop(.5, #1a1a1a), to(#cdcdcd))",
WebkitBackgroundClip: "text",
backgroundRepeat: "no-repeat",
backgroundSize: "50% 200%",
backgroundPositionX: "-100%",
}}
>
className="text-xs pl-2 text-gray-400 shimmer">
Preparing function {functionName}...
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoadingIndicator } from "../../loading-indicator";
import { LoadingIndicator } from "@/components/loading-indicator";
import { cn } from "@heroui/react";
import { ErrorToolCard } from "./error";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,6 @@ type GeneralToolCardProps = {
isLoading?: boolean;
};

const shimmerStyle = {
WebkitTextFillColor: "transparent",
animationDelay: "0.5s",
animationDuration: "3s",
animationIterationCount: "infinite",
animationName: "shimmer",
background: "#cdcdcd -webkit-gradient(linear, 100% 0, 0 0, from(#cdcdcd), color-stop(.5, #1a1a1a), to(#cdcdcd))",
WebkitBackgroundClip: "text",
backgroundRepeat: "no-repeat",
backgroundSize: "50% 200%",
backgroundPositionX: "-100%",
} as const;

export const GeneralToolCard = ({
functionName,
message,
Expand Down Expand Up @@ -74,7 +61,7 @@ export const GeneralToolCard = ({
if (!message) {
return (
<div className="chat-message-entry">
<span className="text-sm text-gray-400 loading-shimmer" style={shimmerStyle}>
<span className="text-sm text-gray-400 shimmer">
Calling tool {functionName}...
</span>
</div>
Expand Down Expand Up @@ -111,7 +98,7 @@ export const GeneralToolCard = ({
aria-label={isCollapsed ? "Expand" : "Collapse"}
>
<svg
className={cn("w-3 h-3 transition-transform duration-200 rotate-[-90deg]", {
className={cn("w-3 h-3 transition-transform duration-200 -rotate-90", {
"rotate-0": !isCollapsed,
})}
fill="none"
Expand All @@ -121,10 +108,7 @@ export const GeneralToolCard = ({
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
<h3
className={cn("tool-card-title", isLoading && "loading-shimmer")}
style={isLoading ? shimmerStyle : undefined}
>
<h3 className={cn("tool-card-title", isLoading && "shimmer")}>
{pascalCase(functionName)}
</h3>
</div>
Expand All @@ -136,7 +120,7 @@ export const GeneralToolCard = ({
<div className="overflow-hidden">
<div
className={cn(
"canselect rounded-md !border px-2 py-1 mt-1 transition-opacity duration-200 relative",
"canselect rounded-md border! px-2 py-1 mt-1 transition-opacity duration-200 relative",
isCollapsed ? "opacity-0" : "opacity-100",
)}
style={{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LoadingIndicator } from "../../loading-indicator";
import { LoadingIndicator } from "@/components/loading-indicator";
import { cn } from "@heroui/react";

type GreetingCardProps = {
Expand Down
Loading