├── .env.example
├── .gitignore
├── .prettierrc
├── LICENSE
├── README.md
├── bun.lockb
├── components.json
├── examples
└── nextjs
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── README.md
│ ├── app
│ ├── components
│ │ ├── chat.tsx
│ │ ├── features.tsx
│ │ ├── footer.tsx
│ │ └── header.tsx
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ └── page.tsx
│ ├── next.config.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── postcss.config.mjs
│ ├── prettier.config.js
│ ├── tailwind.config.ts
│ ├── tsconfig.json
│ └── vercel.json
├── index.ts
├── package.json
├── playground
├── .gitignore
├── README.md
├── eslint.config.mjs
├── next.config.ts
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│ ├── file.svg
│ ├── globe.svg
│ ├── next.svg
│ ├── vercel.svg
│ └── window.svg
├── src
│ └── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ └── page.tsx
├── tailwind.config.ts
└── tsconfig.json
├── postcss.config.mjs
├── public
└── images
│ ├── vector-databrowser.png
│ ├── widget-closed.png
│ └── widget-open.png
├── src
├── client
│ ├── components
│ │ ├── chat-component.tsx
│ │ ├── lib
│ │ │ └── utils.ts
│ │ ├── styles.css
│ │ └── ui
│ │ │ ├── button.tsx
│ │ │ └── scroll-area.tsx
│ └── index.ts
└── server
│ ├── actions
│ ├── chat.ts
│ └── history.ts
│ ├── constants.ts
│ ├── index.ts
│ └── lib
│ ├── history
│ ├── get-client.ts
│ ├── in-memory.ts
│ └── redis.ts
│ └── types.ts
├── tailwind.config.ts
├── tsconfig.json
└── tsup.config.ts
/.env.example:
--------------------------------------------------------------------------------
1 | UPSTASH_VECTOR_REST_URL=
2 | UPSTASH_VECTOR_REST_TOKEN=
3 |
4 | # Optional for persistent chat history
5 | UPSTASH_REDIS_REST_URL=
6 | UPSTASH_REDIS_REST_TOKEN=
7 |
8 | TOGETHER_API_KEY=
9 | # (Optional) Default = meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo
10 | TOGETHER_MODEL=
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
2 |
3 | # Logs
4 |
5 | logs
6 | _.log
7 | npm-debug.log_
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 | .pnpm-debug.log*
12 |
13 | # Caches
14 |
15 | .cache
16 |
17 | # Diagnostic reports (https://nodejs.org/api/report.html)
18 |
19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
20 |
21 | # Runtime data
22 |
23 | pids
24 | _.pid
25 | _.seed
26 | *.pid.lock
27 |
28 | # Directory for instrumented libs generated by jscoverage/JSCover
29 |
30 | lib-cov
31 |
32 | # Coverage directory used by tools like istanbul
33 |
34 | coverage
35 | *.lcov
36 |
37 | # nyc test coverage
38 |
39 | .nyc_output
40 |
41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
42 |
43 | .grunt
44 |
45 | # Bower dependency directory (https://bower.io/)
46 |
47 | bower_components
48 |
49 | # node-waf configuration
50 |
51 | .lock-wscript
52 |
53 | # Compiled binary addons (https://nodejs.org/api/addons.html)
54 |
55 | build/Release
56 |
57 | # Dependency directories
58 |
59 | node_modules/
60 | jspm_packages/
61 |
62 | # Snowpack dependency directory (https://snowpack.dev/)
63 |
64 | web_modules/
65 |
66 | # TypeScript cache
67 |
68 | *.tsbuildinfo
69 |
70 | # Optional npm cache directory
71 |
72 | .npm
73 |
74 | # Optional eslint cache
75 |
76 | .eslintcache
77 |
78 | # Optional stylelint cache
79 |
80 | .stylelintcache
81 |
82 | # Microbundle cache
83 |
84 | .rpt2_cache/
85 | .rts2_cache_cjs/
86 | .rts2_cache_es/
87 | .rts2_cache_umd/
88 |
89 | # Optional REPL history
90 |
91 | .node_repl_history
92 |
93 | # Output of 'npm pack'
94 |
95 | *.tgz
96 |
97 | # Yarn Integrity file
98 |
99 | .yarn-integrity
100 |
101 | # dotenv environment variable files
102 |
103 | .env
104 | .env.development.local
105 | .env.test.local
106 | .env.production.local
107 | .env.local
108 |
109 | # parcel-bundler cache (https://parceljs.org/)
110 |
111 | .parcel-cache
112 |
113 | # Next.js build output
114 |
115 | .next
116 | out
117 |
118 | # Nuxt.js build / generate output
119 |
120 | .nuxt
121 | dist
122 |
123 | # Gatsby files
124 |
125 | # Comment in the public line in if your project uses Gatsby and not Next.js
126 |
127 | # https://nextjs.org/blog/next-9-1#public-directory-support
128 |
129 | # public
130 |
131 | # vuepress build output
132 |
133 | .vuepress/dist
134 |
135 | # vuepress v2.x temp and cache directory
136 |
137 | .temp
138 |
139 | # Docusaurus cache and generated files
140 |
141 | .docusaurus
142 |
143 | # Serverless directories
144 |
145 | .serverless/
146 |
147 | # FuseBox cache
148 |
149 | .fusebox/
150 |
151 | # DynamoDB Local files
152 |
153 | .dynamodb/
154 |
155 | # TernJS port file
156 |
157 | .tern-port
158 |
159 | # Stores VSCode versions used for testing VSCode extensions
160 |
161 | .vscode-test
162 |
163 | # yarn v2
164 |
165 | .yarn/cache
166 | .yarn/unplugged
167 | .yarn/build-state.yml
168 | .yarn/install-state.gz
169 | .pnp.*
170 |
171 | # IntelliJ based IDEs
172 | .idea
173 |
174 | # Finder (MacOS) folder config
175 | .DS_Store
176 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "arrowParens": "always",
3 | "bracketSameLine": false,
4 | "bracketSpacing": true,
5 | "semi": true,
6 | "singleQuote": false,
7 | "jsxSingleQuote": false,
8 | "trailingComma": "all",
9 | "singleAttributePerLine": false,
10 | "importOrderSeparation": true,
11 | "importOrderSortSpecifiers": true,
12 | "importOrderBuiltinModulesToTop": true,
13 | "tailwindFunctions": ["clsx"],
14 | "plugins": ["prettier-plugin-tailwindcss"]
15 | }
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Upstash
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RAG Chat Component
2 |
3 | A customizable Reach chat component that combines Upstash Vector for similarity search, Together AI for LLM, and Vercel AI SDK for streaming responses. This ready-to-use component provides an out of the box solution for adding RAG-Powered chat interfaces to your Next.js application.
4 |
5 |
6 |
7 |
8 |
9 | Closed State
10 |
11 |
12 |
13 | Open State
14 |
15 |
16 |
17 |
18 | ## Features
19 |
20 | ⚡ Streaming responses support
21 |
22 | 💻 Server actions
23 |
24 | 📱 Responsive design
25 |
26 | 🔍 Real-time context retrieval
27 |
28 | 💾 Persistent chat history
29 |
30 | 🎨 Fully customizable UI components
31 |
32 | 🎨 Dark/light mode support
33 |
34 | ## Installation
35 |
36 | ```bash
37 | # Using npm
38 | npm install @upstash/rag-chat-component
39 |
40 | # Using pnpm
41 | pnpm add @upstash/rag-chat-component
42 |
43 | # Using yarn
44 | yarn add @upstash/rag-chat-component
45 | ```
46 |
47 | ## Quick Start
48 |
49 | ### 1. Environment Variables
50 |
51 | Create an Upstash Vector database and set up the environment variables as below. If you don't have an account, you can start by going to [Upstash Console](https://console.upstash.com).
52 |
53 | Choose an embedding model when creating an index in Upstash Vector.
54 |
55 | ```
56 | UPSTASH_VECTOR_REST_URL=
57 | UPSTASH_VECTOR_REST_TOKEN=
58 |
59 | # Optional for persistent chat history
60 | UPSTASH_REDIS_REST_URL=
61 | UPSTASH_REDIS_REST_TOKEN=
62 |
63 | OPENAI_API_KEY=
64 |
65 | TOGETHER_API_KEY=
66 |
67 | # Optional
68 | TOGETHER_MODEL=
69 | ```
70 |
71 | ### 2. Configure Styles
72 |
73 | In your `tailwind.config.ts` file, add the configuration below:
74 |
75 | ```ts
76 | import type { Config } from "tailwindcss";
77 |
78 | export default {
79 | content: ["./node_modules/@upstash/rag-chat-component/**/*.{js,mjs}"],
80 | } satisfies Config;
81 | ```
82 |
83 | ### 3. Implementation
84 |
85 | The RAG Chat Component can be integrated into your application using two straightforward approaches. Choose the method that best fits your project structure:
86 |
87 | #### 1. Using a Dedicated Component File (Recommended)
88 |
89 | Create a seperate component file with the `use client` directive, then import and use it anywhere in your application.
90 |
91 | ```jsx
92 | // components/chat.tsx
93 | "use client";
94 |
95 | import { ChatComponent } from "@upstash/rag-chat-component";
96 |
97 | export const Chat = () => {
98 | return ;
99 | };
100 | ```
101 |
102 | ```jsx
103 | // page.tsx
104 | import { Chat } from "./components/chat";
105 |
106 | export default function Home() {
107 | return (
108 | <>
109 |
110 | Home
111 | >
112 | );
113 | }
114 | ```
115 |
116 | #### 2. Direct Integration in Client Components
117 |
118 | Alternatively, import and use the **ChatComponent** directly in your client-side pages.
119 |
120 | ```jsx
121 | // page.tsx
122 | "use client";
123 | import { ChatComponent } from "@upstash/rag-chat-component";
124 |
125 | export default function Home() {
126 | return (
127 | <>
128 |
129 | Home
130 | >
131 | );
132 | }
133 | ```
134 |
135 | ### 4. Choosing Chat Model
136 |
137 | It's possible to choose one of the [together.ai](https://www.together.ai/) models for the chat.
138 | Default model is `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo`. You can configure it in the environment variables.
139 |
140 | ```
141 | TOGETHER_MODEL="deepseek-ai/DeepSeek-V3"
142 | ```
143 |
144 | ### 5. Additional Notes
145 |
146 | If you're deploying on Vercel and experiencing timeout issues, you can increase the function execution time limit by adding the following configuration to your `vercel.json`:
147 |
148 | ```
149 | {
150 | "functions": {
151 | "app/**/*": {
152 | "maxDuration": 30
153 | }
154 | }
155 | }
156 | ```
157 |
158 | This extends the function timeout to 30 seconds, allowing more time for RAG operations to complete on serverless functions.
159 |
160 |
161 |
162 | ## Adding Content
163 |
164 | You can add content to your RAG Chat component in several ways:
165 |
166 |
167 | 1. Using Upstash Vector SDK
168 |
169 | Upstash has Vector SDKs in JS and Python. You can use those SDK to insert data to your Vector index.
170 |
171 | [Vector JS SDK](https://github.com/upstash/vector-js)
172 |
173 | [Vector Python SDK](https://github.com/upstash/vector-py)
174 |
175 | For other languages you can use [Vector REST API](https://upstash.com/docs/vector/api/get-started).
176 |
177 |
178 |
179 |
180 | 2. Using Upstash Vector UI
181 |
182 | For testing purpose, you can add your data directly through the Upstash Vector Console:
183 |
184 | 1. Navigate to [Upstash Console](http://console.upstash.com/vector).
185 | 2. Go to details page of the Vector database.
186 | 3. Navigate to **Data Browser Tab**.
187 | 4. Here, you can upsert data or upload a PDF.
188 |
189 |
190 |
191 |
192 |
193 |
194 | 3. docs2vector tool
195 |
196 | If you are planning to insert your documentation (markdown files) to your Vector index, then you can use [docs2vector](https://github.com/upstash/docs2vector/) tool.
197 |
198 |
199 |
200 | ## Development
201 |
202 | You can use the playground for development, by basically running the command in the root.
203 |
204 | ```bash
205 | bun run playground
206 | ```
207 |
208 | ## Roadmap
209 |
210 | - Integration with [QStash](https://upstash.com/docs/qstash/overall/getstarted) for infinite timout for serverless functions
211 |
212 | ## Contributing
213 |
214 | We welcome contributions! Please see our contributing guidelines for more details.
215 |
216 | ## License
217 |
218 | MIT License - see the LICENSE file for details.
219 |
--------------------------------------------------------------------------------
/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/bun.lockb
--------------------------------------------------------------------------------
/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "default",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/app/globals.css",
9 | "baseColor": "slate",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "utils": "@/lib/utils"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/nextjs/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/examples/nextjs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for committing if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
--------------------------------------------------------------------------------
/examples/nextjs/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37 |
--------------------------------------------------------------------------------
/examples/nextjs/app/components/chat.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { ChatComponent } from "@upstash/rag-chat-component";
4 |
5 | export const Chat = () => {
6 | return ;
7 | };
8 |
--------------------------------------------------------------------------------
/examples/nextjs/app/components/features.tsx:
--------------------------------------------------------------------------------
1 | export default function Features() {
2 | return (
3 |
4 |
8 |
12 |
16 |
20 |
21 | );
22 | }
23 |
24 | export function FeatureCard({
25 | title,
26 | description,
27 | }: {
28 | title: string;
29 | description: string;
30 | }) {
31 | return (
32 |
33 |
{title}
34 |
{description}
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/examples/nextjs/app/components/footer.tsx:
--------------------------------------------------------------------------------
1 | import { ArrowUpRight } from "lucide-react";
2 |
3 | export default function Footer() {
4 | return (
5 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/examples/nextjs/app/components/header.tsx:
--------------------------------------------------------------------------------
1 | export default function Header() {
2 | return (
3 |
67 | );
68 | }
69 |
--------------------------------------------------------------------------------
/examples/nextjs/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/examples/nextjs/app/favicon.ico
--------------------------------------------------------------------------------
/examples/nextjs/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @keyframes anim-zoom {
6 | 0% {
7 | width: 64px;
8 | height: 64px;
9 | opacity: 1;
10 | }
11 | 99% {
12 | width: 2000px;
13 | height: 2000px;
14 | opacity: 0;
15 | }
16 | 100% {
17 | width: 64px;
18 | height: 64px;
19 | opacity: 0;
20 | }
21 | }
22 |
23 | .pulse {
24 | @apply absolute left-0 right-0 size-16 -translate-x-1/2 -translate-y-1/2 rounded-full border-[60px] border-emerald-500/20 opacity-0;
25 | animation: anim-zoom 40s ease infinite;
26 | }
27 |
--------------------------------------------------------------------------------
/examples/nextjs/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter, Inter_Tight } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const defaultFont = Inter({
6 | variable: "--font-sans",
7 | subsets: ["latin"],
8 | });
9 |
10 | const displayFont = Inter_Tight({
11 | variable: "--font-display",
12 | subsets: ["latin"],
13 | });
14 |
15 | export const metadata: Metadata = {
16 | title: "RAG Component",
17 | description: "Streaming Chat Component with Persistent History",
18 | icons: {
19 | icon: [{ url: "upstash.png" }],
20 | },
21 | };
22 |
23 | export default function RootLayout({
24 | children,
25 | }: Readonly<{
26 | children: React.ReactNode;
27 | }>) {
28 | return (
29 |
33 |
34 | {children}
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/examples/nextjs/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Features from "@/app/components/features";
2 | import Footer from "@/app/components/footer";
3 | import Header from "@/app/components/header";
4 | import { Chat } from "./components/chat";
5 |
6 | export default function Home() {
7 | return (
8 |
9 | {/* page */}
10 |
11 |
12 |
13 |
14 |
15 |
16 | {/* chat */}
17 |
18 |
19 |
20 | {[0, 5, 10, 15, 20, 25, 30, 35].map((o) => (
21 |
26 | ))}
27 |
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/examples/nextjs/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/examples/nextjs/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs",
3 | "version": "0.1.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "nextjs",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "@upstash/rag-chat-component": "^0.2.1",
12 | "next": "15.1.4",
13 | "react": "^19.0.0",
14 | "react-dom": "^19.0.0"
15 | },
16 | "devDependencies": {
17 | "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
18 | "@types/node": "^20",
19 | "@types/react": "^19",
20 | "@types/react-dom": "^19",
21 | "postcss": "^8",
22 | "prettier": "^3.4.2",
23 | "prettier-plugin-tailwindcss": "^0.6.9",
24 | "tailwindcss": "^3.4.1",
25 | "typescript": "^5"
26 | }
27 | },
28 | "node_modules/@ai-sdk/openai": {
29 | "version": "1.0.18",
30 | "license": "Apache-2.0",
31 | "dependencies": {
32 | "@ai-sdk/provider": "1.0.4",
33 | "@ai-sdk/provider-utils": "2.0.7"
34 | },
35 | "engines": {
36 | "node": ">=18"
37 | },
38 | "peerDependencies": {
39 | "zod": "^3.0.0"
40 | }
41 | },
42 | "node_modules/@ai-sdk/provider": {
43 | "version": "1.0.4",
44 | "license": "Apache-2.0",
45 | "dependencies": {
46 | "json-schema": "^0.4.0"
47 | },
48 | "engines": {
49 | "node": ">=18"
50 | }
51 | },
52 | "node_modules/@ai-sdk/provider-utils": {
53 | "version": "2.0.7",
54 | "license": "Apache-2.0",
55 | "dependencies": {
56 | "@ai-sdk/provider": "1.0.4",
57 | "eventsource-parser": "^3.0.0",
58 | "nanoid": "^3.3.8",
59 | "secure-json-parse": "^2.7.0"
60 | },
61 | "engines": {
62 | "node": ">=18"
63 | },
64 | "peerDependencies": {
65 | "zod": "^3.0.0"
66 | },
67 | "peerDependenciesMeta": {
68 | "zod": {
69 | "optional": true
70 | }
71 | }
72 | },
73 | "node_modules/@ai-sdk/react": {
74 | "version": "1.0.9",
75 | "license": "Apache-2.0",
76 | "dependencies": {
77 | "@ai-sdk/provider-utils": "2.0.7",
78 | "@ai-sdk/ui-utils": "1.0.8",
79 | "swr": "^2.2.5",
80 | "throttleit": "2.1.0"
81 | },
82 | "engines": {
83 | "node": ">=18"
84 | },
85 | "peerDependencies": {
86 | "react": "^18 || ^19 || ^19.0.0-rc",
87 | "zod": "^3.0.0"
88 | },
89 | "peerDependenciesMeta": {
90 | "react": {
91 | "optional": true
92 | },
93 | "zod": {
94 | "optional": true
95 | }
96 | }
97 | },
98 | "node_modules/@ai-sdk/ui-utils": {
99 | "version": "1.0.8",
100 | "license": "Apache-2.0",
101 | "dependencies": {
102 | "@ai-sdk/provider": "1.0.4",
103 | "@ai-sdk/provider-utils": "2.0.7",
104 | "zod-to-json-schema": "^3.23.5"
105 | },
106 | "engines": {
107 | "node": ">=18"
108 | },
109 | "peerDependencies": {
110 | "zod": "^3.0.0"
111 | },
112 | "peerDependenciesMeta": {
113 | "zod": {
114 | "optional": true
115 | }
116 | }
117 | },
118 | "node_modules/@alloc/quick-lru": {
119 | "version": "5.2.0",
120 | "license": "MIT",
121 | "engines": {
122 | "node": ">=10"
123 | },
124 | "funding": {
125 | "url": "https://github.com/sponsors/sindresorhus"
126 | }
127 | },
128 | "node_modules/@babel/code-frame": {
129 | "version": "7.26.2",
130 | "dev": true,
131 | "license": "MIT",
132 | "dependencies": {
133 | "@babel/helper-validator-identifier": "^7.25.9",
134 | "js-tokens": "^4.0.0",
135 | "picocolors": "^1.0.0"
136 | },
137 | "engines": {
138 | "node": ">=6.9.0"
139 | }
140 | },
141 | "node_modules/@babel/generator": {
142 | "version": "7.26.5",
143 | "dev": true,
144 | "license": "MIT",
145 | "dependencies": {
146 | "@babel/parser": "^7.26.5",
147 | "@babel/types": "^7.26.5",
148 | "@jridgewell/gen-mapping": "^0.3.5",
149 | "@jridgewell/trace-mapping": "^0.3.25",
150 | "jsesc": "^3.0.2"
151 | },
152 | "engines": {
153 | "node": ">=6.9.0"
154 | }
155 | },
156 | "node_modules/@babel/helper-string-parser": {
157 | "version": "7.25.9",
158 | "dev": true,
159 | "license": "MIT",
160 | "engines": {
161 | "node": ">=6.9.0"
162 | }
163 | },
164 | "node_modules/@babel/helper-validator-identifier": {
165 | "version": "7.25.9",
166 | "dev": true,
167 | "license": "MIT",
168 | "engines": {
169 | "node": ">=6.9.0"
170 | }
171 | },
172 | "node_modules/@babel/parser": {
173 | "version": "7.26.5",
174 | "dev": true,
175 | "license": "MIT",
176 | "dependencies": {
177 | "@babel/types": "^7.26.5"
178 | },
179 | "bin": {
180 | "parser": "bin/babel-parser.js"
181 | },
182 | "engines": {
183 | "node": ">=6.0.0"
184 | }
185 | },
186 | "node_modules/@babel/runtime": {
187 | "version": "7.26.0",
188 | "license": "MIT",
189 | "dependencies": {
190 | "regenerator-runtime": "^0.14.0"
191 | },
192 | "engines": {
193 | "node": ">=6.9.0"
194 | }
195 | },
196 | "node_modules/@babel/template": {
197 | "version": "7.25.9",
198 | "dev": true,
199 | "license": "MIT",
200 | "dependencies": {
201 | "@babel/code-frame": "^7.25.9",
202 | "@babel/parser": "^7.25.9",
203 | "@babel/types": "^7.25.9"
204 | },
205 | "engines": {
206 | "node": ">=6.9.0"
207 | }
208 | },
209 | "node_modules/@babel/traverse": {
210 | "version": "7.26.5",
211 | "dev": true,
212 | "license": "MIT",
213 | "dependencies": {
214 | "@babel/code-frame": "^7.26.2",
215 | "@babel/generator": "^7.26.5",
216 | "@babel/parser": "^7.26.5",
217 | "@babel/template": "^7.25.9",
218 | "@babel/types": "^7.26.5",
219 | "debug": "^4.3.1",
220 | "globals": "^11.1.0"
221 | },
222 | "engines": {
223 | "node": ">=6.9.0"
224 | }
225 | },
226 | "node_modules/@babel/types": {
227 | "version": "7.26.5",
228 | "dev": true,
229 | "license": "MIT",
230 | "dependencies": {
231 | "@babel/helper-string-parser": "^7.25.9",
232 | "@babel/helper-validator-identifier": "^7.25.9"
233 | },
234 | "engines": {
235 | "node": ">=6.9.0"
236 | }
237 | },
238 | "node_modules/@ianvs/prettier-plugin-sort-imports": {
239 | "version": "4.4.1",
240 | "dev": true,
241 | "license": "Apache-2.0",
242 | "dependencies": {
243 | "@babel/generator": "^7.26.2",
244 | "@babel/parser": "^7.26.2",
245 | "@babel/traverse": "^7.25.9",
246 | "@babel/types": "^7.26.0",
247 | "semver": "^7.5.2"
248 | },
249 | "peerDependencies": {
250 | "@vue/compiler-sfc": "2.7.x || 3.x",
251 | "prettier": "2 || 3"
252 | },
253 | "peerDependenciesMeta": {
254 | "@vue/compiler-sfc": {
255 | "optional": true
256 | }
257 | }
258 | },
259 | "node_modules/@isaacs/cliui": {
260 | "version": "8.0.2",
261 | "license": "ISC",
262 | "dependencies": {
263 | "string-width": "^5.1.2",
264 | "string-width-cjs": "npm:string-width@^4.2.0",
265 | "strip-ansi": "^7.0.1",
266 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
267 | "wrap-ansi": "^8.1.0",
268 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
269 | },
270 | "engines": {
271 | "node": ">=12"
272 | }
273 | },
274 | "node_modules/@jridgewell/gen-mapping": {
275 | "version": "0.3.8",
276 | "license": "MIT",
277 | "dependencies": {
278 | "@jridgewell/set-array": "^1.2.1",
279 | "@jridgewell/sourcemap-codec": "^1.4.10",
280 | "@jridgewell/trace-mapping": "^0.3.24"
281 | },
282 | "engines": {
283 | "node": ">=6.0.0"
284 | }
285 | },
286 | "node_modules/@jridgewell/resolve-uri": {
287 | "version": "3.1.2",
288 | "license": "MIT",
289 | "engines": {
290 | "node": ">=6.0.0"
291 | }
292 | },
293 | "node_modules/@jridgewell/set-array": {
294 | "version": "1.2.1",
295 | "license": "MIT",
296 | "engines": {
297 | "node": ">=6.0.0"
298 | }
299 | },
300 | "node_modules/@jridgewell/sourcemap-codec": {
301 | "version": "1.5.0",
302 | "license": "MIT"
303 | },
304 | "node_modules/@jridgewell/trace-mapping": {
305 | "version": "0.3.25",
306 | "license": "MIT",
307 | "dependencies": {
308 | "@jridgewell/resolve-uri": "^3.1.0",
309 | "@jridgewell/sourcemap-codec": "^1.4.14"
310 | }
311 | },
312 | "node_modules/@next/env": {
313 | "version": "15.1.4",
314 | "license": "MIT"
315 | },
316 | "node_modules/@next/swc-darwin-arm64": {
317 | "version": "15.1.4",
318 | "cpu": [
319 | "arm64"
320 | ],
321 | "license": "MIT",
322 | "optional": true,
323 | "os": [
324 | "darwin"
325 | ],
326 | "engines": {
327 | "node": ">= 10"
328 | }
329 | },
330 | "node_modules/@next/swc-darwin-x64": {
331 | "version": "15.1.4",
332 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.4.tgz",
333 | "integrity": "sha512-7sgf5rM7Z81V9w48F02Zz6DgEJulavC0jadab4ZsJ+K2sxMNK0/BtF8J8J3CxnsJN3DGcIdC260wEKssKTukUw==",
334 | "cpu": [
335 | "x64"
336 | ],
337 | "optional": true,
338 | "os": [
339 | "darwin"
340 | ],
341 | "engines": {
342 | "node": ">= 10"
343 | }
344 | },
345 | "node_modules/@next/swc-linux-arm64-gnu": {
346 | "version": "15.1.4",
347 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.4.tgz",
348 | "integrity": "sha512-JaZlIMNaJenfd55kjaLWMfok+vWBlcRxqnRoZrhFQrhM1uAehP3R0+Aoe+bZOogqlZvAz53nY/k3ZyuKDtT2zQ==",
349 | "cpu": [
350 | "arm64"
351 | ],
352 | "optional": true,
353 | "os": [
354 | "linux"
355 | ],
356 | "engines": {
357 | "node": ">= 10"
358 | }
359 | },
360 | "node_modules/@next/swc-linux-arm64-musl": {
361 | "version": "15.1.4",
362 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.4.tgz",
363 | "integrity": "sha512-7EBBjNoyTO2ipMDgCiORpwwOf5tIueFntKjcN3NK+GAQD7OzFJe84p7a2eQUeWdpzZvhVXuAtIen8QcH71ZCOQ==",
364 | "cpu": [
365 | "arm64"
366 | ],
367 | "optional": true,
368 | "os": [
369 | "linux"
370 | ],
371 | "engines": {
372 | "node": ">= 10"
373 | }
374 | },
375 | "node_modules/@next/swc-linux-x64-gnu": {
376 | "version": "15.1.4",
377 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.4.tgz",
378 | "integrity": "sha512-9TGEgOycqZFuADyFqwmK/9g6S0FYZ3tphR4ebcmCwhL8Y12FW8pIBKJvSwV+UBjMkokstGNH+9F8F031JZKpHw==",
379 | "cpu": [
380 | "x64"
381 | ],
382 | "optional": true,
383 | "os": [
384 | "linux"
385 | ],
386 | "engines": {
387 | "node": ">= 10"
388 | }
389 | },
390 | "node_modules/@next/swc-linux-x64-musl": {
391 | "version": "15.1.4",
392 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.4.tgz",
393 | "integrity": "sha512-0578bLRVDJOh+LdIoKvgNDz77+Bd85c5JrFgnlbI1SM3WmEQvsjxTA8ATu9Z9FCiIS/AliVAW2DV/BDwpXbtiQ==",
394 | "cpu": [
395 | "x64"
396 | ],
397 | "optional": true,
398 | "os": [
399 | "linux"
400 | ],
401 | "engines": {
402 | "node": ">= 10"
403 | }
404 | },
405 | "node_modules/@next/swc-win32-arm64-msvc": {
406 | "version": "15.1.4",
407 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.4.tgz",
408 | "integrity": "sha512-JgFCiV4libQavwII+kncMCl30st0JVxpPOtzWcAI2jtum4HjYaclobKhj+JsRu5tFqMtA5CJIa0MvYyuu9xjjQ==",
409 | "cpu": [
410 | "arm64"
411 | ],
412 | "optional": true,
413 | "os": [
414 | "win32"
415 | ],
416 | "engines": {
417 | "node": ">= 10"
418 | }
419 | },
420 | "node_modules/@next/swc-win32-x64-msvc": {
421 | "version": "15.1.4",
422 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.4.tgz",
423 | "integrity": "sha512-xxsJy9wzq7FR5SqPCUqdgSXiNXrMuidgckBa8nH9HtjjxsilgcN6VgXF6tZ3uEWuVEadotQJI8/9EQ6guTC4Yw==",
424 | "cpu": [
425 | "x64"
426 | ],
427 | "optional": true,
428 | "os": [
429 | "win32"
430 | ],
431 | "engines": {
432 | "node": ">= 10"
433 | }
434 | },
435 | "node_modules/@nodelib/fs.scandir": {
436 | "version": "2.1.5",
437 | "license": "MIT",
438 | "dependencies": {
439 | "@nodelib/fs.stat": "2.0.5",
440 | "run-parallel": "^1.1.9"
441 | },
442 | "engines": {
443 | "node": ">= 8"
444 | }
445 | },
446 | "node_modules/@nodelib/fs.stat": {
447 | "version": "2.0.5",
448 | "license": "MIT",
449 | "engines": {
450 | "node": ">= 8"
451 | }
452 | },
453 | "node_modules/@nodelib/fs.walk": {
454 | "version": "1.2.8",
455 | "license": "MIT",
456 | "dependencies": {
457 | "@nodelib/fs.scandir": "2.1.5",
458 | "fastq": "^1.6.0"
459 | },
460 | "engines": {
461 | "node": ">= 8"
462 | }
463 | },
464 | "node_modules/@opentelemetry/api": {
465 | "version": "1.9.0",
466 | "license": "Apache-2.0",
467 | "engines": {
468 | "node": ">=8.0.0"
469 | }
470 | },
471 | "node_modules/@pkgjs/parseargs": {
472 | "version": "0.11.0",
473 | "license": "MIT",
474 | "optional": true,
475 | "engines": {
476 | "node": ">=14"
477 | }
478 | },
479 | "node_modules/@radix-ui/number": {
480 | "version": "1.1.0",
481 | "license": "MIT"
482 | },
483 | "node_modules/@radix-ui/primitive": {
484 | "version": "1.1.1",
485 | "license": "MIT"
486 | },
487 | "node_modules/@radix-ui/react-compose-refs": {
488 | "version": "1.1.1",
489 | "license": "MIT",
490 | "peerDependencies": {
491 | "@types/react": "*",
492 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
493 | },
494 | "peerDependenciesMeta": {
495 | "@types/react": {
496 | "optional": true
497 | }
498 | }
499 | },
500 | "node_modules/@radix-ui/react-context": {
501 | "version": "1.1.1",
502 | "license": "MIT",
503 | "peerDependencies": {
504 | "@types/react": "*",
505 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
506 | },
507 | "peerDependenciesMeta": {
508 | "@types/react": {
509 | "optional": true
510 | }
511 | }
512 | },
513 | "node_modules/@radix-ui/react-direction": {
514 | "version": "1.1.0",
515 | "license": "MIT",
516 | "peerDependencies": {
517 | "@types/react": "*",
518 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
519 | },
520 | "peerDependenciesMeta": {
521 | "@types/react": {
522 | "optional": true
523 | }
524 | }
525 | },
526 | "node_modules/@radix-ui/react-presence": {
527 | "version": "1.1.2",
528 | "license": "MIT",
529 | "dependencies": {
530 | "@radix-ui/react-compose-refs": "1.1.1",
531 | "@radix-ui/react-use-layout-effect": "1.1.0"
532 | },
533 | "peerDependencies": {
534 | "@types/react": "*",
535 | "@types/react-dom": "*",
536 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
537 | "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
538 | },
539 | "peerDependenciesMeta": {
540 | "@types/react": {
541 | "optional": true
542 | },
543 | "@types/react-dom": {
544 | "optional": true
545 | }
546 | }
547 | },
548 | "node_modules/@radix-ui/react-primitive": {
549 | "version": "2.0.1",
550 | "license": "MIT",
551 | "dependencies": {
552 | "@radix-ui/react-slot": "1.1.1"
553 | },
554 | "peerDependencies": {
555 | "@types/react": "*",
556 | "@types/react-dom": "*",
557 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
558 | "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
559 | },
560 | "peerDependenciesMeta": {
561 | "@types/react": {
562 | "optional": true
563 | },
564 | "@types/react-dom": {
565 | "optional": true
566 | }
567 | }
568 | },
569 | "node_modules/@radix-ui/react-scroll-area": {
570 | "version": "1.2.2",
571 | "license": "MIT",
572 | "dependencies": {
573 | "@radix-ui/number": "1.1.0",
574 | "@radix-ui/primitive": "1.1.1",
575 | "@radix-ui/react-compose-refs": "1.1.1",
576 | "@radix-ui/react-context": "1.1.1",
577 | "@radix-ui/react-direction": "1.1.0",
578 | "@radix-ui/react-presence": "1.1.2",
579 | "@radix-ui/react-primitive": "2.0.1",
580 | "@radix-ui/react-use-callback-ref": "1.1.0",
581 | "@radix-ui/react-use-layout-effect": "1.1.0"
582 | },
583 | "peerDependencies": {
584 | "@types/react": "*",
585 | "@types/react-dom": "*",
586 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
587 | "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
588 | },
589 | "peerDependenciesMeta": {
590 | "@types/react": {
591 | "optional": true
592 | },
593 | "@types/react-dom": {
594 | "optional": true
595 | }
596 | }
597 | },
598 | "node_modules/@radix-ui/react-slot": {
599 | "version": "1.1.1",
600 | "license": "MIT",
601 | "dependencies": {
602 | "@radix-ui/react-compose-refs": "1.1.1"
603 | },
604 | "peerDependencies": {
605 | "@types/react": "*",
606 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
607 | },
608 | "peerDependenciesMeta": {
609 | "@types/react": {
610 | "optional": true
611 | }
612 | }
613 | },
614 | "node_modules/@radix-ui/react-use-callback-ref": {
615 | "version": "1.1.0",
616 | "license": "MIT",
617 | "peerDependencies": {
618 | "@types/react": "*",
619 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
620 | },
621 | "peerDependenciesMeta": {
622 | "@types/react": {
623 | "optional": true
624 | }
625 | }
626 | },
627 | "node_modules/@radix-ui/react-use-layout-effect": {
628 | "version": "1.1.0",
629 | "license": "MIT",
630 | "peerDependencies": {
631 | "@types/react": "*",
632 | "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
633 | },
634 | "peerDependenciesMeta": {
635 | "@types/react": {
636 | "optional": true
637 | }
638 | }
639 | },
640 | "node_modules/@swc/counter": {
641 | "version": "0.1.3",
642 | "license": "Apache-2.0"
643 | },
644 | "node_modules/@swc/helpers": {
645 | "version": "0.5.15",
646 | "license": "Apache-2.0",
647 | "dependencies": {
648 | "tslib": "^2.8.0"
649 | }
650 | },
651 | "node_modules/@types/diff-match-patch": {
652 | "version": "1.0.36",
653 | "license": "MIT"
654 | },
655 | "node_modules/@types/node": {
656 | "version": "20.17.12",
657 | "license": "MIT",
658 | "dependencies": {
659 | "undici-types": "~6.19.2"
660 | }
661 | },
662 | "node_modules/@types/node-fetch": {
663 | "version": "2.6.12",
664 | "license": "MIT",
665 | "dependencies": {
666 | "@types/node": "*",
667 | "form-data": "^4.0.0"
668 | }
669 | },
670 | "node_modules/@types/node-int64": {
671 | "version": "0.4.32",
672 | "license": "MIT",
673 | "dependencies": {
674 | "@types/node": "*"
675 | }
676 | },
677 | "node_modules/@types/parquetjs": {
678 | "version": "0.10.6",
679 | "license": "MIT",
680 | "dependencies": {
681 | "@types/node-int64": "*"
682 | }
683 | },
684 | "node_modules/@types/progress-stream": {
685 | "version": "2.0.5",
686 | "license": "MIT",
687 | "dependencies": {
688 | "@types/node": "*"
689 | }
690 | },
691 | "node_modules/@types/react": {
692 | "version": "19.0.6",
693 | "devOptional": true,
694 | "license": "MIT",
695 | "dependencies": {
696 | "csstype": "^3.0.2"
697 | }
698 | },
699 | "node_modules/@types/react-dom": {
700 | "version": "19.0.3",
701 | "devOptional": true,
702 | "license": "MIT",
703 | "peerDependencies": {
704 | "@types/react": "^19.0.0"
705 | }
706 | },
707 | "node_modules/@upstash/rag-chat-component": {
708 | "version": "0.2.1",
709 | "resolved": "https://registry.npmjs.org/@upstash/rag-chat-component/-/rag-chat-component-0.2.1.tgz",
710 | "integrity": "sha512-YsYTds0MTS85cpP9OreLQNnEFCaWv+rql+OHTd1ebnI+FNW3n2QhjNlvOuni6J15bL5xSe/Eaw5kPfzgUqEWeQ==",
711 | "dependencies": {
712 | "@ai-sdk/openai": "^1.0.18",
713 | "@radix-ui/react-scroll-area": "^1.2.2",
714 | "@radix-ui/react-slot": "^1.1.1",
715 | "@upstash/redis": "^1.34.3",
716 | "@upstash/vector": "^1.2.0",
717 | "ai": "^4.0.33",
718 | "class-variance-authority": "^0.7.1",
719 | "clsx": "^2.1.1",
720 | "lodash.debounce": "^4.0.8",
721 | "lucide-react": "^0.471.0",
722 | "react": "^19",
723 | "react-dom": "^19",
724 | "react-textarea-autosize": "^8.5.7",
725 | "tailwind-merge": "^2.6.0",
726 | "tailwindcss": "^3.4.1",
727 | "tailwindcss-animate": "^1.0.7",
728 | "together-ai": "^0.11.1"
729 | },
730 | "peerDependencies": {
731 | "next": "^14 || ^15",
732 | "react": "^18 || ^19",
733 | "typescript": "^5"
734 | }
735 | },
736 | "node_modules/@upstash/redis": {
737 | "version": "v1.34.3",
738 | "license": "MIT",
739 | "dependencies": {
740 | "crypto-js": "^4.2.0"
741 | }
742 | },
743 | "node_modules/@upstash/vector": {
744 | "version": "v1.2.0",
745 | "license": "MIT"
746 | },
747 | "node_modules/abort-controller": {
748 | "version": "3.0.0",
749 | "license": "MIT",
750 | "dependencies": {
751 | "event-target-shim": "^5.0.0"
752 | },
753 | "engines": {
754 | "node": ">=6.5"
755 | }
756 | },
757 | "node_modules/agentkeepalive": {
758 | "version": "4.6.0",
759 | "license": "MIT",
760 | "dependencies": {
761 | "humanize-ms": "^1.2.1"
762 | },
763 | "engines": {
764 | "node": ">= 8.0.0"
765 | }
766 | },
767 | "node_modules/ai": {
768 | "version": "4.0.33",
769 | "license": "Apache-2.0",
770 | "dependencies": {
771 | "@ai-sdk/provider": "1.0.4",
772 | "@ai-sdk/provider-utils": "2.0.7",
773 | "@ai-sdk/react": "1.0.9",
774 | "@ai-sdk/ui-utils": "1.0.8",
775 | "@opentelemetry/api": "1.9.0",
776 | "jsondiffpatch": "0.6.0",
777 | "zod-to-json-schema": "^3.23.5"
778 | },
779 | "engines": {
780 | "node": ">=18"
781 | },
782 | "peerDependencies": {
783 | "react": "^18 || ^19 || ^19.0.0-rc",
784 | "zod": "^3.0.0"
785 | },
786 | "peerDependenciesMeta": {
787 | "react": {
788 | "optional": true
789 | },
790 | "zod": {
791 | "optional": true
792 | }
793 | }
794 | },
795 | "node_modules/ansi-regex": {
796 | "version": "6.1.0",
797 | "license": "MIT",
798 | "engines": {
799 | "node": ">=12"
800 | },
801 | "funding": {
802 | "url": "https://github.com/chalk/ansi-regex?sponsor=1"
803 | }
804 | },
805 | "node_modules/ansi-styles": {
806 | "version": "6.2.1",
807 | "license": "MIT",
808 | "engines": {
809 | "node": ">=12"
810 | },
811 | "funding": {
812 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
813 | }
814 | },
815 | "node_modules/any-promise": {
816 | "version": "1.3.0",
817 | "license": "MIT"
818 | },
819 | "node_modules/anymatch": {
820 | "version": "3.1.3",
821 | "license": "ISC",
822 | "dependencies": {
823 | "normalize-path": "^3.0.0",
824 | "picomatch": "^2.0.4"
825 | },
826 | "engines": {
827 | "node": ">= 8"
828 | }
829 | },
830 | "node_modules/arg": {
831 | "version": "5.0.2",
832 | "license": "MIT"
833 | },
834 | "node_modules/asynckit": {
835 | "version": "0.4.0",
836 | "license": "MIT"
837 | },
838 | "node_modules/axios": {
839 | "version": "1.7.9",
840 | "license": "MIT",
841 | "dependencies": {
842 | "follow-redirects": "^1.15.6",
843 | "form-data": "^4.0.0",
844 | "proxy-from-env": "^1.1.0"
845 | }
846 | },
847 | "node_modules/balanced-match": {
848 | "version": "1.0.2",
849 | "license": "MIT"
850 | },
851 | "node_modules/base64-js": {
852 | "version": "1.5.1",
853 | "funding": [
854 | {
855 | "type": "github",
856 | "url": "https://github.com/sponsors/feross"
857 | },
858 | {
859 | "type": "patreon",
860 | "url": "https://www.patreon.com/feross"
861 | },
862 | {
863 | "type": "consulting",
864 | "url": "https://feross.org/support"
865 | }
866 | ],
867 | "license": "MIT"
868 | },
869 | "node_modules/binary-extensions": {
870 | "version": "2.3.0",
871 | "license": "MIT",
872 | "engines": {
873 | "node": ">=8"
874 | },
875 | "funding": {
876 | "url": "https://github.com/sponsors/sindresorhus"
877 | }
878 | },
879 | "node_modules/brace-expansion": {
880 | "version": "2.0.1",
881 | "license": "MIT",
882 | "dependencies": {
883 | "balanced-match": "^1.0.0"
884 | }
885 | },
886 | "node_modules/braces": {
887 | "version": "3.0.3",
888 | "license": "MIT",
889 | "dependencies": {
890 | "fill-range": "^7.1.1"
891 | },
892 | "engines": {
893 | "node": ">=8"
894 | }
895 | },
896 | "node_modules/brotli": {
897 | "version": "1.3.3",
898 | "license": "MIT",
899 | "dependencies": {
900 | "base64-js": "^1.1.2"
901 | }
902 | },
903 | "node_modules/bson": {
904 | "version": "1.1.6",
905 | "license": "Apache-2.0",
906 | "engines": {
907 | "node": ">=0.6.19"
908 | }
909 | },
910 | "node_modules/busboy": {
911 | "version": "1.6.0",
912 | "dependencies": {
913 | "streamsearch": "^1.1.0"
914 | },
915 | "engines": {
916 | "node": ">=10.16.0"
917 | }
918 | },
919 | "node_modules/camelcase-css": {
920 | "version": "2.0.1",
921 | "license": "MIT",
922 | "engines": {
923 | "node": ">= 6"
924 | }
925 | },
926 | "node_modules/caniuse-lite": {
927 | "version": "1.0.30001692",
928 | "funding": [
929 | {
930 | "type": "opencollective",
931 | "url": "https://opencollective.com/browserslist"
932 | },
933 | {
934 | "type": "tidelift",
935 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
936 | },
937 | {
938 | "type": "github",
939 | "url": "https://github.com/sponsors/ai"
940 | }
941 | ],
942 | "license": "CC-BY-4.0"
943 | },
944 | "node_modules/chalk": {
945 | "version": "5.4.1",
946 | "license": "MIT",
947 | "engines": {
948 | "node": "^12.17.0 || ^14.13 || >=16.0.0"
949 | },
950 | "funding": {
951 | "url": "https://github.com/chalk/chalk?sponsor=1"
952 | }
953 | },
954 | "node_modules/chokidar": {
955 | "version": "3.6.0",
956 | "license": "MIT",
957 | "dependencies": {
958 | "anymatch": "~3.1.2",
959 | "braces": "~3.0.2",
960 | "glob-parent": "~5.1.2",
961 | "is-binary-path": "~2.1.0",
962 | "is-glob": "~4.0.1",
963 | "normalize-path": "~3.0.0",
964 | "readdirp": "~3.6.0"
965 | },
966 | "engines": {
967 | "node": ">= 8.10.0"
968 | },
969 | "funding": {
970 | "url": "https://paulmillr.com/funding/"
971 | },
972 | "optionalDependencies": {
973 | "fsevents": "~2.3.2"
974 | }
975 | },
976 | "node_modules/chokidar/node_modules/glob-parent": {
977 | "version": "5.1.2",
978 | "license": "ISC",
979 | "dependencies": {
980 | "is-glob": "^4.0.1"
981 | },
982 | "engines": {
983 | "node": ">= 6"
984 | }
985 | },
986 | "node_modules/class-variance-authority": {
987 | "version": "0.7.1",
988 | "license": "Apache-2.0",
989 | "dependencies": {
990 | "clsx": "^2.1.1"
991 | },
992 | "funding": {
993 | "url": "https://polar.sh/cva"
994 | }
995 | },
996 | "node_modules/client-only": {
997 | "version": "0.0.1",
998 | "license": "MIT"
999 | },
1000 | "node_modules/clsx": {
1001 | "version": "2.1.1",
1002 | "license": "MIT",
1003 | "engines": {
1004 | "node": ">=6"
1005 | }
1006 | },
1007 | "node_modules/color-convert": {
1008 | "version": "2.0.1",
1009 | "license": "MIT",
1010 | "dependencies": {
1011 | "color-name": "~1.1.4"
1012 | },
1013 | "engines": {
1014 | "node": ">=7.0.0"
1015 | }
1016 | },
1017 | "node_modules/color-name": {
1018 | "version": "1.1.4",
1019 | "license": "MIT"
1020 | },
1021 | "node_modules/combined-stream": {
1022 | "version": "1.0.8",
1023 | "license": "MIT",
1024 | "dependencies": {
1025 | "delayed-stream": "~1.0.0"
1026 | },
1027 | "engines": {
1028 | "node": ">= 0.8"
1029 | }
1030 | },
1031 | "node_modules/commander": {
1032 | "version": "4.1.1",
1033 | "license": "MIT",
1034 | "engines": {
1035 | "node": ">= 6"
1036 | }
1037 | },
1038 | "node_modules/core-util-is": {
1039 | "version": "1.0.3",
1040 | "license": "MIT"
1041 | },
1042 | "node_modules/cross-spawn": {
1043 | "version": "7.0.6",
1044 | "license": "MIT",
1045 | "dependencies": {
1046 | "path-key": "^3.1.0",
1047 | "shebang-command": "^2.0.0",
1048 | "which": "^2.0.1"
1049 | },
1050 | "engines": {
1051 | "node": ">= 8"
1052 | }
1053 | },
1054 | "node_modules/crypto-js": {
1055 | "version": "4.2.0",
1056 | "license": "MIT"
1057 | },
1058 | "node_modules/cssesc": {
1059 | "version": "3.0.0",
1060 | "license": "MIT",
1061 | "bin": {
1062 | "cssesc": "bin/cssesc"
1063 | },
1064 | "engines": {
1065 | "node": ">=4"
1066 | }
1067 | },
1068 | "node_modules/csstype": {
1069 | "version": "3.1.3",
1070 | "devOptional": true,
1071 | "license": "MIT"
1072 | },
1073 | "node_modules/debug": {
1074 | "version": "4.4.0",
1075 | "dev": true,
1076 | "license": "MIT",
1077 | "dependencies": {
1078 | "ms": "^2.1.3"
1079 | },
1080 | "engines": {
1081 | "node": ">=6.0"
1082 | },
1083 | "peerDependenciesMeta": {
1084 | "supports-color": {
1085 | "optional": true
1086 | }
1087 | }
1088 | },
1089 | "node_modules/delayed-stream": {
1090 | "version": "1.0.0",
1091 | "license": "MIT",
1092 | "engines": {
1093 | "node": ">=0.4.0"
1094 | }
1095 | },
1096 | "node_modules/dequal": {
1097 | "version": "2.0.3",
1098 | "license": "MIT",
1099 | "engines": {
1100 | "node": ">=6"
1101 | }
1102 | },
1103 | "node_modules/didyoumean": {
1104 | "version": "1.2.2",
1105 | "license": "Apache-2.0"
1106 | },
1107 | "node_modules/diff-match-patch": {
1108 | "version": "1.0.5",
1109 | "license": "Apache-2.0"
1110 | },
1111 | "node_modules/dlv": {
1112 | "version": "1.1.3",
1113 | "license": "MIT"
1114 | },
1115 | "node_modules/eastasianwidth": {
1116 | "version": "0.2.0",
1117 | "license": "MIT"
1118 | },
1119 | "node_modules/emoji-regex": {
1120 | "version": "9.2.2",
1121 | "license": "MIT"
1122 | },
1123 | "node_modules/event-target-shim": {
1124 | "version": "5.0.1",
1125 | "license": "MIT",
1126 | "engines": {
1127 | "node": ">=6"
1128 | }
1129 | },
1130 | "node_modules/eventsource-parser": {
1131 | "version": "3.0.0",
1132 | "license": "MIT",
1133 | "engines": {
1134 | "node": ">=18.0.0"
1135 | }
1136 | },
1137 | "node_modules/fast-glob": {
1138 | "version": "3.3.3",
1139 | "license": "MIT",
1140 | "dependencies": {
1141 | "@nodelib/fs.stat": "^2.0.2",
1142 | "@nodelib/fs.walk": "^1.2.3",
1143 | "glob-parent": "^5.1.2",
1144 | "merge2": "^1.3.0",
1145 | "micromatch": "^4.0.8"
1146 | },
1147 | "engines": {
1148 | "node": ">=8.6.0"
1149 | }
1150 | },
1151 | "node_modules/fast-glob/node_modules/glob-parent": {
1152 | "version": "5.1.2",
1153 | "license": "ISC",
1154 | "dependencies": {
1155 | "is-glob": "^4.0.1"
1156 | },
1157 | "engines": {
1158 | "node": ">= 6"
1159 | }
1160 | },
1161 | "node_modules/fastq": {
1162 | "version": "1.18.0",
1163 | "license": "ISC",
1164 | "dependencies": {
1165 | "reusify": "^1.0.4"
1166 | }
1167 | },
1168 | "node_modules/fill-range": {
1169 | "version": "7.1.1",
1170 | "license": "MIT",
1171 | "dependencies": {
1172 | "to-regex-range": "^5.0.1"
1173 | },
1174 | "engines": {
1175 | "node": ">=8"
1176 | }
1177 | },
1178 | "node_modules/follow-redirects": {
1179 | "version": "1.15.9",
1180 | "funding": [
1181 | {
1182 | "type": "individual",
1183 | "url": "https://github.com/sponsors/RubenVerborgh"
1184 | }
1185 | ],
1186 | "license": "MIT",
1187 | "engines": {
1188 | "node": ">=4.0"
1189 | },
1190 | "peerDependenciesMeta": {
1191 | "debug": {
1192 | "optional": true
1193 | }
1194 | }
1195 | },
1196 | "node_modules/foreground-child": {
1197 | "version": "3.3.0",
1198 | "license": "ISC",
1199 | "dependencies": {
1200 | "cross-spawn": "^7.0.0",
1201 | "signal-exit": "^4.0.1"
1202 | },
1203 | "engines": {
1204 | "node": ">=14"
1205 | },
1206 | "funding": {
1207 | "url": "https://github.com/sponsors/isaacs"
1208 | }
1209 | },
1210 | "node_modules/form-data": {
1211 | "version": "4.0.1",
1212 | "license": "MIT",
1213 | "dependencies": {
1214 | "asynckit": "^0.4.0",
1215 | "combined-stream": "^1.0.8",
1216 | "mime-types": "^2.1.12"
1217 | },
1218 | "engines": {
1219 | "node": ">= 6"
1220 | }
1221 | },
1222 | "node_modules/form-data-encoder": {
1223 | "version": "1.7.2",
1224 | "license": "MIT"
1225 | },
1226 | "node_modules/formdata-node": {
1227 | "version": "4.4.1",
1228 | "license": "MIT",
1229 | "dependencies": {
1230 | "node-domexception": "1.0.0",
1231 | "web-streams-polyfill": "4.0.0-beta.3"
1232 | },
1233 | "engines": {
1234 | "node": ">= 12.20"
1235 | }
1236 | },
1237 | "node_modules/fsevents": {
1238 | "version": "2.3.3",
1239 | "license": "MIT",
1240 | "optional": true,
1241 | "os": [
1242 | "darwin"
1243 | ],
1244 | "engines": {
1245 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1246 | }
1247 | },
1248 | "node_modules/function-bind": {
1249 | "version": "1.1.2",
1250 | "license": "MIT",
1251 | "funding": {
1252 | "url": "https://github.com/sponsors/ljharb"
1253 | }
1254 | },
1255 | "node_modules/glob": {
1256 | "version": "10.4.5",
1257 | "license": "ISC",
1258 | "dependencies": {
1259 | "foreground-child": "^3.1.0",
1260 | "jackspeak": "^3.1.2",
1261 | "minimatch": "^9.0.4",
1262 | "minipass": "^7.1.2",
1263 | "package-json-from-dist": "^1.0.0",
1264 | "path-scurry": "^1.11.1"
1265 | },
1266 | "bin": {
1267 | "glob": "dist/esm/bin.mjs"
1268 | },
1269 | "funding": {
1270 | "url": "https://github.com/sponsors/isaacs"
1271 | }
1272 | },
1273 | "node_modules/glob-parent": {
1274 | "version": "6.0.2",
1275 | "license": "ISC",
1276 | "dependencies": {
1277 | "is-glob": "^4.0.3"
1278 | },
1279 | "engines": {
1280 | "node": ">=10.13.0"
1281 | }
1282 | },
1283 | "node_modules/globals": {
1284 | "version": "11.12.0",
1285 | "dev": true,
1286 | "license": "MIT",
1287 | "engines": {
1288 | "node": ">=4"
1289 | }
1290 | },
1291 | "node_modules/hasown": {
1292 | "version": "2.0.2",
1293 | "license": "MIT",
1294 | "dependencies": {
1295 | "function-bind": "^1.1.2"
1296 | },
1297 | "engines": {
1298 | "node": ">= 0.4"
1299 | }
1300 | },
1301 | "node_modules/humanize-ms": {
1302 | "version": "1.2.1",
1303 | "license": "MIT",
1304 | "dependencies": {
1305 | "ms": "^2.0.0"
1306 | }
1307 | },
1308 | "node_modules/inherits": {
1309 | "version": "2.0.4",
1310 | "license": "ISC"
1311 | },
1312 | "node_modules/int53": {
1313 | "version": "0.2.4",
1314 | "license": "BSD-3-Clause"
1315 | },
1316 | "node_modules/is-binary-path": {
1317 | "version": "2.1.0",
1318 | "license": "MIT",
1319 | "dependencies": {
1320 | "binary-extensions": "^2.0.0"
1321 | },
1322 | "engines": {
1323 | "node": ">=8"
1324 | }
1325 | },
1326 | "node_modules/is-core-module": {
1327 | "version": "2.16.1",
1328 | "license": "MIT",
1329 | "dependencies": {
1330 | "hasown": "^2.0.2"
1331 | },
1332 | "engines": {
1333 | "node": ">= 0.4"
1334 | },
1335 | "funding": {
1336 | "url": "https://github.com/sponsors/ljharb"
1337 | }
1338 | },
1339 | "node_modules/is-extglob": {
1340 | "version": "2.1.1",
1341 | "license": "MIT",
1342 | "engines": {
1343 | "node": ">=0.10.0"
1344 | }
1345 | },
1346 | "node_modules/is-fullwidth-code-point": {
1347 | "version": "3.0.0",
1348 | "license": "MIT",
1349 | "engines": {
1350 | "node": ">=8"
1351 | }
1352 | },
1353 | "node_modules/is-glob": {
1354 | "version": "4.0.3",
1355 | "license": "MIT",
1356 | "dependencies": {
1357 | "is-extglob": "^2.1.1"
1358 | },
1359 | "engines": {
1360 | "node": ">=0.10.0"
1361 | }
1362 | },
1363 | "node_modules/is-number": {
1364 | "version": "7.0.0",
1365 | "license": "MIT",
1366 | "engines": {
1367 | "node": ">=0.12.0"
1368 | }
1369 | },
1370 | "node_modules/isarray": {
1371 | "version": "1.0.0",
1372 | "license": "MIT"
1373 | },
1374 | "node_modules/isexe": {
1375 | "version": "2.0.0",
1376 | "license": "ISC"
1377 | },
1378 | "node_modules/jackspeak": {
1379 | "version": "3.4.3",
1380 | "license": "BlueOak-1.0.0",
1381 | "dependencies": {
1382 | "@isaacs/cliui": "^8.0.2"
1383 | },
1384 | "funding": {
1385 | "url": "https://github.com/sponsors/isaacs"
1386 | },
1387 | "optionalDependencies": {
1388 | "@pkgjs/parseargs": "^0.11.0"
1389 | }
1390 | },
1391 | "node_modules/jiti": {
1392 | "version": "1.21.7",
1393 | "license": "MIT",
1394 | "bin": {
1395 | "jiti": "bin/jiti.js"
1396 | }
1397 | },
1398 | "node_modules/js-tokens": {
1399 | "version": "4.0.0",
1400 | "dev": true,
1401 | "license": "MIT"
1402 | },
1403 | "node_modules/jsesc": {
1404 | "version": "3.1.0",
1405 | "dev": true,
1406 | "license": "MIT",
1407 | "bin": {
1408 | "jsesc": "bin/jsesc"
1409 | },
1410 | "engines": {
1411 | "node": ">=6"
1412 | }
1413 | },
1414 | "node_modules/json-schema": {
1415 | "version": "0.4.0",
1416 | "license": "(AFL-2.1 OR BSD-3-Clause)"
1417 | },
1418 | "node_modules/jsondiffpatch": {
1419 | "version": "0.6.0",
1420 | "license": "MIT",
1421 | "dependencies": {
1422 | "@types/diff-match-patch": "^1.0.36",
1423 | "chalk": "^5.3.0",
1424 | "diff-match-patch": "^1.0.5"
1425 | },
1426 | "bin": {
1427 | "jsondiffpatch": "bin/jsondiffpatch.js"
1428 | },
1429 | "engines": {
1430 | "node": "^18.0.0 || >=20.0.0"
1431 | }
1432 | },
1433 | "node_modules/lilconfig": {
1434 | "version": "3.1.3",
1435 | "license": "MIT",
1436 | "engines": {
1437 | "node": ">=14"
1438 | },
1439 | "funding": {
1440 | "url": "https://github.com/sponsors/antonk52"
1441 | }
1442 | },
1443 | "node_modules/lines-and-columns": {
1444 | "version": "1.2.4",
1445 | "license": "MIT"
1446 | },
1447 | "node_modules/lodash.debounce": {
1448 | "version": "4.0.8",
1449 | "license": "MIT"
1450 | },
1451 | "node_modules/lru-cache": {
1452 | "version": "10.4.3",
1453 | "license": "ISC"
1454 | },
1455 | "node_modules/lucide-react": {
1456 | "version": "0.471.1",
1457 | "license": "ISC",
1458 | "peerDependencies": {
1459 | "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
1460 | }
1461 | },
1462 | "node_modules/merge2": {
1463 | "version": "1.4.1",
1464 | "license": "MIT",
1465 | "engines": {
1466 | "node": ">= 8"
1467 | }
1468 | },
1469 | "node_modules/micromatch": {
1470 | "version": "4.0.8",
1471 | "license": "MIT",
1472 | "dependencies": {
1473 | "braces": "^3.0.3",
1474 | "picomatch": "^2.3.1"
1475 | },
1476 | "engines": {
1477 | "node": ">=8.6"
1478 | }
1479 | },
1480 | "node_modules/mime-db": {
1481 | "version": "1.52.0",
1482 | "license": "MIT",
1483 | "engines": {
1484 | "node": ">= 0.6"
1485 | }
1486 | },
1487 | "node_modules/mime-types": {
1488 | "version": "2.1.35",
1489 | "license": "MIT",
1490 | "dependencies": {
1491 | "mime-db": "1.52.0"
1492 | },
1493 | "engines": {
1494 | "node": ">= 0.6"
1495 | }
1496 | },
1497 | "node_modules/minimatch": {
1498 | "version": "9.0.5",
1499 | "license": "ISC",
1500 | "dependencies": {
1501 | "brace-expansion": "^2.0.1"
1502 | },
1503 | "engines": {
1504 | "node": ">=16 || 14 >=14.17"
1505 | },
1506 | "funding": {
1507 | "url": "https://github.com/sponsors/isaacs"
1508 | }
1509 | },
1510 | "node_modules/minipass": {
1511 | "version": "7.1.2",
1512 | "license": "ISC",
1513 | "engines": {
1514 | "node": ">=16 || 14 >=14.17"
1515 | }
1516 | },
1517 | "node_modules/ms": {
1518 | "version": "2.1.3",
1519 | "license": "MIT"
1520 | },
1521 | "node_modules/mz": {
1522 | "version": "2.7.0",
1523 | "license": "MIT",
1524 | "dependencies": {
1525 | "any-promise": "^1.0.0",
1526 | "object-assign": "^4.0.1",
1527 | "thenify-all": "^1.0.0"
1528 | }
1529 | },
1530 | "node_modules/nanoid": {
1531 | "version": "3.3.8",
1532 | "funding": [
1533 | {
1534 | "type": "github",
1535 | "url": "https://github.com/sponsors/ai"
1536 | }
1537 | ],
1538 | "license": "MIT",
1539 | "bin": {
1540 | "nanoid": "bin/nanoid.cjs"
1541 | },
1542 | "engines": {
1543 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1544 | }
1545 | },
1546 | "node_modules/next": {
1547 | "version": "15.1.4",
1548 | "license": "MIT",
1549 | "dependencies": {
1550 | "@next/env": "15.1.4",
1551 | "@swc/counter": "0.1.3",
1552 | "@swc/helpers": "0.5.15",
1553 | "busboy": "1.6.0",
1554 | "caniuse-lite": "^1.0.30001579",
1555 | "postcss": "8.4.31",
1556 | "styled-jsx": "5.1.6"
1557 | },
1558 | "bin": {
1559 | "next": "dist/bin/next"
1560 | },
1561 | "engines": {
1562 | "node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
1563 | },
1564 | "optionalDependencies": {
1565 | "@next/swc-darwin-arm64": "15.1.4",
1566 | "@next/swc-darwin-x64": "15.1.4",
1567 | "@next/swc-linux-arm64-gnu": "15.1.4",
1568 | "@next/swc-linux-arm64-musl": "15.1.4",
1569 | "@next/swc-linux-x64-gnu": "15.1.4",
1570 | "@next/swc-linux-x64-musl": "15.1.4",
1571 | "@next/swc-win32-arm64-msvc": "15.1.4",
1572 | "@next/swc-win32-x64-msvc": "15.1.4",
1573 | "sharp": "^0.33.5"
1574 | },
1575 | "peerDependencies": {
1576 | "@opentelemetry/api": "^1.1.0",
1577 | "@playwright/test": "^1.41.2",
1578 | "babel-plugin-react-compiler": "*",
1579 | "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
1580 | "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
1581 | "sass": "^1.3.0"
1582 | },
1583 | "peerDependenciesMeta": {
1584 | "@opentelemetry/api": {
1585 | "optional": true
1586 | },
1587 | "@playwright/test": {
1588 | "optional": true
1589 | },
1590 | "babel-plugin-react-compiler": {
1591 | "optional": true
1592 | },
1593 | "sass": {
1594 | "optional": true
1595 | }
1596 | }
1597 | },
1598 | "node_modules/next/node_modules/postcss": {
1599 | "version": "8.4.31",
1600 | "funding": [
1601 | {
1602 | "type": "opencollective",
1603 | "url": "https://opencollective.com/postcss/"
1604 | },
1605 | {
1606 | "type": "tidelift",
1607 | "url": "https://tidelift.com/funding/github/npm/postcss"
1608 | },
1609 | {
1610 | "type": "github",
1611 | "url": "https://github.com/sponsors/ai"
1612 | }
1613 | ],
1614 | "license": "MIT",
1615 | "dependencies": {
1616 | "nanoid": "^3.3.6",
1617 | "picocolors": "^1.0.0",
1618 | "source-map-js": "^1.0.2"
1619 | },
1620 | "engines": {
1621 | "node": "^10 || ^12 || >=14"
1622 | }
1623 | },
1624 | "node_modules/node-domexception": {
1625 | "version": "1.0.0",
1626 | "funding": [
1627 | {
1628 | "type": "github",
1629 | "url": "https://github.com/sponsors/jimmywarting"
1630 | },
1631 | {
1632 | "type": "github",
1633 | "url": "https://paypal.me/jimmywarting"
1634 | }
1635 | ],
1636 | "license": "MIT",
1637 | "engines": {
1638 | "node": ">=10.5.0"
1639 | }
1640 | },
1641 | "node_modules/node-fetch": {
1642 | "version": "2.7.0",
1643 | "license": "MIT",
1644 | "dependencies": {
1645 | "whatwg-url": "^5.0.0"
1646 | },
1647 | "engines": {
1648 | "node": "4.x || >=6.0.0"
1649 | },
1650 | "peerDependencies": {
1651 | "encoding": "^0.1.0"
1652 | },
1653 | "peerDependenciesMeta": {
1654 | "encoding": {
1655 | "optional": true
1656 | }
1657 | }
1658 | },
1659 | "node_modules/node-int64": {
1660 | "version": "0.4.0",
1661 | "license": "MIT"
1662 | },
1663 | "node_modules/normalize-path": {
1664 | "version": "3.0.0",
1665 | "license": "MIT",
1666 | "engines": {
1667 | "node": ">=0.10.0"
1668 | }
1669 | },
1670 | "node_modules/object-assign": {
1671 | "version": "4.1.1",
1672 | "license": "MIT",
1673 | "engines": {
1674 | "node": ">=0.10.0"
1675 | }
1676 | },
1677 | "node_modules/object-hash": {
1678 | "version": "3.0.0",
1679 | "license": "MIT",
1680 | "engines": {
1681 | "node": ">= 6"
1682 | }
1683 | },
1684 | "node_modules/object-stream": {
1685 | "version": "0.0.1",
1686 | "engines": {
1687 | "node": ">=0.10"
1688 | }
1689 | },
1690 | "node_modules/package-json-from-dist": {
1691 | "version": "1.0.1",
1692 | "license": "BlueOak-1.0.0"
1693 | },
1694 | "node_modules/parquetjs": {
1695 | "version": "0.11.2",
1696 | "license": "MIT",
1697 | "dependencies": {
1698 | "brotli": "^1.3.0",
1699 | "bson": "^1.0.4",
1700 | "int53": "^0.2.4",
1701 | "object-stream": "0.0.1",
1702 | "snappyjs": "^0.6.0",
1703 | "thrift": "^0.11.0",
1704 | "varint": "^5.0.0"
1705 | },
1706 | "engines": {
1707 | "node": ">=7.6"
1708 | },
1709 | "optionalDependencies": {
1710 | "lzo": "^0.4.0"
1711 | }
1712 | },
1713 | "node_modules/path-key": {
1714 | "version": "3.1.1",
1715 | "license": "MIT",
1716 | "engines": {
1717 | "node": ">=8"
1718 | }
1719 | },
1720 | "node_modules/path-parse": {
1721 | "version": "1.0.7",
1722 | "license": "MIT"
1723 | },
1724 | "node_modules/path-scurry": {
1725 | "version": "1.11.1",
1726 | "license": "BlueOak-1.0.0",
1727 | "dependencies": {
1728 | "lru-cache": "^10.2.0",
1729 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1730 | },
1731 | "engines": {
1732 | "node": ">=16 || 14 >=14.18"
1733 | },
1734 | "funding": {
1735 | "url": "https://github.com/sponsors/isaacs"
1736 | }
1737 | },
1738 | "node_modules/picocolors": {
1739 | "version": "1.1.1",
1740 | "license": "ISC"
1741 | },
1742 | "node_modules/picomatch": {
1743 | "version": "2.3.1",
1744 | "license": "MIT",
1745 | "engines": {
1746 | "node": ">=8.6"
1747 | },
1748 | "funding": {
1749 | "url": "https://github.com/sponsors/jonschlinkert"
1750 | }
1751 | },
1752 | "node_modules/pify": {
1753 | "version": "2.3.0",
1754 | "license": "MIT",
1755 | "engines": {
1756 | "node": ">=0.10.0"
1757 | }
1758 | },
1759 | "node_modules/pirates": {
1760 | "version": "4.0.6",
1761 | "license": "MIT",
1762 | "engines": {
1763 | "node": ">= 6"
1764 | }
1765 | },
1766 | "node_modules/postcss": {
1767 | "version": "8.4.49",
1768 | "funding": [
1769 | {
1770 | "type": "opencollective",
1771 | "url": "https://opencollective.com/postcss/"
1772 | },
1773 | {
1774 | "type": "tidelift",
1775 | "url": "https://tidelift.com/funding/github/npm/postcss"
1776 | },
1777 | {
1778 | "type": "github",
1779 | "url": "https://github.com/sponsors/ai"
1780 | }
1781 | ],
1782 | "license": "MIT",
1783 | "dependencies": {
1784 | "nanoid": "^3.3.7",
1785 | "picocolors": "^1.1.1",
1786 | "source-map-js": "^1.2.1"
1787 | },
1788 | "engines": {
1789 | "node": "^10 || ^12 || >=14"
1790 | }
1791 | },
1792 | "node_modules/postcss-import": {
1793 | "version": "15.1.0",
1794 | "license": "MIT",
1795 | "dependencies": {
1796 | "postcss-value-parser": "^4.0.0",
1797 | "read-cache": "^1.0.0",
1798 | "resolve": "^1.1.7"
1799 | },
1800 | "engines": {
1801 | "node": ">=14.0.0"
1802 | },
1803 | "peerDependencies": {
1804 | "postcss": "^8.0.0"
1805 | }
1806 | },
1807 | "node_modules/postcss-js": {
1808 | "version": "4.0.1",
1809 | "license": "MIT",
1810 | "dependencies": {
1811 | "camelcase-css": "^2.0.1"
1812 | },
1813 | "engines": {
1814 | "node": "^12 || ^14 || >= 16"
1815 | },
1816 | "funding": {
1817 | "type": "opencollective",
1818 | "url": "https://opencollective.com/postcss/"
1819 | },
1820 | "peerDependencies": {
1821 | "postcss": "^8.4.21"
1822 | }
1823 | },
1824 | "node_modules/postcss-load-config": {
1825 | "version": "4.0.2",
1826 | "funding": [
1827 | {
1828 | "type": "opencollective",
1829 | "url": "https://opencollective.com/postcss/"
1830 | },
1831 | {
1832 | "type": "github",
1833 | "url": "https://github.com/sponsors/ai"
1834 | }
1835 | ],
1836 | "license": "MIT",
1837 | "dependencies": {
1838 | "lilconfig": "^3.0.0",
1839 | "yaml": "^2.3.4"
1840 | },
1841 | "engines": {
1842 | "node": ">= 14"
1843 | },
1844 | "peerDependencies": {
1845 | "postcss": ">=8.0.9",
1846 | "ts-node": ">=9.0.0"
1847 | },
1848 | "peerDependenciesMeta": {
1849 | "postcss": {
1850 | "optional": true
1851 | },
1852 | "ts-node": {
1853 | "optional": true
1854 | }
1855 | }
1856 | },
1857 | "node_modules/postcss-nested": {
1858 | "version": "6.2.0",
1859 | "funding": [
1860 | {
1861 | "type": "opencollective",
1862 | "url": "https://opencollective.com/postcss/"
1863 | },
1864 | {
1865 | "type": "github",
1866 | "url": "https://github.com/sponsors/ai"
1867 | }
1868 | ],
1869 | "license": "MIT",
1870 | "dependencies": {
1871 | "postcss-selector-parser": "^6.1.1"
1872 | },
1873 | "engines": {
1874 | "node": ">=12.0"
1875 | },
1876 | "peerDependencies": {
1877 | "postcss": "^8.2.14"
1878 | }
1879 | },
1880 | "node_modules/postcss-selector-parser": {
1881 | "version": "6.1.2",
1882 | "license": "MIT",
1883 | "dependencies": {
1884 | "cssesc": "^3.0.0",
1885 | "util-deprecate": "^1.0.2"
1886 | },
1887 | "engines": {
1888 | "node": ">=4"
1889 | }
1890 | },
1891 | "node_modules/postcss-value-parser": {
1892 | "version": "4.2.0",
1893 | "license": "MIT"
1894 | },
1895 | "node_modules/prettier": {
1896 | "version": "3.4.2",
1897 | "dev": true,
1898 | "license": "MIT",
1899 | "bin": {
1900 | "prettier": "bin/prettier.cjs"
1901 | },
1902 | "engines": {
1903 | "node": ">=14"
1904 | },
1905 | "funding": {
1906 | "url": "https://github.com/prettier/prettier?sponsor=1"
1907 | }
1908 | },
1909 | "node_modules/prettier-plugin-tailwindcss": {
1910 | "version": "0.6.9",
1911 | "dev": true,
1912 | "license": "MIT",
1913 | "engines": {
1914 | "node": ">=14.21.3"
1915 | },
1916 | "peerDependencies": {
1917 | "@ianvs/prettier-plugin-sort-imports": "*",
1918 | "@prettier/plugin-pug": "*",
1919 | "@shopify/prettier-plugin-liquid": "*",
1920 | "@trivago/prettier-plugin-sort-imports": "*",
1921 | "@zackad/prettier-plugin-twig-melody": "*",
1922 | "prettier": "^3.0",
1923 | "prettier-plugin-astro": "*",
1924 | "prettier-plugin-css-order": "*",
1925 | "prettier-plugin-import-sort": "*",
1926 | "prettier-plugin-jsdoc": "*",
1927 | "prettier-plugin-marko": "*",
1928 | "prettier-plugin-multiline-arrays": "*",
1929 | "prettier-plugin-organize-attributes": "*",
1930 | "prettier-plugin-organize-imports": "*",
1931 | "prettier-plugin-sort-imports": "*",
1932 | "prettier-plugin-style-order": "*",
1933 | "prettier-plugin-svelte": "*"
1934 | },
1935 | "peerDependenciesMeta": {
1936 | "@ianvs/prettier-plugin-sort-imports": {
1937 | "optional": true
1938 | },
1939 | "@prettier/plugin-pug": {
1940 | "optional": true
1941 | },
1942 | "@shopify/prettier-plugin-liquid": {
1943 | "optional": true
1944 | },
1945 | "@trivago/prettier-plugin-sort-imports": {
1946 | "optional": true
1947 | },
1948 | "@zackad/prettier-plugin-twig-melody": {
1949 | "optional": true
1950 | },
1951 | "prettier-plugin-astro": {
1952 | "optional": true
1953 | },
1954 | "prettier-plugin-css-order": {
1955 | "optional": true
1956 | },
1957 | "prettier-plugin-import-sort": {
1958 | "optional": true
1959 | },
1960 | "prettier-plugin-jsdoc": {
1961 | "optional": true
1962 | },
1963 | "prettier-plugin-marko": {
1964 | "optional": true
1965 | },
1966 | "prettier-plugin-multiline-arrays": {
1967 | "optional": true
1968 | },
1969 | "prettier-plugin-organize-attributes": {
1970 | "optional": true
1971 | },
1972 | "prettier-plugin-organize-imports": {
1973 | "optional": true
1974 | },
1975 | "prettier-plugin-sort-imports": {
1976 | "optional": true
1977 | },
1978 | "prettier-plugin-style-order": {
1979 | "optional": true
1980 | },
1981 | "prettier-plugin-svelte": {
1982 | "optional": true
1983 | }
1984 | }
1985 | },
1986 | "node_modules/process-nextick-args": {
1987 | "version": "2.0.1",
1988 | "license": "MIT"
1989 | },
1990 | "node_modules/progress-stream": {
1991 | "version": "2.0.0",
1992 | "license": "BSD-2-Clause",
1993 | "dependencies": {
1994 | "speedometer": "~1.0.0",
1995 | "through2": "~2.0.3"
1996 | }
1997 | },
1998 | "node_modules/proxy-from-env": {
1999 | "version": "1.1.0",
2000 | "license": "MIT"
2001 | },
2002 | "node_modules/q": {
2003 | "version": "1.5.1",
2004 | "license": "MIT",
2005 | "engines": {
2006 | "node": ">=0.6.0",
2007 | "teleport": ">=0.2.0"
2008 | }
2009 | },
2010 | "node_modules/queue-microtask": {
2011 | "version": "1.2.3",
2012 | "funding": [
2013 | {
2014 | "type": "github",
2015 | "url": "https://github.com/sponsors/feross"
2016 | },
2017 | {
2018 | "type": "patreon",
2019 | "url": "https://www.patreon.com/feross"
2020 | },
2021 | {
2022 | "type": "consulting",
2023 | "url": "https://feross.org/support"
2024 | }
2025 | ],
2026 | "license": "MIT"
2027 | },
2028 | "node_modules/react": {
2029 | "version": "19.0.0",
2030 | "license": "MIT",
2031 | "engines": {
2032 | "node": ">=0.10.0"
2033 | }
2034 | },
2035 | "node_modules/react-dom": {
2036 | "version": "19.0.0",
2037 | "license": "MIT",
2038 | "dependencies": {
2039 | "scheduler": "^0.25.0"
2040 | },
2041 | "peerDependencies": {
2042 | "react": "^19.0.0"
2043 | }
2044 | },
2045 | "node_modules/react-textarea-autosize": {
2046 | "version": "8.5.7",
2047 | "license": "MIT",
2048 | "dependencies": {
2049 | "@babel/runtime": "^7.20.13",
2050 | "use-composed-ref": "^1.3.0",
2051 | "use-latest": "^1.2.1"
2052 | },
2053 | "engines": {
2054 | "node": ">=10"
2055 | },
2056 | "peerDependencies": {
2057 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2058 | }
2059 | },
2060 | "node_modules/read-cache": {
2061 | "version": "1.0.0",
2062 | "license": "MIT",
2063 | "dependencies": {
2064 | "pify": "^2.3.0"
2065 | }
2066 | },
2067 | "node_modules/readable-stream": {
2068 | "version": "2.3.8",
2069 | "license": "MIT",
2070 | "dependencies": {
2071 | "core-util-is": "~1.0.0",
2072 | "inherits": "~2.0.3",
2073 | "isarray": "~1.0.0",
2074 | "process-nextick-args": "~2.0.0",
2075 | "safe-buffer": "~5.1.1",
2076 | "string_decoder": "~1.1.1",
2077 | "util-deprecate": "~1.0.1"
2078 | }
2079 | },
2080 | "node_modules/readdirp": {
2081 | "version": "3.6.0",
2082 | "license": "MIT",
2083 | "dependencies": {
2084 | "picomatch": "^2.2.1"
2085 | },
2086 | "engines": {
2087 | "node": ">=8.10.0"
2088 | }
2089 | },
2090 | "node_modules/regenerator-runtime": {
2091 | "version": "0.14.1",
2092 | "license": "MIT"
2093 | },
2094 | "node_modules/resolve": {
2095 | "version": "1.22.10",
2096 | "license": "MIT",
2097 | "dependencies": {
2098 | "is-core-module": "^2.16.0",
2099 | "path-parse": "^1.0.7",
2100 | "supports-preserve-symlinks-flag": "^1.0.0"
2101 | },
2102 | "bin": {
2103 | "resolve": "bin/resolve"
2104 | },
2105 | "engines": {
2106 | "node": ">= 0.4"
2107 | },
2108 | "funding": {
2109 | "url": "https://github.com/sponsors/ljharb"
2110 | }
2111 | },
2112 | "node_modules/reusify": {
2113 | "version": "1.0.4",
2114 | "license": "MIT",
2115 | "engines": {
2116 | "iojs": ">=1.0.0",
2117 | "node": ">=0.10.0"
2118 | }
2119 | },
2120 | "node_modules/run-parallel": {
2121 | "version": "1.2.0",
2122 | "funding": [
2123 | {
2124 | "type": "github",
2125 | "url": "https://github.com/sponsors/feross"
2126 | },
2127 | {
2128 | "type": "patreon",
2129 | "url": "https://www.patreon.com/feross"
2130 | },
2131 | {
2132 | "type": "consulting",
2133 | "url": "https://feross.org/support"
2134 | }
2135 | ],
2136 | "license": "MIT",
2137 | "dependencies": {
2138 | "queue-microtask": "^1.2.2"
2139 | }
2140 | },
2141 | "node_modules/safe-buffer": {
2142 | "version": "5.1.2",
2143 | "license": "MIT"
2144 | },
2145 | "node_modules/scheduler": {
2146 | "version": "0.25.0",
2147 | "license": "MIT"
2148 | },
2149 | "node_modules/secure-json-parse": {
2150 | "version": "2.7.0",
2151 | "license": "BSD-3-Clause"
2152 | },
2153 | "node_modules/semver": {
2154 | "version": "7.6.3",
2155 | "dev": true,
2156 | "license": "ISC",
2157 | "bin": {
2158 | "semver": "bin/semver.js"
2159 | },
2160 | "engines": {
2161 | "node": ">=10"
2162 | }
2163 | },
2164 | "node_modules/shebang-command": {
2165 | "version": "2.0.0",
2166 | "license": "MIT",
2167 | "dependencies": {
2168 | "shebang-regex": "^3.0.0"
2169 | },
2170 | "engines": {
2171 | "node": ">=8"
2172 | }
2173 | },
2174 | "node_modules/shebang-regex": {
2175 | "version": "3.0.0",
2176 | "license": "MIT",
2177 | "engines": {
2178 | "node": ">=8"
2179 | }
2180 | },
2181 | "node_modules/signal-exit": {
2182 | "version": "4.1.0",
2183 | "license": "ISC",
2184 | "engines": {
2185 | "node": ">=14"
2186 | },
2187 | "funding": {
2188 | "url": "https://github.com/sponsors/isaacs"
2189 | }
2190 | },
2191 | "node_modules/snappyjs": {
2192 | "version": "0.6.1",
2193 | "license": "MIT"
2194 | },
2195 | "node_modules/source-map-js": {
2196 | "version": "1.2.1",
2197 | "license": "BSD-3-Clause",
2198 | "engines": {
2199 | "node": ">=0.10.0"
2200 | }
2201 | },
2202 | "node_modules/speedometer": {
2203 | "version": "1.0.0",
2204 | "license": "MIT"
2205 | },
2206 | "node_modules/streamsearch": {
2207 | "version": "1.1.0",
2208 | "engines": {
2209 | "node": ">=10.0.0"
2210 | }
2211 | },
2212 | "node_modules/string_decoder": {
2213 | "version": "1.1.1",
2214 | "license": "MIT",
2215 | "dependencies": {
2216 | "safe-buffer": "~5.1.0"
2217 | }
2218 | },
2219 | "node_modules/string-width": {
2220 | "version": "5.1.2",
2221 | "license": "MIT",
2222 | "dependencies": {
2223 | "eastasianwidth": "^0.2.0",
2224 | "emoji-regex": "^9.2.2",
2225 | "strip-ansi": "^7.0.1"
2226 | },
2227 | "engines": {
2228 | "node": ">=12"
2229 | },
2230 | "funding": {
2231 | "url": "https://github.com/sponsors/sindresorhus"
2232 | }
2233 | },
2234 | "node_modules/string-width-cjs": {
2235 | "name": "string-width",
2236 | "version": "4.2.3",
2237 | "license": "MIT",
2238 | "dependencies": {
2239 | "emoji-regex": "^8.0.0",
2240 | "is-fullwidth-code-point": "^3.0.0",
2241 | "strip-ansi": "^6.0.1"
2242 | },
2243 | "engines": {
2244 | "node": ">=8"
2245 | }
2246 | },
2247 | "node_modules/string-width-cjs/node_modules/ansi-regex": {
2248 | "version": "5.0.1",
2249 | "license": "MIT",
2250 | "engines": {
2251 | "node": ">=8"
2252 | }
2253 | },
2254 | "node_modules/string-width-cjs/node_modules/emoji-regex": {
2255 | "version": "8.0.0",
2256 | "license": "MIT"
2257 | },
2258 | "node_modules/string-width-cjs/node_modules/strip-ansi": {
2259 | "version": "6.0.1",
2260 | "license": "MIT",
2261 | "dependencies": {
2262 | "ansi-regex": "^5.0.1"
2263 | },
2264 | "engines": {
2265 | "node": ">=8"
2266 | }
2267 | },
2268 | "node_modules/strip-ansi": {
2269 | "version": "7.1.0",
2270 | "license": "MIT",
2271 | "dependencies": {
2272 | "ansi-regex": "^6.0.1"
2273 | },
2274 | "engines": {
2275 | "node": ">=12"
2276 | },
2277 | "funding": {
2278 | "url": "https://github.com/chalk/strip-ansi?sponsor=1"
2279 | }
2280 | },
2281 | "node_modules/strip-ansi-cjs": {
2282 | "name": "strip-ansi",
2283 | "version": "6.0.1",
2284 | "license": "MIT",
2285 | "dependencies": {
2286 | "ansi-regex": "^5.0.1"
2287 | },
2288 | "engines": {
2289 | "node": ">=8"
2290 | }
2291 | },
2292 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
2293 | "version": "5.0.1",
2294 | "license": "MIT",
2295 | "engines": {
2296 | "node": ">=8"
2297 | }
2298 | },
2299 | "node_modules/styled-jsx": {
2300 | "version": "5.1.6",
2301 | "license": "MIT",
2302 | "dependencies": {
2303 | "client-only": "0.0.1"
2304 | },
2305 | "engines": {
2306 | "node": ">= 12.0.0"
2307 | },
2308 | "peerDependencies": {
2309 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
2310 | },
2311 | "peerDependenciesMeta": {
2312 | "@babel/core": {
2313 | "optional": true
2314 | },
2315 | "babel-plugin-macros": {
2316 | "optional": true
2317 | }
2318 | }
2319 | },
2320 | "node_modules/sucrase": {
2321 | "version": "3.35.0",
2322 | "license": "MIT",
2323 | "dependencies": {
2324 | "@jridgewell/gen-mapping": "^0.3.2",
2325 | "commander": "^4.0.0",
2326 | "glob": "^10.3.10",
2327 | "lines-and-columns": "^1.1.6",
2328 | "mz": "^2.7.0",
2329 | "pirates": "^4.0.1",
2330 | "ts-interface-checker": "^0.1.9"
2331 | },
2332 | "bin": {
2333 | "sucrase": "bin/sucrase",
2334 | "sucrase-node": "bin/sucrase-node"
2335 | },
2336 | "engines": {
2337 | "node": ">=16 || 14 >=14.17"
2338 | }
2339 | },
2340 | "node_modules/supports-preserve-symlinks-flag": {
2341 | "version": "1.0.0",
2342 | "license": "MIT",
2343 | "engines": {
2344 | "node": ">= 0.4"
2345 | },
2346 | "funding": {
2347 | "url": "https://github.com/sponsors/ljharb"
2348 | }
2349 | },
2350 | "node_modules/swr": {
2351 | "version": "2.3.0",
2352 | "license": "MIT",
2353 | "dependencies": {
2354 | "dequal": "^2.0.3",
2355 | "use-sync-external-store": "^1.4.0"
2356 | },
2357 | "peerDependencies": {
2358 | "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2359 | }
2360 | },
2361 | "node_modules/tailwind-merge": {
2362 | "version": "2.6.0",
2363 | "license": "MIT",
2364 | "funding": {
2365 | "type": "github",
2366 | "url": "https://github.com/sponsors/dcastil"
2367 | }
2368 | },
2369 | "node_modules/tailwindcss": {
2370 | "version": "3.4.17",
2371 | "license": "MIT",
2372 | "dependencies": {
2373 | "@alloc/quick-lru": "^5.2.0",
2374 | "arg": "^5.0.2",
2375 | "chokidar": "^3.6.0",
2376 | "didyoumean": "^1.2.2",
2377 | "dlv": "^1.1.3",
2378 | "fast-glob": "^3.3.2",
2379 | "glob-parent": "^6.0.2",
2380 | "is-glob": "^4.0.3",
2381 | "jiti": "^1.21.6",
2382 | "lilconfig": "^3.1.3",
2383 | "micromatch": "^4.0.8",
2384 | "normalize-path": "^3.0.0",
2385 | "object-hash": "^3.0.0",
2386 | "picocolors": "^1.1.1",
2387 | "postcss": "^8.4.47",
2388 | "postcss-import": "^15.1.0",
2389 | "postcss-js": "^4.0.1",
2390 | "postcss-load-config": "^4.0.2",
2391 | "postcss-nested": "^6.2.0",
2392 | "postcss-selector-parser": "^6.1.2",
2393 | "resolve": "^1.22.8",
2394 | "sucrase": "^3.35.0"
2395 | },
2396 | "bin": {
2397 | "tailwind": "lib/cli.js",
2398 | "tailwindcss": "lib/cli.js"
2399 | },
2400 | "engines": {
2401 | "node": ">=14.0.0"
2402 | }
2403 | },
2404 | "node_modules/tailwindcss-animate": {
2405 | "version": "1.0.7",
2406 | "license": "MIT",
2407 | "peerDependencies": {
2408 | "tailwindcss": ">=3.0.0 || insiders"
2409 | }
2410 | },
2411 | "node_modules/thenify": {
2412 | "version": "3.3.1",
2413 | "license": "MIT",
2414 | "dependencies": {
2415 | "any-promise": "^1.0.0"
2416 | }
2417 | },
2418 | "node_modules/thenify-all": {
2419 | "version": "1.6.0",
2420 | "license": "MIT",
2421 | "dependencies": {
2422 | "thenify": ">= 3.1.0 < 4"
2423 | },
2424 | "engines": {
2425 | "node": ">=0.8"
2426 | }
2427 | },
2428 | "node_modules/thrift": {
2429 | "version": "0.11.0",
2430 | "license": "Apache-2.0",
2431 | "dependencies": {
2432 | "node-int64": "^0.4.0",
2433 | "q": "^1.5.0",
2434 | "ws": ">= 2.2.3"
2435 | },
2436 | "engines": {
2437 | "node": ">= 4.1.0"
2438 | }
2439 | },
2440 | "node_modules/throttleit": {
2441 | "version": "2.1.0",
2442 | "license": "MIT",
2443 | "engines": {
2444 | "node": ">=18"
2445 | },
2446 | "funding": {
2447 | "url": "https://github.com/sponsors/sindresorhus"
2448 | }
2449 | },
2450 | "node_modules/through2": {
2451 | "version": "2.0.5",
2452 | "license": "MIT",
2453 | "dependencies": {
2454 | "readable-stream": "~2.3.6",
2455 | "xtend": "~4.0.1"
2456 | }
2457 | },
2458 | "node_modules/to-regex-range": {
2459 | "version": "5.0.1",
2460 | "license": "MIT",
2461 | "dependencies": {
2462 | "is-number": "^7.0.0"
2463 | },
2464 | "engines": {
2465 | "node": ">=8.0"
2466 | }
2467 | },
2468 | "node_modules/together-ai": {
2469 | "version": "0.11.1",
2470 | "license": "Apache-2.0",
2471 | "dependencies": {
2472 | "@types/node": "^18.11.18",
2473 | "@types/node-fetch": "^2.6.4",
2474 | "@types/parquetjs": "^0.10.6",
2475 | "@types/progress-stream": "^2.0.5",
2476 | "abort-controller": "^3.0.0",
2477 | "agentkeepalive": "^4.2.1",
2478 | "axios": "^1.7.7",
2479 | "form-data-encoder": "1.7.2",
2480 | "formdata-node": "^4.3.2",
2481 | "node-fetch": "^2.6.7",
2482 | "parquetjs": "^0.11.2",
2483 | "progress-stream": "^2.0.0"
2484 | }
2485 | },
2486 | "node_modules/together-ai/node_modules/@types/node": {
2487 | "version": "18.19.70",
2488 | "license": "MIT",
2489 | "dependencies": {
2490 | "undici-types": "~5.26.4"
2491 | }
2492 | },
2493 | "node_modules/together-ai/node_modules/undici-types": {
2494 | "version": "5.26.5",
2495 | "license": "MIT"
2496 | },
2497 | "node_modules/tr46": {
2498 | "version": "0.0.3",
2499 | "license": "MIT"
2500 | },
2501 | "node_modules/ts-interface-checker": {
2502 | "version": "0.1.13",
2503 | "license": "Apache-2.0"
2504 | },
2505 | "node_modules/tslib": {
2506 | "version": "2.8.1",
2507 | "license": "0BSD"
2508 | },
2509 | "node_modules/typescript": {
2510 | "version": "5.7.3",
2511 | "license": "Apache-2.0",
2512 | "bin": {
2513 | "tsc": "bin/tsc",
2514 | "tsserver": "bin/tsserver"
2515 | },
2516 | "engines": {
2517 | "node": ">=14.17"
2518 | }
2519 | },
2520 | "node_modules/undici-types": {
2521 | "version": "6.19.8",
2522 | "license": "MIT"
2523 | },
2524 | "node_modules/use-composed-ref": {
2525 | "version": "1.4.0",
2526 | "license": "MIT",
2527 | "peerDependencies": {
2528 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2529 | },
2530 | "peerDependenciesMeta": {
2531 | "@types/react": {
2532 | "optional": true
2533 | }
2534 | }
2535 | },
2536 | "node_modules/use-isomorphic-layout-effect": {
2537 | "version": "1.2.0",
2538 | "license": "MIT",
2539 | "peerDependencies": {
2540 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2541 | },
2542 | "peerDependenciesMeta": {
2543 | "@types/react": {
2544 | "optional": true
2545 | }
2546 | }
2547 | },
2548 | "node_modules/use-latest": {
2549 | "version": "1.3.0",
2550 | "license": "MIT",
2551 | "dependencies": {
2552 | "use-isomorphic-layout-effect": "^1.1.1"
2553 | },
2554 | "peerDependencies": {
2555 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2556 | },
2557 | "peerDependenciesMeta": {
2558 | "@types/react": {
2559 | "optional": true
2560 | }
2561 | }
2562 | },
2563 | "node_modules/use-sync-external-store": {
2564 | "version": "1.4.0",
2565 | "license": "MIT",
2566 | "peerDependencies": {
2567 | "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2568 | }
2569 | },
2570 | "node_modules/util-deprecate": {
2571 | "version": "1.0.2",
2572 | "license": "MIT"
2573 | },
2574 | "node_modules/varint": {
2575 | "version": "5.0.2",
2576 | "license": "MIT"
2577 | },
2578 | "node_modules/web-streams-polyfill": {
2579 | "version": "4.0.0-beta.3",
2580 | "license": "MIT",
2581 | "engines": {
2582 | "node": ">= 14"
2583 | }
2584 | },
2585 | "node_modules/webidl-conversions": {
2586 | "version": "3.0.1",
2587 | "license": "BSD-2-Clause"
2588 | },
2589 | "node_modules/whatwg-url": {
2590 | "version": "5.0.0",
2591 | "license": "MIT",
2592 | "dependencies": {
2593 | "tr46": "~0.0.3",
2594 | "webidl-conversions": "^3.0.0"
2595 | }
2596 | },
2597 | "node_modules/which": {
2598 | "version": "2.0.2",
2599 | "license": "ISC",
2600 | "dependencies": {
2601 | "isexe": "^2.0.0"
2602 | },
2603 | "bin": {
2604 | "node-which": "bin/node-which"
2605 | },
2606 | "engines": {
2607 | "node": ">= 8"
2608 | }
2609 | },
2610 | "node_modules/wrap-ansi": {
2611 | "version": "8.1.0",
2612 | "license": "MIT",
2613 | "dependencies": {
2614 | "ansi-styles": "^6.1.0",
2615 | "string-width": "^5.0.1",
2616 | "strip-ansi": "^7.0.1"
2617 | },
2618 | "engines": {
2619 | "node": ">=12"
2620 | },
2621 | "funding": {
2622 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2623 | }
2624 | },
2625 | "node_modules/wrap-ansi-cjs": {
2626 | "name": "wrap-ansi",
2627 | "version": "7.0.0",
2628 | "license": "MIT",
2629 | "dependencies": {
2630 | "ansi-styles": "^4.0.0",
2631 | "string-width": "^4.1.0",
2632 | "strip-ansi": "^6.0.0"
2633 | },
2634 | "engines": {
2635 | "node": ">=10"
2636 | },
2637 | "funding": {
2638 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2639 | }
2640 | },
2641 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2642 | "version": "5.0.1",
2643 | "license": "MIT",
2644 | "engines": {
2645 | "node": ">=8"
2646 | }
2647 | },
2648 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2649 | "version": "4.3.0",
2650 | "license": "MIT",
2651 | "dependencies": {
2652 | "color-convert": "^2.0.1"
2653 | },
2654 | "engines": {
2655 | "node": ">=8"
2656 | },
2657 | "funding": {
2658 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2659 | }
2660 | },
2661 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
2662 | "version": "8.0.0",
2663 | "license": "MIT"
2664 | },
2665 | "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2666 | "version": "4.2.3",
2667 | "license": "MIT",
2668 | "dependencies": {
2669 | "emoji-regex": "^8.0.0",
2670 | "is-fullwidth-code-point": "^3.0.0",
2671 | "strip-ansi": "^6.0.1"
2672 | },
2673 | "engines": {
2674 | "node": ">=8"
2675 | }
2676 | },
2677 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2678 | "version": "6.0.1",
2679 | "license": "MIT",
2680 | "dependencies": {
2681 | "ansi-regex": "^5.0.1"
2682 | },
2683 | "engines": {
2684 | "node": ">=8"
2685 | }
2686 | },
2687 | "node_modules/ws": {
2688 | "version": "8.18.0",
2689 | "license": "MIT",
2690 | "engines": {
2691 | "node": ">=10.0.0"
2692 | },
2693 | "peerDependencies": {
2694 | "bufferutil": "^4.0.1",
2695 | "utf-8-validate": ">=5.0.2"
2696 | },
2697 | "peerDependenciesMeta": {
2698 | "bufferutil": {
2699 | "optional": true
2700 | },
2701 | "utf-8-validate": {
2702 | "optional": true
2703 | }
2704 | }
2705 | },
2706 | "node_modules/xtend": {
2707 | "version": "4.0.2",
2708 | "license": "MIT",
2709 | "engines": {
2710 | "node": ">=0.4"
2711 | }
2712 | },
2713 | "node_modules/yaml": {
2714 | "version": "2.7.0",
2715 | "license": "ISC",
2716 | "bin": {
2717 | "yaml": "bin.mjs"
2718 | },
2719 | "engines": {
2720 | "node": ">= 14"
2721 | }
2722 | },
2723 | "node_modules/zod": {
2724 | "version": "3.24.1",
2725 | "license": "MIT",
2726 | "peer": true,
2727 | "funding": {
2728 | "url": "https://github.com/sponsors/colinhacks"
2729 | }
2730 | },
2731 | "node_modules/zod-to-json-schema": {
2732 | "version": "3.24.1",
2733 | "license": "ISC",
2734 | "peerDependencies": {
2735 | "zod": "^3.24.1"
2736 | }
2737 | }
2738 | }
2739 | }
2740 |
--------------------------------------------------------------------------------
/examples/nextjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint",
10 | "format": "pnpm prettier --write ."
11 | },
12 | "dependencies": {
13 | "@upstash/rag-chat-component": "^0.2.2",
14 | "next": "15.1.4",
15 | "react": "^19.0.0",
16 | "react-dom": "^19.0.0"
17 | },
18 | "devDependencies": {
19 | "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
20 | "@types/node": "^20",
21 | "@types/react": "^19",
22 | "@types/react-dom": "^19",
23 | "postcss": "^8",
24 | "prettier": "^3.4.2",
25 | "prettier-plugin-tailwindcss": "^0.6.9",
26 | "tailwindcss": "^3.4.1",
27 | "typescript": "^5"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/nextjs/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/examples/nextjs/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: "always",
3 | bracketSameLine: false,
4 | bracketSpacing: true,
5 | semi: true,
6 | singleQuote: false,
7 | jsxSingleQuote: false,
8 | trailingComma: "all",
9 | singleAttributePerLine: false,
10 | importOrderSeparation: true,
11 | importOrderSortSpecifiers: true,
12 | importOrderBuiltinModulesToTop: true,
13 | tailwindFunctions: ["clsx"],
14 | plugins: [
15 | "@ianvs/prettier-plugin-sort-imports",
16 | "prettier-plugin-tailwindcss",
17 | ],
18 | };
19 |
--------------------------------------------------------------------------------
/examples/nextjs/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | export default {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
8 | "./node_modules/@upstash/rag-chat-component/**/*.{js,mjs}",
9 | ],
10 | theme: {
11 | extend: {
12 | fontFamily: {
13 | sans: ["var(--font-sans)"],
14 | display: ["var(--font-display)"],
15 | },
16 | },
17 | },
18 | } satisfies Config;
19 |
--------------------------------------------------------------------------------
/examples/nextjs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/nextjs/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "functions": {
3 | "app/**/*": {
4 | "maxDuration": 30
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello via Bun!");
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@upstash/rag-chat-component",
3 | "description": "Streaming Chat Component with Persistent History",
4 | "version": "0.2.2",
5 | "module": "index.ts",
6 | "main": "./dist/client/index.mjs",
7 | "types": "./dist/client/index.d.ts",
8 | "exports": {
9 | ".": {
10 | "import": "./dist/client/index.mjs"
11 | },
12 | "./styles.css": "./dist/client/styles.mjs"
13 | },
14 | "files": [
15 | "dist"
16 | ],
17 | "peerDependencies": {
18 | "next": "^14 || ^15",
19 | "react": "^18 || ^19",
20 | "typescript": "^5"
21 | },
22 | "scripts": {
23 | "build": "tsup",
24 | "playground": "cd playground && npm run dev"
25 | },
26 | "dependencies": {
27 | "@ai-sdk/openai": "^1.0.18",
28 | "@radix-ui/react-scroll-area": "^1.2.2",
29 | "@radix-ui/react-slot": "^1.1.1",
30 | "@upstash/redis": "^1.34.3",
31 | "@upstash/vector": "^1.2.0",
32 | "ai": "^4.0.33",
33 | "class-variance-authority": "^0.7.1",
34 | "clsx": "^2.1.1",
35 | "lodash.debounce": "^4.0.8",
36 | "lucide-react": "^0.471.0",
37 | "react": "^19",
38 | "react-dom": "^19",
39 | "react-textarea-autosize": "^8.5.7",
40 | "tailwind-merge": "^2.6.0",
41 | "tailwindcss": "^3.4.1",
42 | "tailwindcss-animate": "^1.0.7",
43 | "together-ai": "^0.11.1"
44 | },
45 | "devDependencies": {
46 | "@types/bun": "latest",
47 | "@types/lodash.debounce": "^4.0.9",
48 | "@types/node": "^22",
49 | "@types/react": "^19",
50 | "@types/react-dom": "^19",
51 | "autoprefixer": "^10.4.20",
52 | "esbuild-fix-imports-plugin": "^1.0.10",
53 | "postcss": "^8",
54 | "postcss-prefix-selector": "^2.1.0",
55 | "prettier": "^3.4.2",
56 | "prettier-plugin-tailwindcss": "^0.6.9",
57 | "tsup": "^8.2.0"
58 | },
59 | "homepage": "https://github.com/upstash/rag-chat-component#readme",
60 | "author": "Fahreddin Ozcan",
61 | "license": "MIT",
62 | "bugs": {
63 | "url": "https://github.com/upstash/rag-chat-component/issues"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/playground/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 | .pnpm-debug.log*
32 |
33 | # env files (can opt-in for committing if needed)
34 | .env*
35 |
36 | # vercel
37 | .vercel
38 |
39 | # typescript
40 | *.tsbuildinfo
41 | next-env.d.ts
42 |
--------------------------------------------------------------------------------
/playground/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37 |
--------------------------------------------------------------------------------
/playground/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 |
5 | const __filename = fileURLToPath(import.meta.url);
6 | const __dirname = dirname(__filename);
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | });
11 |
12 | const eslintConfig = [
13 | ...compat.extends("next/core-web-vitals", "next/typescript"),
14 | ];
15 |
16 | export default eslintConfig;
17 |
--------------------------------------------------------------------------------
/playground/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/playground/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "react": "^19.0.0",
13 | "react-dom": "^19.0.0",
14 | "next": "15.1.6"
15 | },
16 | "exports": {
17 | ".": {
18 | "import": "./src/client/index.ts"
19 | }
20 | },
21 | "devDependencies": {
22 | "typescript": "^5",
23 | "@types/node": "^20",
24 | "@types/react": "^19",
25 | "@types/react-dom": "^19",
26 | "postcss": "^8",
27 | "tailwindcss": "^3.4.1",
28 | "eslint": "^9",
29 | "eslint-config-next": "15.1.6",
30 | "@eslint/eslintrc": "^3"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/playground/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/playground/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/playground/public/globe.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/playground/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/playground/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/playground/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/playground/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/playground/src/app/favicon.ico
--------------------------------------------------------------------------------
/playground/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --background: #ffffff;
7 | --foreground: #171717;
8 | }
9 |
10 | @media (prefers-color-scheme: dark) {
11 | :root {
12 | --background: #0a0a0a;
13 | --foreground: #ededed;
14 | }
15 | }
16 |
17 | body {
18 | color: var(--foreground);
19 | background: var(--background);
20 | font-family: Arial, Helvetica, sans-serif;
21 | }
22 |
--------------------------------------------------------------------------------
/playground/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Geist, Geist_Mono } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const geistSans = Geist({
6 | variable: "--font-geist-sans",
7 | subsets: ["latin"],
8 | });
9 |
10 | const geistMono = Geist_Mono({
11 | variable: "--font-geist-mono",
12 | subsets: ["latin"],
13 | });
14 |
15 | export const metadata: Metadata = {
16 | title: "Create Next App",
17 | description: "Generated by create next app",
18 | };
19 |
20 | export default function RootLayout({
21 | children,
22 | }: Readonly<{
23 | children: React.ReactNode;
24 | }>) {
25 | return (
26 |
27 |
30 | {children}
31 |
32 |
33 | );
34 | }
35 |
--------------------------------------------------------------------------------
/playground/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import { ChatComponent } from "@/client/components/chat-component";
2 |
3 | export default function Home() {
4 | return (
5 |
6 | Component Playground
7 |
8 |
9 |
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/playground/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | export default {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | '../src/**/*.{js,ts,jsx,tsx,mdx}',
9 | ],
10 | theme: {
11 | extend: {
12 | colors: {
13 | background: "var(--background)",
14 | foreground: "var(--foreground)",
15 | },
16 | },
17 | },
18 | plugins: [],
19 | } satisfies Config;
20 |
--------------------------------------------------------------------------------
/playground/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["../src/*"],
23 | "@playground/*": ["./src/*"]
24 | }
25 | },
26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
27 | "exclude": ["node_modules"]
28 | }
29 |
--------------------------------------------------------------------------------
/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import("postcss-load-config").Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | autoprefixer: {},
6 | "postcss-prefix-selector": {
7 | prefix: ".ups-chat",
8 | },
9 | },
10 | };
11 |
12 | export default config;
13 |
--------------------------------------------------------------------------------
/public/images/vector-databrowser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/public/images/vector-databrowser.png
--------------------------------------------------------------------------------
/public/images/widget-closed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/public/images/widget-closed.png
--------------------------------------------------------------------------------
/public/images/widget-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/upstash/rag-chat-component/cd9ea021276dc5bf9f5cab9ab8770de858ba9bfd/public/images/widget-open.png
--------------------------------------------------------------------------------
/src/client/components/chat-component.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { ScrollArea } from "@radix-ui/react-scroll-area";
4 |
5 | import * as React from "react";
6 | import { useEffect, useRef, useState } from "react";
7 | import { serverChat } from "../../server/actions/chat";
8 | import { deleteHistory, getHistory } from "../../server/actions/history";
9 |
10 | import type { Message } from "../../server/lib/types";
11 | import { cn } from "./lib/utils";
12 | import { Button } from "./ui/button";
13 | import { ArrowUp, Bot, Loader2, X } from "lucide-react";
14 | import TextareaAutosize from "react-textarea-autosize";
15 | import { readStreamableValue } from "ai/rsc";
16 |
17 | type ChatComponentProps = {
18 | theme?: {
19 | triggerButtonIcon?: React.ReactNode;
20 | triggerButtonColor?: string;
21 | };
22 | };
23 |
24 | export const ChatComponent = ({ theme }: ChatComponentProps) => {
25 | const [conversation, setConversation] = useState([]);
26 | const [sessionId, setSessionId] = useState("");
27 | const [input, setInput] = useState("");
28 | const [isLoading, setIsLoading] = useState(false);
29 | const [isOpen, setIsOpen] = useState(false);
30 | const [isStreaming, setIsStreaming] = useState(false);
31 | const scrollAreaRef = useRef(null);
32 | const lastMessageRef = useRef(null);
33 | const inputRef = useRef(null);
34 |
35 | const toggleChat = () => {
36 | setIsOpen(!isOpen);
37 | if (!isOpen) {
38 | setTimeout(() => inputRef.current?.focus(), 100);
39 | }
40 | };
41 |
42 | const scrollToBottom = () => {
43 | if (lastMessageRef.current) {
44 | lastMessageRef.current.scrollIntoView({ behavior: "smooth" });
45 | }
46 | };
47 |
48 | useEffect(() => {
49 | let id = localStorage.getItem("chat_session_id");
50 | if (!id) {
51 | id = "session_" + Math.random().toString(36).substr(2, 9);
52 | localStorage.setItem("chat_session_id", id);
53 | }
54 | setSessionId(id);
55 |
56 | const fetchHistory = async () => {
57 | try {
58 | setIsLoading(true);
59 | const { messages } = await getHistory(id);
60 | if (messages.length > 0) {
61 | setConversation(messages);
62 | }
63 | } catch (error) {
64 | console.error("Error fetching chat history:", error);
65 | } finally {
66 | setIsLoading(false);
67 | }
68 | };
69 |
70 | fetchHistory();
71 | }, []);
72 |
73 | useEffect(() => {
74 | scrollToBottom();
75 | }, [conversation]);
76 |
77 | useEffect(() => {
78 | if (isStreaming) {
79 | const intervalId = setInterval(scrollToBottom, 100);
80 | return () => clearInterval(intervalId);
81 | }
82 | }, [isStreaming]);
83 |
84 | const handleSubmit = async (e: React.FormEvent) => {
85 | e.preventDefault();
86 | if (!input.trim()) return;
87 |
88 | const userMessage: Message = {
89 | content: input,
90 | role: "user",
91 | id: Date.now().toString(),
92 | };
93 |
94 | const newConversation = [...conversation, userMessage];
95 | setConversation(newConversation);
96 | setInput("");
97 | setIsLoading(true);
98 |
99 | try {
100 | const { output } = await serverChat({
101 | messages: newConversation,
102 | sessionId,
103 | });
104 | setIsStreaming(true);
105 | let aiMessage: Message = {
106 | content: "",
107 | role: "assistant",
108 | id: (Date.now() + 1).toString(),
109 | };
110 | setConversation((prev) => [...prev, aiMessage]);
111 |
112 | let messageReceived = false;
113 | for await (const delta of readStreamableValue(output)) {
114 | if (delta) {
115 | messageReceived = true;
116 | }
117 | aiMessage.content += delta;
118 | setConversation((prev) =>
119 | prev.map((msg) =>
120 | msg.id === aiMessage.id
121 | ? { ...msg, content: aiMessage.content }
122 | : msg,
123 | ),
124 | );
125 | }
126 |
127 | if (!messageReceived || !aiMessage.content.trim()) {
128 | setConversation((prev) => [
129 | ...prev.slice(0, -1),
130 | {
131 | content: "No response received. Please try again.",
132 | role: "error",
133 | id: (Date.now() + 2).toString(),
134 | },
135 | ]);
136 | }
137 | } catch (error) {
138 | console.error("Error in AI response:", error);
139 | setConversation((prev) => [
140 | ...prev.slice(0, -1),
141 | {
142 | content: "An error occurred. Please try again.",
143 | role: "error",
144 | id: (Date.now() + 3).toString(),
145 | },
146 | ]);
147 | } finally {
148 | setIsLoading(false);
149 | setIsStreaming(false);
150 | }
151 | };
152 |
153 | const handleClearHistory = async () => {
154 | if (!sessionId || isLoading) return;
155 |
156 | setIsLoading(true);
157 | try {
158 | const { success } = await deleteHistory(sessionId);
159 | if (success) {
160 | setConversation([]);
161 | }
162 | } catch (error) {
163 | console.error("Error clearing chat history:", error);
164 | } finally {
165 | setIsLoading(false);
166 | }
167 | };
168 |
169 | const renderMessage = (message: Message, index: number) => {
170 | const isLastMessage = index === conversation.length - 1;
171 | const showDots = isLastMessage && isStreaming;
172 | const isUser = message.role === "user";
173 | const isError = message.role === "error";
174 |
175 | return (
176 |
181 | {isUser ? (
182 | // User message
183 |
184 | {message.content}
185 |
186 | ) : isError ? (
187 |
188 |
189 |
190 |
191 | {message.content}
192 |
193 |
194 | ) : (
195 | // Assistant message
196 |
197 |
198 |
199 |
200 | {message.content}
201 | {showDots && (
202 |
203 | ...
204 |
205 | )}
206 |
207 |
208 | )}
209 |
210 | );
211 | };
212 |
213 | const hasMessages = conversation.length > 0;
214 |
215 | return (
216 |
217 | {/* >>> Trigger Button */}
218 |
231 | {theme?.triggerButtonIcon ?? }
232 |
233 |
234 | {/* >>> Chat Modal */}
235 |
251 | {/* Chat Header */}
252 |
280 |
281 | {/* Chat Body */}
282 |
286 | {/* empty message */}
287 | {!hasMessages && !isLoading && (
288 |
289 |
290 | Chat with the AI assistant
291 |
292 |
293 | )}
294 |
295 | {/* chat bubbles */}
296 |
297 | {conversation.map(renderMessage)}
298 | {isLoading && !isStreaming && (
299 |
300 |
301 |
302 | )}
303 |
304 |
305 |
306 | {/* Chat Form */}
307 |
346 |
347 |
348 | );
349 | };
350 |
--------------------------------------------------------------------------------
/src/client/components/lib/utils.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from "clsx";
2 | import { twMerge } from "tailwind-merge";
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
--------------------------------------------------------------------------------
/src/client/components/styles.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/src/client/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Slot } from "@radix-ui/react-slot";
3 | import { cva, type VariantProps } from "class-variance-authority";
4 | import { cn } from "../lib/utils";
5 |
6 | const buttonVariants = cva(
7 | "inline-flex items-center justify-center whitespace-nowrap rounded-md disabled:pointer-events-none disabled:opacity-50",
8 | {
9 | variants: {
10 | variant: {
11 | default: "bg-black text-white",
12 | secondary: "bg-black text-white",
13 | ghost: "",
14 | },
15 | size: {
16 | default: "h-10 px-4 py-2",
17 | sm: "h-8 rounded-md px-3",
18 | icon: "size-8 rounded-full p-0",
19 | },
20 | },
21 | defaultVariants: {
22 | variant: "default",
23 | size: "default",
24 | },
25 | },
26 | );
27 |
28 | export interface ButtonProps
29 | extends React.ButtonHTMLAttributes,
30 | VariantProps {
31 | asChild?: boolean;
32 | }
33 |
34 | const Button = React.forwardRef(
35 | ({ className, variant, size, asChild = false, ...props }, ref) => {
36 | const Comp = asChild ? Slot : "button";
37 | return (
38 |
43 | );
44 | },
45 | );
46 | Button.displayName = "Button";
47 |
48 | export { Button, buttonVariants };
49 |
--------------------------------------------------------------------------------
/src/client/components/ui/scroll-area.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import * as React from "react";
4 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
5 |
6 | import { cn } from "../lib/utils";
7 |
8 | const ScrollArea = React.forwardRef<
9 | React.ElementRef,
10 | React.ComponentPropsWithoutRef
11 | >(({ className, children, ...props }, ref) => (
12 |
17 |
18 | {children}
19 |
20 |
21 |
22 |
23 | ));
24 | ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
25 |
26 | const ScrollBar = React.forwardRef<
27 | React.ElementRef,
28 | React.ComponentPropsWithoutRef
29 | >(({ className, orientation = "vertical", ...props }, ref) => (
30 |
43 |
44 |
45 | ));
46 | ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
47 |
48 | export { ScrollArea, ScrollBar };
49 |
--------------------------------------------------------------------------------
/src/client/index.ts:
--------------------------------------------------------------------------------
1 | export { ChatComponent } from "./components/chat-component";
2 |
--------------------------------------------------------------------------------
/src/server/actions/chat.ts:
--------------------------------------------------------------------------------
1 | "use server";
2 |
3 | import { Index } from "@upstash/vector"
4 | import { createOpenAI } from "@ai-sdk/openai"
5 | import { streamText } from "ai"
6 | import { createStreamableValue, type StreamableValue } from "ai/rsc";
7 | import { DEFAULT_PROMPT } from "../constants";
8 | import type { Message } from "../lib/types";
9 | import { getHistoryClient } from "../lib/history/get-client";
10 |
11 | type StreamMessage = {
12 | role: 'user' | 'assistant';
13 | content: string;
14 | }
15 |
16 | const vectorIndex = new Index()
17 |
18 | const together = createOpenAI({
19 | apiKey: process.env.TOGETHER_API_KEY ?? "",
20 | baseURL: "https://api.together.xyz/v1",
21 |
22 | })
23 |
24 | const searchSimilarDocs = async (data: string, topK: number) => {
25 | const results = await vectorIndex.query({
26 | data,
27 | topK: topK ? topK : 5,
28 | includeMetadata: true,
29 | includeData: true,
30 | });
31 |
32 | return results
33 | }
34 |
35 | const history = getHistoryClient()
36 |
37 | export const serverChat = async ({
38 | messages,
39 | sessionId,
40 | }: {
41 | messages: Message[];
42 | sessionId: string;
43 | }): Promise<{ output: StreamableValue }> => {
44 | const userMessage = messages[messages.length - 1]
45 |
46 | await history.addMessage({
47 | message: userMessage,
48 | sessionId
49 | })
50 |
51 | const serverMessages = messages
52 | .filter(msg => msg.role !== 'error')
53 | .map(msg => ({
54 | role: msg.role,
55 | content: msg.content
56 | })) as StreamMessage[];
57 |
58 | const similarDocs = await searchSimilarDocs(userMessage.content, 5)
59 |
60 | const context = similarDocs.map(doc => doc.data).join("\n")
61 |
62 | const chatMessages = messages.map(message => message.content).join("\n")
63 |
64 | const system = DEFAULT_PROMPT({ context, question: userMessage.content, chatMessages })
65 |
66 | const stream = createStreamableValue("");
67 |
68 | (async () => {
69 | const { textStream } = streamText({
70 | model: together(process.env.TOGETHER_MODEL ?? "deepseek-ai/DeepSeek-V3"),
71 | system,
72 | messages: serverMessages,
73 |
74 | async onFinish({ text }) {
75 | await history.addMessage({
76 | message: {
77 | role: "assistant",
78 | content: text,
79 | id: Date.now().toString(),
80 | },
81 | sessionId
82 | })
83 | },
84 |
85 | })
86 |
87 | for await (const delta of textStream) {
88 | stream.update(delta);
89 | }
90 |
91 | stream.done();
92 | })();
93 |
94 | return { output: stream.value }
95 | };
96 |
--------------------------------------------------------------------------------
/src/server/actions/history.ts:
--------------------------------------------------------------------------------
1 | 'use server'
2 |
3 | import { getHistoryClient } from "../lib/history/get-client";
4 | import type { Message } from "../lib/types";
5 |
6 | const history = getHistoryClient();
7 |
8 | export async function getHistory(sessionId: string): Promise<{ messages: Message[] }> {
9 | try {
10 | const messages = await history.getMessages({ sessionId });
11 | return { messages };
12 | } catch (error) {
13 | console.error("Failed to fetch chat history:", error);
14 | return { messages: [] };
15 | }
16 | }
17 |
18 | export async function deleteHistory(sessionId: string): Promise<{ success: boolean }> {
19 | try {
20 | await history.deleteMessages({ sessionId });
21 | return { success: true };
22 | } catch (error) {
23 | console.error("Failed to delete chat history:", error);
24 | return { success: false };
25 | }
26 | }
--------------------------------------------------------------------------------
/src/server/constants.ts:
--------------------------------------------------------------------------------
1 | type PromptParameters = {
2 | chatMessages?: string;
3 | question: string;
4 | context: string;
5 | };
6 |
7 | type Prompt = ({ question, chatMessages, context }: PromptParameters) => string;
8 |
9 | export const DEFAULT_PROMPT: Prompt = ({ context, question, chatMessages }) =>
10 | `You are a concise AI assistant helping users on a website. Provide brief, clear answers in 1-2 sentences when possible.
11 |
12 | Context and chat history are provided to help you answer questions accurately. Only use information from these sources.
13 |
14 | ${context ? `Context: ${context}\n` : ''}${chatMessages ? `Previous messages: ${chatMessages}\n` : ''}
15 | Q: ${question}
16 | A:`;
17 |
18 | export const DEFAULT_CHAT_SESSION_ID = "upstash-rag-chat-session";
19 |
20 | export const DEFAULT_HISTORY_LENGTH = 5;
--------------------------------------------------------------------------------
/src/server/index.ts:
--------------------------------------------------------------------------------
1 | export { serverChat } from "./actions/chat";
2 |
--------------------------------------------------------------------------------
/src/server/lib/history/get-client.ts:
--------------------------------------------------------------------------------
1 | import type { BaseMessageHistory } from "../types";
2 | import { RedisHistory } from "./redis";
3 | import { InMemoryHistory } from "./in-memory";
4 |
5 | export const getHistoryClient = (): BaseMessageHistory => {
6 | const redisUrl = process.env.UPSTASH_REDIS_REST_URL;
7 | const redisToken = process.env.UPSTASH_REDIS_REST_TOKEN;
8 |
9 | if (redisUrl && redisToken) {
10 | return new RedisHistory({
11 | config: {
12 | url: redisUrl,
13 | token: redisToken,
14 | }
15 | });
16 | }
17 |
18 | return new InMemoryHistory();
19 | }
--------------------------------------------------------------------------------
/src/server/lib/history/in-memory.ts:
--------------------------------------------------------------------------------
1 | import type { Message, BaseMessageHistory } from "../types";
2 | import { DEFAULT_CHAT_SESSION_ID, DEFAULT_HISTORY_LENGTH } from "../../constants";
3 |
4 | declare global {
5 | var store: Record;
6 | }
7 | export class InMemoryHistory implements BaseMessageHistory {
8 | constructor() {
9 | if (!global.store) global.store = {};
10 | }
11 |
12 | async addMessage(params: {
13 | message: Message;
14 | sessionId: string;
15 | sessionTTL?: number;
16 | }): Promise {
17 | const { message, sessionId = DEFAULT_CHAT_SESSION_ID } = params;
18 | if (!global.store[sessionId]) {
19 | global.store[sessionId] = { messages: [] };
20 | }
21 |
22 | const oldMessages = global.store[sessionId].messages || [];
23 | const newMessages = [message, ...oldMessages];
24 | global.store[sessionId].messages = newMessages;
25 | }
26 |
27 | async deleteMessages({ sessionId }: { sessionId: string }): Promise {
28 | if (!global.store[sessionId]) {
29 | return;
30 | }
31 | global.store[sessionId].messages = [];
32 | }
33 |
34 | async getMessages({
35 | sessionId = DEFAULT_CHAT_SESSION_ID,
36 | amount = DEFAULT_HISTORY_LENGTH,
37 | startIndex = 0,
38 | }): Promise {
39 | if (!global.store[sessionId]) {
40 | global.store[sessionId] = { messages: [] };
41 | }
42 |
43 | const messages = global.store[sessionId]?.messages ?? [];
44 | const slicedMessages = messages.slice(startIndex, startIndex + amount);
45 | return slicedMessages.reverse();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/server/lib/history/redis.ts:
--------------------------------------------------------------------------------
1 | import { Redis, type RedisConfigNodejs } from "@upstash/redis";
2 | import { DEFAULT_CHAT_SESSION_ID, DEFAULT_HISTORY_LENGTH } from "../../constants";
3 | import type { Message, BaseMessageHistory } from "../types";
4 |
5 | export type RedisHistoryConfig = {
6 | config?: RedisConfigNodejs;
7 | client?: Redis;
8 | };
9 |
10 | export class RedisHistory implements BaseMessageHistory {
11 | public client: Redis;
12 |
13 | constructor(config: RedisHistoryConfig) {
14 | const { config: redisConfig, client } = config;
15 |
16 | if (client) {
17 | this.client = client;
18 | } else if (redisConfig) {
19 | this.client = new Redis(redisConfig);
20 | } else {
21 | throw new Error(
22 | "Redis message stores require either a config object or a pre-configured client."
23 | );
24 | }
25 | }
26 |
27 | async addMessage(params: {
28 | message: Message;
29 | sessionId: string;
30 | sessionTTL?: number;
31 | }): Promise {
32 | const { message, sessionId = DEFAULT_CHAT_SESSION_ID, sessionTTL } = params;
33 | await this.client.lpush(sessionId, JSON.stringify(message));
34 | if (sessionTTL) {
35 | await this.client.expire(sessionId, sessionTTL);
36 | }
37 | }
38 |
39 | async deleteMessages({ sessionId }: { sessionId: string }): Promise {
40 | await this.client.del(sessionId);
41 | }
42 |
43 | async getMessages({
44 | sessionId = DEFAULT_CHAT_SESSION_ID,
45 | amount = DEFAULT_HISTORY_LENGTH,
46 | startIndex = 0,
47 | }): Promise {
48 | const endIndex = startIndex + amount - 1;
49 | const messages = await this.client.lrange(
50 | sessionId,
51 | startIndex,
52 | endIndex
53 | );
54 |
55 | return messages.reverse();
56 | }
57 | }
--------------------------------------------------------------------------------
/src/server/lib/types.ts:
--------------------------------------------------------------------------------
1 | export type Message = {
2 | role: "user" | "assistant" | "error"
3 | content: string;
4 | id: string
5 | }
6 |
7 | export interface BaseMessageHistory {
8 | addMessage(params: {
9 | message: Message;
10 | sessionId: string;
11 | sessionTTL?: number;
12 | }): Promise;
13 |
14 | deleteMessages(params: {
15 | sessionId: string
16 | }): Promise;
17 |
18 | getMessages(params: {
19 | sessionId: string;
20 | amount?: number;
21 | startIndex?: number;
22 | }): Promise;
23 | }
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config = {
4 | content: ["./src/**/*.{ts,tsx}"],
5 | theme: {
6 | screens: {
7 | 'sm': '640px',
8 | 'md': '768px',
9 | 'lg': '1024px',
10 | 'xl': '1280px',
11 | '2xl': '1536px',
12 | },
13 | extend: {
14 | animation: {
15 | "accordion-down": "accordion-down 0.2s ease-out",
16 | "accordion-up": "accordion-up 0.2s ease-out",
17 | },
18 | },
19 | },
20 | plugins: [require("tailwindcss-animate")],
21 | } satisfies Config;
22 |
23 | export default config;
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["ESNext", "DOM"],
4 | "declarationDir": "dist",
5 | "declaration": true,
6 | "target": "ESNext",
7 | "module": "ES2022",
8 | "moduleDetection": "force",
9 | "jsx": "react-jsx",
10 | "allowJs": true,
11 | "outDir": "./dist",
12 | "types": ["react/experimental", "node"],
13 | "jsxImportSource": "react",
14 | "allowSyntheticDefaultImports": true,
15 | "resolveJsonModule": true,
16 | "skipDefaultLibCheck": true,
17 | "moduleResolution": "Bundler",
18 | "allowImportingTsExtensions": true,
19 | "verbatimModuleSyntax": true,
20 | "noEmit": true,
21 | "strict": true,
22 | "skipLibCheck": true,
23 | "noFallthroughCasesInSwitch": true,
24 | "noUnusedLocals": false,
25 | "noUnusedParameters": false,
26 | "noPropertyAccessFromIndexSignature": false
27 | },
28 | "include": ["src/**/*", "./package.json"],
29 | "exclude": ["node_modules"]
30 | }
31 |
--------------------------------------------------------------------------------
/tsup.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "tsup";
2 | import { fixExtensionsPlugin } from "esbuild-fix-imports-plugin";
3 |
4 | export default defineConfig([
5 | {
6 | entry: ["src/client"],
7 | outDir: "dist/client",
8 | external: ["react", "next"],
9 |
10 | // 👇 important: cjs doesn't work well
11 | format: "esm",
12 | splitting: false,
13 | sourcemap: false,
14 | clean: true,
15 | dts: true,
16 |
17 | // 👇 important: do not bundle
18 | bundle: false,
19 | minify: false,
20 | treeshake: false,
21 | injectStyle: true,
22 | esbuildPlugins: [fixExtensionsPlugin()],
23 | },
24 | {
25 | entry: ["src/server"],
26 | outDir: "dist/server",
27 | external: ["react", "next"],
28 |
29 | // 👇 important: cjs doesn't work well
30 | format: "esm",
31 | splitting: false,
32 | sourcemap: false,
33 | clean: true,
34 | dts: true,
35 |
36 | // 👇 important: do not bundle
37 | bundle: false,
38 | minify: false,
39 | esbuildPlugins: [fixExtensionsPlugin()],
40 | },
41 | ]);
42 |
--------------------------------------------------------------------------------