From 6e3ef109954cc7ef5127ccc677a1446ef0799226 Mon Sep 17 00:00:00 2001 From: zahidalidev Date: Mon, 24 Jun 2024 16:24:52 +0500 Subject: [PATCH 01/19] Added Ask Source Graph bot --- src/app/ask-source/page.tsx | 124 +++++++++++++++++++++++ src/components/Layout.tsx | 5 + src/components/icons/SourceGraphIcon.tsx | 49 +++++++++ 3 files changed, 178 insertions(+) create mode 100644 src/app/ask-source/page.tsx create mode 100644 src/components/icons/SourceGraphIcon.tsx diff --git a/src/app/ask-source/page.tsx b/src/app/ask-source/page.tsx new file mode 100644 index 000000000..2457bb13b --- /dev/null +++ b/src/app/ask-source/page.tsx @@ -0,0 +1,124 @@ +'use client'; + +import React, { useState, useEffect, useRef } from 'react'; +import clsx from 'clsx'; +import SourceGraphIcon from '@/components/icons/SourceGraphIcon'; + +interface Message { + sender: 'bot' | 'user'; + text: string; +} + +const AskSourceChat = () => { + const [messages, setMessages] = useState([ + { sender: 'bot', text: 'Hello! How can I help you today?' }, + { sender: 'user', text: 'What is Sourcegraph? What is Sourcegraph? What is Sourcegraph? What is Sourcegraph? What is Sourcegraph?' }, + { sender: 'bot', text: 'Sourcegraph is a code search and intelligence tool. Sourcegraph is a code search and intelligence tool.' } + ]); + const [inputValue, setInputValue] = useState(''); + const [charCount, setCharCount] = useState(0); + const [isLoggedIn, setIsLoggedIn] = useState(true); // Add state for user login + const charLimit = 250; + const messagesEndRef = useRef(null); + + const handleInputChange = (e: React.ChangeEvent) => { + setInputValue(e.target.value); + setCharCount(e.target.value.length); + }; + + const handleSendMessage = () => { + if (inputValue.trim() === '') return; + + setMessages([...messages, { sender: 'user', text: inputValue }]); + setInputValue(''); + setCharCount(0); + + // Dummy bot response + setTimeout(() => { + setMessages(prevMessages => [...prevMessages, { sender: 'bot', text: 'Thank you for your message!' }]); + scrollToBottom(); + }, 1000); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSendMessage(); + } + }; + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }; + + useEffect(() => { + scrollToBottom(); + }, [messages]); + + return ( + <> +
+
+

Ask Sourcegraph

+

Get information faster by asking our AI chatbot assistant.

+
+
+ {messages.map((message, index) => ( +
+ {message.sender === 'bot' && ( +
+
+ +
+
+ )} +
+ {message.text} +
+
+ ))} +
+
+ {!isLoggedIn && ( +
+ +
+ )} +
+
+ + +
+

{charCount}/{charLimit}

+
+
+
+ + ); +}; + +export default AskSourceChat; diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 6afe45b64..b1fe4c290 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -5,6 +5,7 @@ import { Logo } from '@/components/Logo'; import { MobileNavigation } from '@/components/MobileNavigation'; import { Navigation } from '@/components/Navigation'; import { ThemeSelector } from '@/components/ThemeSelector'; +import SourceGraphIcon from '@/components/icons/SourceGraphIcon'; import clsx from 'clsx'; import Link from 'next/link'; import { usePathname } from 'next/navigation'; @@ -68,6 +69,10 @@ function Header() {
+ + + Ask Source + ( + + + + + + + + + + + + + + +); + +export default BotIcon; From e6dce7e2db3497e8af23c4cfb11dc0f199d28bfd Mon Sep 17 00:00:00 2001 From: zahidalidev Date: Thu, 4 Jul 2024 22:16:21 +0500 Subject: [PATCH 02/19] Added ask-source chatbot --- package.json | 12 +- pnpm-lock.yaml | 900 +++++++++++++++++- src/app/ask-source/page.tsx | 129 +-- src/components/chatbot/chat-input.tsx | 75 ++ src/components/chatbot/chat-list.tsx | 23 + .../chatbot/chat-message-actions.tsx | 40 + src/components/chatbot/chat-message.tsx | 77 ++ src/components/chatbot/chatbot-page.tsx | 56 ++ src/components/chatbot/header.tsx | 47 + src/components/chatbot/markdown.tsx | 9 + src/components/chatbot/opening.tsx | 81 ++ src/components/chatbot/prompt-form.tsx | 95 ++ src/components/chatbot/ui/button.tsx | 70 ++ src/components/chatbot/ui/codeblock.tsx | 145 +++ src/components/chatbot/ui/icons.tsx | 339 +++++++ src/components/chatbot/ui/separator.tsx | 32 + src/components/chatbot/ui/textarea.tsx | 23 + src/lib/hooks/use-copy-to-clipboard.tsx | 33 + src/lib/hooks/use-enter-submit.tsx | 23 + src/lib/types.ts | 11 + src/lib/utils.ts | 9 + 21 files changed, 2107 insertions(+), 122 deletions(-) create mode 100644 src/components/chatbot/chat-input.tsx create mode 100644 src/components/chatbot/chat-list.tsx create mode 100644 src/components/chatbot/chat-message-actions.tsx create mode 100644 src/components/chatbot/chat-message.tsx create mode 100644 src/components/chatbot/chatbot-page.tsx create mode 100644 src/components/chatbot/header.tsx create mode 100644 src/components/chatbot/markdown.tsx create mode 100644 src/components/chatbot/opening.tsx create mode 100644 src/components/chatbot/prompt-form.tsx create mode 100644 src/components/chatbot/ui/button.tsx create mode 100644 src/components/chatbot/ui/codeblock.tsx create mode 100644 src/components/chatbot/ui/icons.tsx create mode 100644 src/components/chatbot/ui/separator.tsx create mode 100644 src/components/chatbot/ui/textarea.tsx create mode 100644 src/lib/hooks/use-copy-to-clipboard.tsx create mode 100644 src/lib/hooks/use-enter-submit.tsx create mode 100644 src/lib/types.ts diff --git a/package.json b/package.json index 9d2b68450..0f8e9b439 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,17 @@ "tailwindcss": "^3.3.3", "tailwindcss-animate": "^1.0.7", "typescript": "5.1.6", - "unist-util-visit": "^5.0.0" + "unist-util-visit": "^5.0.0", + "mxcn": "^2.0.0", + "ai": "3.0.16", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-switch": "^1.0.3", + "react-markdown": "^8.0.7", + "react-syntax-highlighter": "^15.5.0", + "react-textarea-autosize": "^8.4.1", + "remark-math": "^5.1.1", + "sonner": "^1.5.0" }, "devDependencies": { "eslint": "8.45.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04c8ebb15..cde9fed92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,12 +23,21 @@ dependencies: '@next/third-parties': specifier: ^14.1.4 version: 14.1.4(next@14.2.3)(react@18.3.1) + '@radix-ui/react-label': + specifier: ^2.0.2 + version: 2.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-select': specifier: ^2.0.0 version: 2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-separator': + specifier: ^1.0.3 + version: 1.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.0.2 version: 1.0.2(@types/react@18.2.20)(react@18.3.1) + '@radix-ui/react-switch': + specifier: ^1.0.3 + version: 1.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) '@tailwindcss/typography': specifier: ^0.5.7 version: 0.5.10(tailwindcss@3.4.0) @@ -44,6 +53,9 @@ dependencies: '@types/react-highlight-words': specifier: ^0.16.4 version: 0.16.7 + ai: + specifier: 3.0.16 + version: 3.0.16(react@18.3.1)(solid-js@1.8.18)(svelte@4.2.18)(vue@3.4.31)(zod@3.23.8) algoliasearch: specifier: ^4.22.1 version: 4.22.1 @@ -80,6 +92,9 @@ dependencies: lucide-react: specifier: ^0.372.0 version: 0.372.0(react@18.3.1) + mxcn: + specifier: ^2.0.0 + version: 2.0.0 next: specifier: ^14.2.3 version: 14.2.3(@opentelemetry/api@1.7.0)(react-dom@18.3.1)(react@18.3.1) @@ -101,6 +116,15 @@ dependencies: react-highlight-words: specifier: ^0.20.0 version: 0.20.0(react@18.3.1) + react-markdown: + specifier: ^8.0.7 + version: 8.0.7(@types/react@18.2.20)(react@18.3.1) + react-syntax-highlighter: + specifier: ^15.5.0 + version: 15.5.0(react@18.3.1) + react-textarea-autosize: + specifier: ^8.4.1 + version: 8.5.3(@types/react@18.2.20)(react@18.3.1) rehype-autolink-headings: specifier: ^7.1.0 version: 7.1.0 @@ -116,12 +140,18 @@ dependencies: remark-gfm: specifier: 3.0.1 version: 3.0.1 + remark-math: + specifier: ^5.1.1 + version: 5.1.1 shiki: specifier: ^0.14.5 version: 0.14.7 simple-functional-loader: specifier: ^1.2.1 version: 1.2.1 + sonner: + specifier: ^1.5.0 + version: 1.5.0(react-dom@18.3.1)(react@18.3.1) tailwind-merge: specifier: ^2.3.0 version: 2.3.0 @@ -334,6 +364,32 @@ packages: engines: {node: '>=10'} dev: false + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + + /@babel/helper-string-parser@7.24.7: + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/parser@7.24.7: + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.7 + dev: false + /@babel/runtime@7.23.6: resolution: {integrity: sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==} engines: {node: '>=6.9.0'} @@ -347,6 +403,15 @@ packages: regenerator-runtime: 0.14.1 dev: false + /@babel/types@7.24.7: + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + dev: false + /@contentlayer/cli@0.3.4(esbuild@0.19.10): resolution: {integrity: sha512-vNDwgLuhYNu+m70NZ3XK9kexKNguuxPXg7Yvzj3B34cEilQjjzSrcTY/i+AIQm9V7uT5GGshx9ukzPf+SmoszQ==} dependencies: @@ -929,6 +994,15 @@ packages: '@jridgewell/trace-mapping': 0.3.20 dev: false + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} @@ -939,6 +1013,11 @@ packages: engines: {node: '>=6.0.0'} dev: false + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: false + /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: false @@ -950,6 +1029,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: false + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + /@js-temporal/polyfill@0.4.4: resolution: {integrity: sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==} engines: {node: '>=12'} @@ -1392,6 +1478,10 @@ packages: '@babel/runtime': 7.24.4 dev: false + /@radix-ui/primitive@1.1.0: + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + dev: false + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} peerDependencies: @@ -1451,6 +1541,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-compose-refs@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-context@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: @@ -1465,6 +1568,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-context@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-direction@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} peerDependencies: @@ -1556,6 +1672,26 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-label@2.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.20 + '@types/react-dom': 18.2.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} peerDependencies: @@ -1628,6 +1764,26 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-primitive@2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@types/react': 18.2.20 + '@types/react-dom': 18.2.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} peerDependencies: @@ -1669,6 +1825,26 @@ packages: react-remove-scroll: 2.5.5(@types/react@18.2.20)(react@18.3.1) dev: false + /@radix-ui/react-separator@1.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.20 + '@types/react-dom': 18.2.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -1684,6 +1860,46 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-slot@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + + /@radix-ui/react-switch@1.1.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@types/react': 18.2.20 + '@types/react-dom': 18.2.7 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: @@ -1698,6 +1914,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: @@ -1713,6 +1942,20 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} peerDependencies: @@ -1742,6 +1985,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} peerDependencies: @@ -1756,6 +2012,19 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-previous@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} peerDependencies: @@ -1786,6 +2055,20 @@ packages: react: 18.3.1 dev: false + /@radix-ui/react-use-size@1.1.0(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.20)(react@18.3.1) + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} peerDependencies: @@ -1856,6 +2139,10 @@ packages: '@types/ms': 0.7.34 dev: false + /@types/diff-match-patch@1.0.36: + resolution: {integrity: sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg==} + dev: false + /@types/estree-jsx@1.0.3: resolution: {integrity: sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==} dependencies: @@ -1882,6 +2169,10 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/katex@0.16.7: + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + dev: false + /@types/mdast@3.0.15: resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} dependencies: @@ -2016,6 +2307,80 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false + /@vue/compiler-core@3.4.31: + resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} + dependencies: + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.31 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + dev: false + + /@vue/compiler-dom@3.4.31: + resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==} + dependencies: + '@vue/compiler-core': 3.4.31 + '@vue/shared': 3.4.31 + dev: false + + /@vue/compiler-sfc@3.4.31: + resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} + dependencies: + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.31 + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.39 + source-map-js: 1.2.0 + dev: false + + /@vue/compiler-ssr@3.4.31: + resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/shared': 3.4.31 + dev: false + + /@vue/reactivity@3.4.31: + resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} + dependencies: + '@vue/shared': 3.4.31 + dev: false + + /@vue/runtime-core@3.4.31: + resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==} + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/shared': 3.4.31 + dev: false + + /@vue/runtime-dom@3.4.31: + resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==} + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/runtime-core': 3.4.31 + '@vue/shared': 3.4.31 + csstype: 3.1.3 + dev: false + + /@vue/server-renderer@3.4.31(vue@3.4.31): + resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==} + peerDependencies: + vue: 3.4.31 + dependencies: + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + vue: 3.4.31(typescript@5.1.6) + dev: false + + /@vue/shared@3.4.31: + resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==} + dev: false + /acorn-jsx@5.3.2(acorn@8.11.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -2028,6 +2393,44 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /ai@3.0.16(react@18.3.1)(solid-js@1.8.18)(svelte@4.2.18)(vue@3.4.31)(zod@3.23.8): + resolution: {integrity: sha512-P6GGUYbE8PDUVeGT9D7tT9nF7lufDjbieZ97YVIVL/eZkGcfXQMvJleO1VzJ1eutoI8f5Llazmhg4K66Gs5q3Q==} + engines: {node: '>=14.6'} + peerDependencies: + react: ^18.2.0 + solid-js: ^1.7.7 + svelte: ^3.0.0 || ^4.0.0 + vue: ^3.3.4 + zod: ^3.0.0 + peerDependenciesMeta: + react: + optional: true + solid-js: + optional: true + svelte: + optional: true + vue: + optional: true + zod: + optional: true + dependencies: + eventsource-parser: 1.1.2 + jsondiffpatch: 0.6.0 + nanoid: 3.3.6 + react: 18.3.1 + secure-json-parse: 2.7.0 + solid-js: 1.8.18 + solid-swr-store: 0.10.7(solid-js@1.8.18)(swr-store@0.10.6) + sswr: 2.0.0(svelte@4.2.18) + svelte: 4.2.18 + swr: 2.2.0(react@18.3.1) + swr-store: 0.10.6 + swrv: 1.0.4(vue@3.4.31) + vue: 3.4.31(typescript@5.1.6) + zod: 3.23.8 + zod-to-json-schema: 3.23.1(zod@3.23.8) + dev: false + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -2116,7 +2519,6 @@ packages: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: dequal: 2.0.3 - dev: true /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} @@ -2246,6 +2648,12 @@ packages: dequal: 2.0.3 dev: true + /axobject-query@4.0.0: + resolution: {integrity: sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==} + dependencies: + dequal: 2.0.3 + dev: false + /b4a@1.6.4: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: true @@ -2370,18 +2778,35 @@ packages: supports-color: 7.2.0 dev: true + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} dev: false + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: false + /character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} dev: false + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: false + /character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} dev: false + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: false + /character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} dev: false @@ -2442,6 +2867,16 @@ packages: engines: {node: '>=6'} dev: false + /code-red@1.0.4: + resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + '@types/estree': 1.0.5 + acorn: 8.11.2 + estree-walker: 3.0.3 + periscopic: 3.1.0 + dev: false + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2466,6 +2901,10 @@ packages: color-string: 1.9.1 dev: true + /comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + dev: false + /comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} dev: false @@ -2475,6 +2914,11 @@ packages: engines: {node: '>= 6'} dev: false + /commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: false + /comment-json@4.2.3: resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} engines: {node: '>= 6'} @@ -2521,6 +2965,14 @@ packages: shebang-command: 2.0.0 which: 2.0.2 + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + dev: false + /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -2632,6 +3084,10 @@ packages: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: false + /diff-match-patch@1.0.5: + resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} + dev: false + /diff@5.1.0: resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} engines: {node: '>=0.3.1'} @@ -2696,6 +3152,11 @@ packages: tapable: 2.2.1 dev: true + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: false + /es-abstract@1.22.3: resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} @@ -3148,6 +3609,10 @@ packages: '@types/unist': 2.0.10 dev: false + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + /estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: @@ -3159,6 +3624,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /eventsource-parser@1.1.2: + resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==} + engines: {node: '>=14.18'} + dev: false + /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -3210,6 +3680,12 @@ packages: dependencies: reusify: 1.0.4 + /fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + dependencies: + format: 0.2.2 + dev: false + /fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} dependencies: @@ -3550,6 +4026,10 @@ packages: '@types/hast': 3.0.3 dev: false + /hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + dev: false + /hast-util-parse-selector@3.1.1: resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} dependencies: @@ -3637,6 +4117,16 @@ packages: resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} dev: false + /hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + dependencies: + '@types/hast': 2.3.9 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + dev: false + /hastscript@7.2.0: resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} dependencies: @@ -3651,6 +4141,10 @@ packages: resolution: {integrity: sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==} dev: false + /highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + dev: false + /html-void-elements@2.0.1: resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} dev: false @@ -3721,10 +4215,21 @@ packages: loose-envify: 1.4.0 dev: false + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: false + /is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} dev: false + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: false + /is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} dependencies: @@ -3794,6 +4299,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: false + /is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} dev: false @@ -3831,6 +4340,10 @@ packages: dependencies: is-extglob: 2.1.1 + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: false + /is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} dev: false @@ -4018,6 +4531,16 @@ packages: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: false + /jsondiffpatch@0.6.0: + resolution: {integrity: sha512-3QItJOXp2AP1uv7waBkao5nCvhEv+QmJAd38Ybq7wNI74Q+BBmnLn4EDKz6yI9xGAIQoUF87qHt+kc1IVxB4zQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + '@types/diff-match-patch': 1.0.36 + chalk: 5.3.0 + diff-match-patch: 1.0.5 + dev: false + /jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -4028,6 +4551,13 @@ packages: object.values: 1.1.7 dev: true + /katex@0.16.11: + resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} + hasBin: true + dependencies: + commander: 8.3.0 + dev: false + /kbar@0.1.0-beta.44(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-hfstBZn/XYhEEobxA6yhMkgu3yHNqAgHbBM/WavC1GvSEMRAVMZAWZBBrNwJCqknSIwu7nS9jsHORENtlrjU1Q==} peerDependencies: @@ -4104,6 +4634,10 @@ packages: json5: 2.2.3 dev: false + /locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + dev: false + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4146,6 +4680,13 @@ packages: tslib: 2.6.2 dev: false + /lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + dev: false + /lru-cache@10.1.0: resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} engines: {node: 14 || >=16.14} @@ -4165,6 +4706,12 @@ packages: react: 18.3.1 dev: false + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + /markdown-extensions@1.1.1: resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} engines: {node: '>=0.10.0'} @@ -4274,6 +4821,14 @@ packages: - supports-color dev: false + /mdast-util-math@2.0.2: + resolution: {integrity: sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ==} + dependencies: + '@types/mdast': 3.0.15 + longest-streak: 3.1.0 + mdast-util-to-markdown: 1.5.0 + dev: false + /mdast-util-mdx-expression@1.3.2: resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} dependencies: @@ -4368,6 +4923,10 @@ packages: '@types/mdast': 3.0.15 dev: false + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: false + /mdx-bundler@9.2.1(esbuild@0.19.10): resolution: {integrity: sha512-hWEEip1KU9MCNqeH2rqwzAZ1pdqPPbfkx9OTJjADqGPQz4t9BO85fhI7AP9gVYrpmfArf9/xJZUN0yBErg/G/Q==} engines: {node: '>=14', npm: '>=6'} @@ -4505,6 +5064,18 @@ packages: micromark-util-types: 1.1.0 dev: false + /micromark-extension-math@2.1.2: + resolution: {integrity: sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg==} + dependencies: + '@types/katex': 0.16.7 + katex: 0.16.11 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: false + /micromark-extension-mdx-expression@1.0.8: resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==} dependencies: @@ -4795,6 +5366,14 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true + /mxcn@2.0.0: + resolution: {integrity: sha512-v7HUffIn60+mllPxuqTzsZxAixpabEwzs/X45InZWOnT+ylJQ55fLADiwudEmqUhqH37PU3OT8mU755XIKgNgg==} + engines: {node: '>=12'} + dependencies: + clsx: 2.0.0 + tailwind-merge: 1.14.0 + dev: false + /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} dependencies: @@ -4803,6 +5382,12 @@ packages: thenify-all: 1.6.0 dev: false + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: false + /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -5054,6 +5639,17 @@ packages: callsites: 3.1.0 dev: true + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: false + /parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} dependencies: @@ -5124,6 +5720,10 @@ packages: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} dev: false + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + dev: false + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -5225,6 +5825,15 @@ packages: source-map-js: 1.0.2 dev: false + /postcss@8.4.39: + resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + dev: false + /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -5317,6 +5926,16 @@ packages: react: 18.3.1 dev: false + /prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + dev: false + + /prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + dev: false + /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -5324,6 +5943,12 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 + /property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + dependencies: + xtend: 4.0.2 + dev: false + /property-information@6.4.0: resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} dev: false @@ -5400,6 +6025,37 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + /react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + dev: false + + /react-markdown@8.0.7(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + dependencies: + '@types/hast': 2.3.9 + '@types/prop-types': 15.7.11 + '@types/react': 18.2.20 + '@types/unist': 2.0.10 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 2.0.1 + prop-types: 15.8.1 + property-information: 6.4.0 + react: 18.3.1 + react-is: 18.3.1 + remark-parse: 10.0.2 + remark-rehype: 10.1.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.4 + unified: 10.1.2 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + transitivePeerDependencies: + - supports-color + dev: false + /react-remove-scroll-bar@2.3.6(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -5452,6 +6108,33 @@ packages: tslib: 2.6.2 dev: false + /react-syntax-highlighter@15.5.0(react@18.3.1): + resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} + peerDependencies: + react: '>= 0.14.0' + dependencies: + '@babel/runtime': 7.24.4 + highlight.js: 10.7.3 + lowlight: 1.20.0 + prismjs: 1.29.0 + react: 18.3.1 + refractor: 3.6.0 + dev: false + + /react-textarea-autosize@8.5.3(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==} + engines: {node: '>=10'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.24.4 + react: 18.3.1 + use-composed-ref: 1.3.0(react@18.3.1) + use-latest: 1.2.1(@types/react@18.2.20)(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + dev: false + /react-virtual@2.10.4(react@18.3.1): resolution: {integrity: sha512-Ir6+oPQZTVHfa6+JL9M7cvMILstFZH/H3jqeYeKI4MSUX+rIruVwFC6nGVXw9wqAw8L0Kg2KvfXxI85OvYQdpQ==} peerDependencies: @@ -5502,6 +6185,14 @@ packages: which-builtin-type: 1.1.3 dev: true + /refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + dev: false + /regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} @@ -5594,6 +6285,15 @@ packages: - supports-color dev: false + /remark-math@5.1.1: + resolution: {integrity: sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw==} + dependencies: + '@types/mdast': 3.0.15 + mdast-util-math: 2.0.2 + micromark-extension-math: 2.1.2 + unified: 10.1.2 + dev: false + /remark-mdx-frontmatter@1.1.1: resolution: {integrity: sha512-7teX9DW4tI2WZkXS4DBxneYSY7NHiXl4AKdWDO9LXVweULlCT8OPWsOjLEnMIXViN1j+QcY8mfbq3k0EK6x3uA==} engines: {node: '>=12.2.0'} @@ -5731,6 +6431,10 @@ packages: kind-of: 6.0.3 dev: false + /secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + dev: false + /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -5743,6 +6447,20 @@ packages: dependencies: lru-cache: 6.0.0 + /seroval-plugins@1.0.7(seroval@1.0.7): + resolution: {integrity: sha512-GO7TkWvodGp6buMEX9p7tNyIkbwlyuAWbI6G9Ec5bhcm7mQdu3JOK1IXbEUwb3FVzSc363GraG/wLW23NSavIw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + dependencies: + seroval: 1.0.7 + dev: false + + /seroval@1.0.7: + resolution: {integrity: sha512-n6ZMQX5q0Vn19Zq7CIKNIo7E75gPkGCFUEqDpa8jgwpYr/vScjqnQ6H09t1uIiZ0ZSK0ypEGvrYK2bhBGWsGdw==} + engines: {node: '>=10'} + dev: false + /set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} engines: {node: '>= 0.4'} @@ -5838,6 +6556,35 @@ packages: engines: {node: '>=8'} dev: true + /solid-js@1.8.18: + resolution: {integrity: sha512-cpkxDPvO/AuKBugVv6xKFd1C9VC0XZMu4VtF56IlHoux8HgyW44uqNSWbozMnVcpIzHIhS3vVXPAVZYM26jpWw==} + dependencies: + csstype: 3.1.3 + seroval: 1.0.7 + seroval-plugins: 1.0.7(seroval@1.0.7) + dev: false + + /solid-swr-store@0.10.7(solid-js@1.8.18)(swr-store@0.10.6): + resolution: {integrity: sha512-A6d68aJmRP471aWqKKPE2tpgOiR5fH4qXQNfKIec+Vap+MGQm3tvXlT8n0I8UgJSlNAsSAUuw2VTviH2h3Vv5g==} + engines: {node: '>=10'} + peerDependencies: + solid-js: ^1.2 + swr-store: ^0.10 + dependencies: + solid-js: 1.8.18 + swr-store: 0.10.6 + dev: false + + /sonner@1.5.0(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /sort-keys@5.0.0: resolution: {integrity: sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==} engines: {node: '>=12'} @@ -5850,6 +6597,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: false + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -5867,6 +6619,10 @@ packages: engines: {node: '>= 8'} dev: false + /space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + dev: false + /space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} dev: false @@ -5875,6 +6631,15 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: false + /sswr@2.0.0(svelte@4.2.18): + resolution: {integrity: sha512-mV0kkeBHcjcb0M5NqKtKVg/uTIYNlIIniyDfSGrSfxpEdM9C365jK0z55pl9K0xAkNTJi2OAOVFQpgMPUk+V0w==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + svelte: 4.2.18 + swrev: 4.0.0 + dev: false + /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -6038,6 +6803,58 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /svelte@4.2.18: + resolution: {integrity: sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==} + engines: {node: '>=16'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.20 + '@types/estree': 1.0.5 + acorn: 8.11.2 + aria-query: 5.3.0 + axobject-query: 4.0.0 + code-red: 1.0.4 + css-tree: 2.3.1 + estree-walker: 3.0.3 + is-reference: 3.0.2 + locate-character: 3.0.0 + magic-string: 0.30.10 + periscopic: 3.1.0 + dev: false + + /swr-store@0.10.6: + resolution: {integrity: sha512-xPjB1hARSiRaNNlUQvWSVrG5SirCjk2TmaUyzzvk69SZQan9hCJqw/5rG9iL7xElHU784GxRPISClq4488/XVw==} + engines: {node: '>=10'} + dependencies: + dequal: 2.0.3 + dev: false + + /swr@2.2.0(react@18.3.1): + resolution: {integrity: sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) + dev: false + + /swrev@4.0.0: + resolution: {integrity: sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA==} + dev: false + + /swrv@1.0.4(vue@3.4.31): + resolution: {integrity: sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==} + peerDependencies: + vue: '>=3.2.26 < 4' + dependencies: + vue: 3.4.31(typescript@5.1.6) + dev: false + + /tailwind-merge@1.14.0: + resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==} + dev: false + /tailwind-merge@2.3.0: resolution: {integrity: sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==} dependencies: @@ -6149,6 +6966,11 @@ packages: resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} dev: false + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: false + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -6414,6 +7236,41 @@ packages: tslib: 2.6.2 dev: false + /use-composed-ref@1.3.0(react@18.3.1): + resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.3.1 + dev: false + + /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + dev: false + + /use-latest@1.2.1(@types/react@18.2.20)(react@18.3.1): + resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.20 + react: 18.3.1 + use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.20)(react@18.3.1) + dev: false + /use-sidecar@1.1.2(@types/react@18.2.20)(react@18.3.1): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} @@ -6430,6 +7287,14 @@ packages: tslib: 2.6.2 dev: false + /use-sync-external-store@1.2.2(react@18.3.1): + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.3.1 + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -6495,6 +7360,22 @@ packages: resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} dev: false + /vue@3.4.31(typescript@5.1.6): + resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-sfc': 3.4.31 + '@vue/runtime-dom': 3.4.31 + '@vue/server-renderer': 3.4.31(vue@3.4.31) + '@vue/shared': 3.4.31 + typescript: 5.1.6 + dev: false + /web-namespaces@2.0.1: resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} dev: false @@ -6581,6 +7462,11 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -6617,10 +7503,22 @@ packages: engines: {node: '>=10'} dev: true + /zod-to-json-schema@3.23.1(zod@3.23.8): + resolution: {integrity: sha512-oT9INvydob1XV0v1d2IadrR74rLtDInLvDFfAa1CG0Pmg/vxATk7I2gSelfj271mbzeM4Da0uuDQE/Nkj3DWNw==} + peerDependencies: + zod: ^3.23.3 + dependencies: + zod: 3.23.8 + dev: false + /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false diff --git a/src/app/ask-source/page.tsx b/src/app/ask-source/page.tsx index 2457bb13b..bd07928ed 100644 --- a/src/app/ask-source/page.tsx +++ b/src/app/ask-source/page.tsx @@ -1,124 +1,13 @@ 'use client'; -import React, { useState, useEffect, useRef } from 'react'; -import clsx from 'clsx'; -import SourceGraphIcon from '@/components/icons/SourceGraphIcon'; +import React from 'react'; +import { Chatbot } from '@/components/chatbot/chatbot-page'; -interface Message { - sender: 'bot' | 'user'; - text: string; -} +const AskSourceChat = () => ( + <> + +
+ +) -const AskSourceChat = () => { - const [messages, setMessages] = useState([ - { sender: 'bot', text: 'Hello! How can I help you today?' }, - { sender: 'user', text: 'What is Sourcegraph? What is Sourcegraph? What is Sourcegraph? What is Sourcegraph? What is Sourcegraph?' }, - { sender: 'bot', text: 'Sourcegraph is a code search and intelligence tool. Sourcegraph is a code search and intelligence tool.' } - ]); - const [inputValue, setInputValue] = useState(''); - const [charCount, setCharCount] = useState(0); - const [isLoggedIn, setIsLoggedIn] = useState(true); // Add state for user login - const charLimit = 250; - const messagesEndRef = useRef(null); - - const handleInputChange = (e: React.ChangeEvent) => { - setInputValue(e.target.value); - setCharCount(e.target.value.length); - }; - - const handleSendMessage = () => { - if (inputValue.trim() === '') return; - - setMessages([...messages, { sender: 'user', text: inputValue }]); - setInputValue(''); - setCharCount(0); - - // Dummy bot response - setTimeout(() => { - setMessages(prevMessages => [...prevMessages, { sender: 'bot', text: 'Thank you for your message!' }]); - scrollToBottom(); - }, 1000); - }; - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - handleSendMessage(); - } - }; - - const scrollToBottom = () => { - messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); - }; - - useEffect(() => { - scrollToBottom(); - }, [messages]); - - return ( - <> -
-
-

Ask Sourcegraph

-

Get information faster by asking our AI chatbot assistant.

-
-
- {messages.map((message, index) => ( -
- {message.sender === 'bot' && ( -
-
- -
-
- )} -
- {message.text} -
-
- ))} -
-
- {!isLoggedIn && ( -
- -
- )} -
-
- - -
-

{charCount}/{charLimit}

-
-
-
- - ); -}; - -export default AskSourceChat; +export default AskSourceChat diff --git a/src/components/chatbot/chat-input.tsx b/src/components/chatbot/chat-input.tsx new file mode 100644 index 000000000..5ec9924f0 --- /dev/null +++ b/src/components/chatbot/chat-input.tsx @@ -0,0 +1,75 @@ +import { type UseChatHelpers } from 'ai/react' + +import { PromptForm } from './prompt-form' +import { Button } from './ui/button' +import { IconRegenerate, IconStop } from './ui/icons' + +export interface ChatInputProps + extends Pick< + UseChatHelpers, + | 'append' + | 'isLoading' + | 'reload' + | 'messages' + | 'stop' + | 'input' + | 'setInput' + > { + id?: string +} + +export function ChatInput({ + id, + isLoading, + stop, + append, + reload, + input, + setInput, + messages +}: ChatInputProps) { + return ( +
+
+
+ {isLoading ? ( + + ) : ( + messages?.length > 0 && ( + + ) + )} +
+
+ { + await append({ + content: value, + role: 'user' + }) + }} + input={input} + setInput={setInput} + isLoading={isLoading} + /> +
+
+
+ ) +} diff --git a/src/components/chatbot/chat-list.tsx b/src/components/chatbot/chat-list.tsx new file mode 100644 index 000000000..446ab2e61 --- /dev/null +++ b/src/components/chatbot/chat-list.tsx @@ -0,0 +1,23 @@ +import { type Message } from 'ai' + +import { Separator } from './ui/separator' +import { ChatMessage } from './chat-message' + +export interface ChatList { + messages: Message[] +} + +export function ChatList({ messages }: ChatList) { + return ( +
+ {messages?.map((message, index) => ( +
+ + {index < messages.length - 1 && ( + + )} +
+ ))} +
+ ) +} diff --git a/src/components/chatbot/chat-message-actions.tsx b/src/components/chatbot/chat-message-actions.tsx new file mode 100644 index 000000000..1037907b4 --- /dev/null +++ b/src/components/chatbot/chat-message-actions.tsx @@ -0,0 +1,40 @@ +'use client' + +import { type Message } from 'ai' + +import { Button } from './ui/button' +import { IconCheck, IconCopy } from './ui/icons' +import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard' +import cn from 'mxcn' + +interface ChatMessageActionsProps extends React.ComponentProps<'div'> { + message: Message +} + +export function ChatMessageActions({ + message, + className, + ...props +}: ChatMessageActionsProps) { + const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 }) + + const onCopy = () => { + if (isCopied) return + copyToClipboard(message.content) + } + + return ( +
+ +
+ ) +} diff --git a/src/components/chatbot/chat-message.tsx b/src/components/chatbot/chat-message.tsx new file mode 100644 index 000000000..a9bf39065 --- /dev/null +++ b/src/components/chatbot/chat-message.tsx @@ -0,0 +1,77 @@ +import { Message } from 'ai' +import remarkGfm from 'remark-gfm' +import remarkMath from 'remark-math' + +import { ChatMessageActions } from './chat-message-actions' +import { MemoizedReactMarkdown } from './markdown' +import { CodeBlock } from './ui/codeblock' +import { IconSparkles, IconUser } from './ui/icons' +import cn from 'mxcn' + +export interface ChatMessageProps { + message: Message +} + +export function ChatMessage({ message, ...props }: ChatMessageProps) { + return ( +
+
+ {message.role === 'user' ? : } +
+
+ {children}

+ }, + code({ node, inline, className, children, ...props }) { + if (children.length) { + if (children[0] == '▍') { + return ( + + ) + } + + children[0] = (children[0] as string).replace('`▍`', '▍') + } + + const match = /language-(\w+)/.exec(className || '') + + if (inline) { + return ( + + {children} + + ) + } + + return ( + + ) + } + }} + > + {message.content} +
+ +
+
+ ) +} diff --git a/src/components/chatbot/chatbot-page.tsx b/src/components/chatbot/chatbot-page.tsx new file mode 100644 index 000000000..494771ec1 --- /dev/null +++ b/src/components/chatbot/chatbot-page.tsx @@ -0,0 +1,56 @@ +'use client' + +import { ChatList } from './chat-list' +import { useChat, type Message } from 'ai/react' +import cn from 'mxcn' +import { useState } from 'react' +import { toast } from 'sonner' +import { ChatInput } from './chat-input' + +export interface ChatProps extends React.ComponentProps<'div'> { + id?: string // Optional: Thread ID if you want to persist the chat in a DB + initialMessages?: Message[] // Optional: Messages to pre-populate the chat from DB +} + +export function Chatbot({ id, initialMessages, className }: ChatProps) { + const [threadId, setThreadId] = useState(null) + + const { messages, append, reload, stop, isLoading, input, setInput } = + useChat({ + api: '/api/chat', + initialMessages, + body: { threadId }, + onResponse(response) { + if (response.status !== 200) { + console.log('✨ ~ response:', response) + toast.error(response.statusText) + } + + // Get Thread ID from response header + const lbThreadId = response.headers.get('lb-thread-id') + setThreadId(lbThreadId) + } + }) + + return ( +
+
+
+

Ask Sourcegraph

+

Get information faster by asking our AI chatbot assistant.

+
+ +
+ +
+ ) +} diff --git a/src/components/chatbot/header.tsx b/src/components/chatbot/header.tsx new file mode 100644 index 000000000..a6dfc4948 --- /dev/null +++ b/src/components/chatbot/header.tsx @@ -0,0 +1,47 @@ +import { buttonVariants } from './ui/button' +import cn from 'mxcn' +import Link from 'next/link' +import { IconFork, IconGitHub } from './ui/icons' + +export async function Header() { + return ( +
+
+

+ + + Langbase + +

+
+ + +
+ ) +} diff --git a/src/components/chatbot/markdown.tsx b/src/components/chatbot/markdown.tsx new file mode 100644 index 000000000..d4491467a --- /dev/null +++ b/src/components/chatbot/markdown.tsx @@ -0,0 +1,9 @@ +import { FC, memo } from 'react' +import ReactMarkdown, { Options } from 'react-markdown' + +export const MemoizedReactMarkdown: FC = memo( + ReactMarkdown, + (prevProps, nextProps) => + prevProps.children === nextProps.children && + prevProps.className === nextProps.className +) diff --git a/src/components/chatbot/opening.tsx b/src/components/chatbot/opening.tsx new file mode 100644 index 000000000..f14817c25 --- /dev/null +++ b/src/components/chatbot/opening.tsx @@ -0,0 +1,81 @@ +import Link from 'next/link' + +export function Opening() { + return ( +
+
+
+
+ + Chatbot Example + +
+ +
+
+

+ AI Chatbot by a + + pipe on ⌘ Langbase + +

+
+ Ship hyper-personalized AI assistants with memory. +
+
+ +
+

Learn more by checking out:

+
+ + 1. + Fork this AI Chatbot Pipe on ⌘ Langbase + + + 2. + Use LangUI.dev's open source code compnents + + + + 3. + Go through Documentaion: Pipe Quickstart + + + 4. + + Learn more about Pipes & Memory features on ⌘ Langbase + + +
+
+
+
+
+ ) +} + +// Description Link +function Dlink({ + href, + children, + ...props +}: { + href: string + children: React.ReactNode + [key: string]: any +}) { + return ( + + {children} + + ) +} diff --git a/src/components/chatbot/prompt-form.tsx b/src/components/chatbot/prompt-form.tsx new file mode 100644 index 000000000..dd7cf0e48 --- /dev/null +++ b/src/components/chatbot/prompt-form.tsx @@ -0,0 +1,95 @@ +import { Button } from './ui/button' +import { IconChat, IconCommand, IconSpinner } from './ui/icons' +import { useEnterSubmit } from '@/lib/hooks/use-enter-submit' +import { UseChatHelpers } from 'ai/react' +import * as React from 'react' +import Textarea from 'react-textarea-autosize' + +export interface PromptProps + extends Pick { + onSubmit: (value: string) => Promise + isLoading: boolean +} + +export function PromptForm({ + onSubmit, + input, + setInput, + isLoading +}: PromptProps) { + const { formRef, onKeyDown } = useEnterSubmit() + const inputRef = React.useRef(null) + + React.useEffect(() => { + if (inputRef.current) { + inputRef.current.focus() + } + }, []) + + return ( +
{ + e.preventDefault() + if (!input?.trim()) { + return + } + setInput('') + await onSubmit(input) + }} + ref={formRef} + > +
+
+ +
+