From 44bda1500aa40da39817ec682e5611d938a4a589 Mon Sep 17 00:00:00 2001 From: Diego Souza Date: Tue, 26 Nov 2024 17:39:13 -0300 Subject: [PATCH 01/27] Check the render method of SlotClone. #432 --- app/components/chat/Messages.client.tsx | 8 +- app/components/ui/IconButton.tsx | 75 ++++++++------- app/components/ui/Tooltip.tsx | 118 +++++++++++++----------- 3 files changed, 107 insertions(+), 94 deletions(-) diff --git a/app/components/chat/Messages.client.tsx b/app/components/chat/Messages.client.tsx index 4a2ac6ac..2765144e 100644 --- a/app/components/chat/Messages.client.tsx +++ b/app/components/chat/Messages.client.tsx @@ -69,8 +69,8 @@ export const Messages = React.forwardRef((props: {!isUserMessage && (
- - {messageId && ( + {messageId && ( + - ); - }, + onClick?.(event); + }} + > + {children ? children :
} + + ); + }, + ), ); function getIconSize(size: IconSize) { diff --git a/app/components/ui/Tooltip.tsx b/app/components/ui/Tooltip.tsx index 4e22f540..278fa1ea 100644 --- a/app/components/ui/Tooltip.tsx +++ b/app/components/ui/Tooltip.tsx @@ -1,8 +1,9 @@ import * as Tooltip from '@radix-ui/react-tooltip'; +import { forwardRef, type ForwardedRef, type ReactElement } from 'react'; interface TooltipProps { tooltip: React.ReactNode; - children: React.ReactNode; + children: ReactElement; sideOffset?: number; className?: string; arrowClassName?: string; @@ -12,62 +13,67 @@ interface TooltipProps { delay?: number; } -const WithTooltip = ({ - tooltip, - children, - sideOffset = 5, - className = '', - arrowClassName = '', - tooltipStyle = {}, - position = 'top', - maxWidth = 250, - delay = 0, -}: TooltipProps) => { - return ( - - {children} - - -
{tooltip}
- , + ) => { + return ( + + {children} + + - - - - ); -}; + sideOffset={sideOffset} + style={{ + maxWidth, + ...tooltipStyle, + }} + > +
{tooltip}
+ +
+
+
+ ); + }, +); export default WithTooltip; From fcb61ba49990d1d0cc13d05a0958007b6e9c1c38 Mon Sep 17 00:00:00 2001 From: eduardruzga Date: Mon, 9 Dec 2024 17:26:33 +0200 Subject: [PATCH 02/27] Refactor to use newver v4 version of Vercel AI package --- app/components/chat/Chat.client.tsx | 11 +- app/components/chat/ImportFolderButton.tsx | 8 +- app/components/chat/SendButton.client.tsx | 1 + app/routes/api.chat.ts | 20 +- app/routes/api.enhancer.ts | 54 +- app/utils/fileUtils.ts | 28 +- app/utils/folderImport.ts | 41 +- package.json | 2 +- pnpm-lock.yaml | 884 ++++++++------------- 9 files changed, 441 insertions(+), 608 deletions(-) diff --git a/app/components/chat/Chat.client.tsx b/app/components/chat/Chat.client.tsx index c6a01eef..f47abec9 100644 --- a/app/components/chat/Chat.client.tsx +++ b/app/components/chat/Chat.client.tsx @@ -112,13 +112,22 @@ export const ChatImpl = memo( body: { apiKeys, }, + sendExtraMessageFields: true, onError: (error) => { logger.error('Request failed\n\n', error); toast.error( 'There was an error processing your request: ' + (error.message ? error.message : 'No details were returned'), ); }, - onFinish: () => { + onFinish: (message, response) => { + const usage = response.usage; + + if (usage) { + console.log('Token usage:', usage); + + // You can now use the usage data as needed + } + logger.debug('Finished streaming'); }, initialMessages, diff --git a/app/components/chat/ImportFolderButton.tsx b/app/components/chat/ImportFolderButton.tsx index e766a716..6cbfcacf 100644 --- a/app/components/chat/ImportFolderButton.tsx +++ b/app/components/chat/ImportFolderButton.tsx @@ -1,8 +1,8 @@ import React, { useState } from 'react'; import type { Message } from 'ai'; import { toast } from 'react-toastify'; -import { MAX_FILES, isBinaryFile, shouldIncludeFile } from '../../utils/fileUtils'; -import { createChatFromFolder } from '../../utils/folderImport'; +import { MAX_FILES, isBinaryFile, shouldIncludeFile } from '~/utils/fileUtils'; +import { createChatFromFolder } from '~/utils/folderImport'; interface ImportFolderButtonProps { className?: string; @@ -17,12 +17,14 @@ export const ImportFolderButton: React.FC = ({ classNam if (allFiles.length > MAX_FILES) { toast.error( - `This folder contains ${allFiles.length.toLocaleString()} files. This product is not yet optimized for very large projects. Please select a folder with fewer than ${MAX_FILES.toLocaleString()} files.` + `This folder contains ${allFiles.length.toLocaleString()} files. This product is not yet optimized for very large projects. Please select a folder with fewer than ${MAX_FILES.toLocaleString()} files.`, ); return; } + const folderName = allFiles[0]?.webkitRelativePath.split('/')[0] || 'Unknown Folder'; setIsLoading(true); + const loadingToast = toast.loading(`Importing ${folderName}...`); try { diff --git a/app/components/chat/SendButton.client.tsx b/app/components/chat/SendButton.client.tsx index c5aa8304..389ca3bf 100644 --- a/app/components/chat/SendButton.client.tsx +++ b/app/components/chat/SendButton.client.tsx @@ -23,6 +23,7 @@ export const SendButton = ({ show, isStreaming, disabled, onClick }: SendButtonP disabled={disabled} onClick={(event) => { event.preventDefault(); + if (!disabled) { onClick?.(event); } diff --git a/app/routes/api.chat.ts b/app/routes/api.chat.ts index 00732745..35802ede 100644 --- a/app/routes/api.chat.ts +++ b/app/routes/api.chat.ts @@ -8,17 +8,15 @@ export async function action(args: ActionFunctionArgs) { return chatAction(args); } -function parseCookies(cookieHeader: string) { - const cookies: any = {}; +function parseCookies(cookieHeader: string): Record { + const cookies: Record = {}; - // Split the cookie string by semicolons and spaces const items = cookieHeader.split(';').map((cookie) => cookie.trim()); items.forEach((item) => { const [name, ...rest] = item.split('='); if (name && rest) { - // Decode the name and value, and join value parts in case it contains '=' const decodedName = decodeURIComponent(name.trim()); const decodedValue = decodeURIComponent(rest.join('=').trim()); cookies[decodedName] = decodedValue; @@ -35,16 +33,15 @@ async function chatAction({ context, request }: ActionFunctionArgs) { }>(); const cookieHeader = request.headers.get('Cookie'); - - // Parse the cookie's value (returns an object or null if no cookie exists) const apiKeys = JSON.parse(parseCookies(cookieHeader || '').apiKeys || '{}'); - const stream = new SwitchableStream(); try { const options: StreamingOptions = { toolChoice: 'none', - onFinish: async ({ text: content, finishReason }) => { + onFinish: async ({ text: content, finishReason, usage }) => { + console.log('usage', usage); + if (finishReason !== 'length') { return stream.close(); } @@ -62,13 +59,12 @@ async function chatAction({ context, request }: ActionFunctionArgs) { const result = await streamText(messages, context.cloudflare.env, options, apiKeys); - return stream.switchSource(result.toAIStream()); + return stream.switchSource(result.toDataStream()); }, }; const result = await streamText(messages, context.cloudflare.env, options, apiKeys); - - stream.switchSource(result.toAIStream()); + stream.switchSource(result.toDataStream()); return new Response(stream.readable, { status: 200, @@ -77,7 +73,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) { }, }); } catch (error: any) { - console.log(error); + console.error(error); if (error.message?.includes('API key')) { throw new Response('Invalid or missing API key', { diff --git a/app/routes/api.enhancer.ts b/app/routes/api.enhancer.ts index 0738ae49..7c284f80 100644 --- a/app/routes/api.enhancer.ts +++ b/app/routes/api.enhancer.ts @@ -1,5 +1,6 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare'; -import { StreamingTextResponse, parseStreamPart } from 'ai'; + +//import { StreamingTextResponse, parseStreamPart } from 'ai'; import { streamText } from '~/lib/.server/llm/stream-text'; import { stripIndents } from '~/utils/stripIndent'; import type { ProviderInfo } from '~/types/model'; @@ -45,32 +46,32 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) { `[Model: ${model}]\n\n[Provider: ${providerName}]\n\n` + stripIndents` You are a professional prompt engineer specializing in crafting precise, effective prompts. - Your task is to enhance prompts by making them more specific, actionable, and effective. + Your task is to enhance prompts by making them more specific, actionable, and effective. - I want you to improve the user prompt that is wrapped in \`\` tags. + I want you to improve the user prompt that is wrapped in \`\` tags. - For valid prompts: - - Make instructions explicit and unambiguous - - Add relevant context and constraints - - Remove redundant information - - Maintain the core intent - - Ensure the prompt is self-contained - - Use professional language + For valid prompts: + - Make instructions explicit and unambiguous + - Add relevant context and constraints + - Remove redundant information + - Maintain the core intent + - Ensure the prompt is self-contained + - Use professional language - For invalid or unclear prompts: - - Respond with a clear, professional guidance message - - Keep responses concise and actionable - - Maintain a helpful, constructive tone - - Focus on what the user should provide - - Use a standard template for consistency + For invalid or unclear prompts: + - Respond with clear, professional guidance + - Keep responses concise and actionable + - Maintain a helpful, constructive tone + - Focus on what the user should provide + - Use a standard template for consistency - IMPORTANT: Your response must ONLY contain the enhanced prompt text. - Do not include any explanations, metadata, or wrapper tags. + IMPORTANT: Your response must ONLY contain the enhanced prompt text. + Do not include any explanations, metadata, or wrapper tags. - - ${message} - - `, + + ${message} + + `, }, ], context.cloudflare.env, @@ -85,7 +86,7 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) { for (const line of lines) { try { - const parsed = parseStreamPart(line); + const parsed = JSON.parse(line); if (parsed.type === 'text') { controller.enqueue(encoder.encode(parsed.value)); @@ -100,7 +101,12 @@ async function enhancerAction({ context, request }: ActionFunctionArgs) { const transformedStream = result.toDataStream().pipeThrough(transformStream); - return new StreamingTextResponse(transformedStream); + return new Response(transformedStream, { + status: 200, + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + }); } catch (error: unknown) { console.log(error); diff --git a/app/utils/fileUtils.ts b/app/utils/fileUtils.ts index f6a52d90..fcf2a017 100644 --- a/app/utils/fileUtils.ts +++ b/app/utils/fileUtils.ts @@ -29,10 +29,12 @@ export const isBinaryFile = async (file: File): Promise => { for (let i = 0; i < buffer.length; i++) { const byte = buffer[i]; + if (byte === 0 || (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13)) { return true; } } + return false; }; @@ -41,8 +43,11 @@ export const shouldIncludeFile = (path: string): boolean => { }; const readPackageJson = async (files: File[]): Promise<{ scripts?: Record } | null> => { - const packageJsonFile = files.find(f => f.webkitRelativePath.endsWith('package.json')); - if (!packageJsonFile) return null; + const packageJsonFile = files.find((f) => f.webkitRelativePath.endsWith('package.json')); + + if (!packageJsonFile) { + return null; + } try { const content = await new Promise((resolve, reject) => { @@ -59,29 +64,32 @@ const readPackageJson = async (files: File[]): Promise<{ scripts?: Record => { - const hasFile = (name: string) => files.some(f => f.webkitRelativePath.endsWith(name)); +export const detectProjectType = async ( + files: File[], +): Promise<{ type: string; setupCommand: string; followupMessage: string }> => { + const hasFile = (name: string) => files.some((f) => f.webkitRelativePath.endsWith(name)); if (hasFile('package.json')) { const packageJson = await readPackageJson(files); const scripts = packageJson?.scripts || {}; - + // Check for preferred commands in priority order const preferredCommands = ['dev', 'start', 'preview']; - const availableCommand = preferredCommands.find(cmd => scripts[cmd]); - + const availableCommand = preferredCommands.find((cmd) => scripts[cmd]); + if (availableCommand) { return { type: 'Node.js', setupCommand: `npm install && npm run ${availableCommand}`, - followupMessage: `Found "${availableCommand}" script in package.json. Running "npm run ${availableCommand}" after installation.` + followupMessage: `Found "${availableCommand}" script in package.json. Running "npm run ${availableCommand}" after installation.`, }; } return { type: 'Node.js', setupCommand: 'npm install', - followupMessage: 'Would you like me to inspect package.json to determine the available scripts for running this project?' + followupMessage: + 'Would you like me to inspect package.json to determine the available scripts for running this project?', }; } @@ -89,7 +97,7 @@ export const detectProjectType = async (files: File[]): Promise<{ type: string; return { type: 'Static', setupCommand: 'npx --yes serve', - followupMessage: '' + followupMessage: '', }; } diff --git a/app/utils/folderImport.ts b/app/utils/folderImport.ts index 57cbe318..54d4666b 100644 --- a/app/utils/folderImport.ts +++ b/app/utils/folderImport.ts @@ -4,12 +4,13 @@ import { generateId, detectProjectType } from './fileUtils'; export const createChatFromFolder = async ( files: File[], binaryFiles: string[], - folderName: string + folderName: string, ): Promise => { const fileArtifacts = await Promise.all( files.map(async (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); + reader.onload = () => { const content = reader.result as string; const relativePath = file.webkitRelativePath.split('/').slice(1).join('/'); @@ -26,31 +27,37 @@ ${content} ); const project = await detectProjectType(files); - const setupCommand = project.setupCommand ? `\n\n\n${project.setupCommand}\n` : ''; + const setupCommand = project.setupCommand + ? `\n\n\n${project.setupCommand}\n` + : ''; const followupMessage = project.followupMessage ? `\n\n${project.followupMessage}` : ''; - const binaryFilesMessage = binaryFiles.length > 0 - ? `\n\nSkipped ${binaryFiles.length} binary files:\n${binaryFiles.map((f) => `- ${f}`).join('\n')}` - : ''; + const binaryFilesMessage = + binaryFiles.length > 0 + ? `\n\nSkipped ${binaryFiles.length} binary files:\n${binaryFiles.map((f) => `- ${f}`).join('\n')}` + : ''; - const assistantMessages: Message[] = [{ - role: 'assistant', - content: `I've imported the contents of the "${folderName}" folder.${binaryFilesMessage} + const assistantMessages: Message[] = [ + { + role: 'assistant', + content: `I've imported the contents of the "${folderName}" folder.${binaryFilesMessage} ${fileArtifacts.join('\n\n')} `, - id: generateId(), - createdAt: new Date(), - },{ - role: 'assistant', - content: ` + id: generateId(), + createdAt: new Date(), + }, + { + role: 'assistant', + content: ` ${setupCommand} ${followupMessage}`, - id: generateId(), - createdAt: new Date(), - }]; + id: generateId(), + createdAt: new Date(), + }, + ]; const userMessage: Message = { role: 'user', @@ -59,5 +66,5 @@ ${setupCommand} createdAt: new Date(), }; - return [ userMessage, ...assistantMessages ]; + return [userMessage, ...assistantMessages]; }; diff --git a/package.json b/package.json index 1cd5c606..8492189d 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@xterm/addon-fit": "^0.10.0", "@xterm/addon-web-links": "^0.11.0", "@xterm/xterm": "^5.5.0", - "ai": "^3.4.33", + "ai": "^4.0.13", "date-fns": "^3.6.0", "diff": "^5.2.0", "file-saver": "^2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bec99e20..b7a21967 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,16 +94,16 @@ importers: version: 0.0.5(zod@3.23.8) '@radix-ui/react-dialog': specifier: ^1.1.2 - version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-dropdown-menu': specifier: ^2.1.2 - version: 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + version: 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-separator': specifier: ^1.1.0 - version: 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + version: 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-tooltip': specifier: ^1.1.4 - version: 1.1.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + version: 1.1.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@remix-run/cloudflare': specifier: ^2.15.0 version: 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2) @@ -112,7 +112,7 @@ importers: version: 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2) '@remix-run/react': specifier: ^2.15.0 - version: 2.15.0(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.2) + version: 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) '@uiw/codemirror-theme-vscode': specifier: ^4.23.6 version: 4.23.6(@codemirror/language@6.10.6)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0) @@ -132,8 +132,8 @@ importers: specifier: ^5.5.0 version: 5.5.0 ai: - specifier: ^3.4.33 - version: 3.4.33(react@18.3.1)(svelte@5.4.0)(vue@3.5.13)(zod@3.23.8) + specifier: ^4.0.13 + version: 4.0.13(react@18.3.1)(zod@3.23.8) date-fns: specifier: ^3.6.0 version: 3.6.0 @@ -145,7 +145,7 @@ importers: version: 2.0.5 framer-motion: specifier: ^11.12.0 - version: 11.12.0(react-dom@18.3.1)(react@18.3.1) + version: 11.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ignore: specifier: ^6.0.2 version: 6.0.2 @@ -181,16 +181,16 @@ importers: version: 18.3.1(react@18.3.1) react-hotkeys-hook: specifier: ^4.6.1 - version: 4.6.1(react-dom@18.3.1)(react@18.3.1) + version: 4.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-markdown: specifier: ^9.0.1 version: 9.0.1(@types/react@18.3.12)(react@18.3.1) react-resizable-panels: specifier: ^2.1.7 - version: 2.1.7(react-dom@18.3.1)(react@18.3.1) + version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-toastify: specifier: ^10.0.6 - version: 10.0.6(react-dom@18.3.1)(react@18.3.1) + version: 10.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rehype-raw: specifier: ^7.0.0 version: 7.0.0 @@ -202,10 +202,10 @@ importers: version: 4.0.0 remix-island: specifier: ^0.2.0 - version: 0.2.0(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(react-dom@18.3.1)(react@18.3.1) + version: 0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.0(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) remix-utils: specifier: ^7.7.0 - version: 7.7.0(@remix-run/cloudflare@2.15.0)(@remix-run/react@2.15.0)(react@18.3.1)(zod@3.23.8) + version: 7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.0(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8) shiki: specifier: ^1.24.0 version: 1.24.0 @@ -215,13 +215,13 @@ importers: devDependencies: '@blitz/eslint-plugin': specifier: 0.1.0 - version: 0.1.0(prettier@3.4.1)(typescript@5.7.2) + version: 0.1.0(@types/eslint@8.56.10)(jiti@1.21.6)(prettier@3.4.1)(typescript@5.7.2) '@cloudflare/workers-types': specifier: ^4.20241127.0 version: 4.20241127.0 '@remix-run/dev': specifier: ^2.15.0 - version: 2.15.0(@remix-run/react@2.15.0)(sass-embedded@1.81.0)(typescript@5.7.2)(vite@5.4.11)(wrangler@3.91.0) + version: 2.15.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@types/node@22.10.1)(sass-embedded@1.81.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0))(wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0)) '@types/diff': specifier: ^5.2.3 version: 5.2.3 @@ -269,22 +269,22 @@ importers: version: 11.0.5 unocss: specifier: ^0.61.9 - version: 0.61.9(postcss@8.4.49)(vite@5.4.11) + version: 0.61.9(postcss@8.4.49)(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) vite: specifier: ^5.4.11 - version: 5.4.11(sass-embedded@1.81.0) + version: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) vite-plugin-node-polyfills: specifier: ^0.22.0 - version: 0.22.0(vite@5.4.11) + version: 0.22.0(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) vite-plugin-optimize-css-modules: specifier: ^1.1.0 - version: 1.1.0(vite@5.4.11) + version: 1.1.0(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) vite-tsconfig-paths: specifier: ^4.3.2 - version: 4.3.2(typescript@5.7.2)(vite@5.4.11) + version: 4.3.2(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) vitest: specifier: ^2.1.7 - version: 2.1.8(sass-embedded@1.81.0) + version: 2.1.8(@types/node@22.10.1)(sass-embedded@1.81.0) wrangler: specifier: ^3.91.0 version: 3.91.0(@cloudflare/workers-types@4.20241127.0) @@ -342,15 +342,6 @@ packages: zod: optional: true - '@ai-sdk/provider-utils@1.0.22': - resolution: {integrity: sha512-YHK2rpj++wnLVc9vPGzGFP3Pjeld2MwhKinetA0zKXOoHAT/Jit5O8kZsxcSlJPu9wvcGT1UGZEjZrtO7PfFOQ==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.0.0 - peerDependenciesMeta: - zod: - optional: true - '@ai-sdk/provider-utils@1.0.9': resolution: {integrity: sha512-yfdanjUiCJbtGoRGXrcrmXn0pTyDfRIeY6ozDG96D66f2wupZaZvAgKptUa3zDYXtUCQQvcNJ+tipBBfQD/UYA==} engines: {node: '>=18'} @@ -369,6 +360,15 @@ packages: zod: optional: true + '@ai-sdk/provider-utils@2.0.3': + resolution: {integrity: sha512-Cyk7GlFEse2jQ4I3FWYuZ1Zhr5w1mD9SHMJTYm/in1rd7r89nmEoQiOy3h8YV2ZvTa2/6aR10xZ4M0k4B3BluA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + peerDependenciesMeta: + zod: + optional: true + '@ai-sdk/provider@0.0.12': resolution: {integrity: sha512-oOwPQD8i2Ynpn22cur4sk26FW3mSy6t6/X/K1Ay2yGBKYiSpRyLfObhOrZEGsXDx+3euKy4nEZ193R36NM+tpQ==} engines: {node: '>=18'} @@ -381,16 +381,12 @@ packages: resolution: {integrity: sha512-XMsNGJdGO+L0cxhhegtqZ8+T6nn4EoShS819OvCgI2kLbYTIvk0GWFGD0AXJmxkxs3DrpsJxKAFukFR7bvTkgQ==} engines: {node: '>=18'} - '@ai-sdk/provider@0.0.26': - resolution: {integrity: sha512-dQkfBDs2lTYpKM8389oopPdQgIU007GQyCbuPPrV+K6MtSII3HBfE0stUIMXUb44L+LK1t6GXPP7wjSzjO6uKg==} - engines: {node: '>=18'} - '@ai-sdk/provider@1.0.1': resolution: {integrity: sha512-mV+3iNDkzUsZ0pR2jG0sVzU6xtQY5DtSCBy3JFycLp6PwjyLw/iodfL3MwdmMCRJWgs3dadcHejRnMvF9nGTBg==} engines: {node: '>=18'} - '@ai-sdk/react@0.0.70': - resolution: {integrity: sha512-GnwbtjW4/4z7MleLiW+TOZC2M29eCg1tOUpuEiYFMmFNZK8mkrqM0PFZMo6UsYeUYMWqEOOcPOU9OQVJMJh7IQ==} + '@ai-sdk/react@1.0.5': + resolution: {integrity: sha512-OPqYhltJE9dceWxw5pTXdYtAhs1Ca6Ly8xR7z/T+JZ0lrcgembFIMvnJ0dMBkba07P4GQBmuvd5DVTeAqPM9SQ==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -401,26 +397,8 @@ packages: zod: optional: true - '@ai-sdk/solid@0.0.54': - resolution: {integrity: sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==} - engines: {node: '>=18'} - peerDependencies: - solid-js: ^1.7.7 - peerDependenciesMeta: - solid-js: - optional: true - - '@ai-sdk/svelte@0.0.57': - resolution: {integrity: sha512-SyF9ItIR9ALP9yDNAD+2/5Vl1IT6kchgyDH8xkmhysfJI6WrvJbtO1wdQ0nylvPLcsPoYu+cAlz1krU4lFHcYw==} - engines: {node: '>=18'} - peerDependencies: - svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - svelte: - optional: true - - '@ai-sdk/ui-utils@0.0.50': - resolution: {integrity: sha512-Z5QYJVW+5XpSaJ4jYCCAVG7zIAuKOOdikhgpksneNmKvx61ACFaf98pmOd+xnjahl0pIlc/QIe6O4yVaJ1sEaw==} + '@ai-sdk/ui-utils@1.0.4': + resolution: {integrity: sha512-P2vDvASaGsD+lmbsQ5WYjELxJBQgse3CpxyLSA+usZiZxspwYbLFsSWiYz3zhIemcnS0T6/OwQdU6UlMB4N5BQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -428,15 +406,6 @@ packages: zod: optional: true - '@ai-sdk/vue@0.0.59': - resolution: {integrity: sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==} - engines: {node: '>=18'} - peerDependencies: - vue: ^3.3.4 - peerDependenciesMeta: - vue: - optional: true - '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -2323,35 +2292,6 @@ packages: '@vitest/utils@2.1.8': resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} - '@vue/compiler-core@3.5.13': - resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - - '@vue/compiler-dom@3.5.13': - resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} - - '@vue/compiler-sfc@3.5.13': - resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - - '@vue/compiler-ssr@3.5.13': - resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} - - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - - '@vue/runtime-core@3.5.13': - resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - - '@vue/runtime-dom@3.5.13': - resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - - '@vue/server-renderer@3.5.13': - resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} - peerDependencies: - vue: 3.5.13 - - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} - '@web3-storage/multipart-parser@1.0.0': resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==} @@ -2387,11 +2327,6 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-typescript@1.4.13: - resolution: {integrity: sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==} - peerDependencies: - acorn: '>=8.9.0' - acorn-walk@8.3.4: resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} @@ -2405,24 +2340,15 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@3.4.33: - resolution: {integrity: sha512-plBlrVZKwPoRTmM8+D1sJac9Bq8eaa2jiZlHLZIWekKWI1yMWYZvCCEezY9ASPwRhULYDJB2VhKOBUUeg3S5JQ==} + ai@4.0.13: + resolution: {integrity: sha512-ic+qEVPQhfLpGPnZ2M55ErofeuKaD/TQebeh0qSPwv2PF+dQwsPr2Pw+JNYXahezAOaxFNdrDPz0EF1kKcSFSw==} engines: {node: '>=18'} peerDependencies: - openai: ^4.42.0 react: ^18 || ^19 || ^19.0.0-rc - sswr: ^2.1.0 - svelte: ^3.0.0 || ^4.0.0 || ^5.0.0 zod: ^3.0.0 peerDependenciesMeta: - openai: - optional: true react: optional: true - sswr: - optional: true - svelte: - optional: true zod: optional: true @@ -2459,10 +2385,6 @@ packages: resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} engines: {node: '>=10'} - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} - array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} @@ -2490,10 +2412,6 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} - bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -3102,9 +3020,6 @@ packages: jiti: optional: true - esm-env@1.2.1: - resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} - espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3117,9 +3032,6 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@1.2.3: - resolution: {integrity: sha512-ZlQmCCK+n7SGoqo7DnfKaP1sJZa49P01/dXzmjCASSo04p72w8EksT2NMK8CEX8DhKsfJXANioIw8VyHNsBfvQ==} - esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -3773,9 +3685,6 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} - locate-character@3.0.0: - resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} - locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -5143,11 +5052,6 @@ packages: resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - sswr@2.1.0: - resolution: {integrity: sha512-Cqc355SYlTAaUt8iDPaC/4DPPXK925PePLMxyBKuWd5kKc5mwsG3nT9+Mq2tyguL5s7b4Jg+IRMpTRsNTAfpSQ==} - peerDependencies: - svelte: ^4.0.0 || ^5.0.0-next.0 - stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} @@ -5238,23 +5142,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte@5.4.0: - resolution: {integrity: sha512-2I/mjD8cXDpKfdfUK+T6yo/OzugMXIm8lhyJUFM5F/gICMYnkl3C/+4cOSpia8TqpDsi6Qfm5+fdmBNMNmaf2g==} - engines: {node: '>=18'} - swr@2.2.5: resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} peerDependencies: react: ^16.11.0 || ^17.0.0 || ^18.0.0 - swrev@4.0.0: - resolution: {integrity: sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA==} - - swrv@1.0.4: - resolution: {integrity: sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==} - peerDependencies: - vue: '>=3.2.26 < 4' - sync-child-process@1.0.2: resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} engines: {node: '>=16.0.0'} @@ -5674,14 +5566,6 @@ packages: vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} - vue@3.5.13: - resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -5796,9 +5680,6 @@ packages: youch@3.3.4: resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} - zimmerframe@1.1.2: - resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} - zod-to-json-schema@3.23.5: resolution: {integrity: sha512-5wlSS0bXfF/BrL4jPAbz9da5hDlDptdEppYfe+x4eIJ7jioqKG9uUxOwPzqof09u/XeVdrgFu29lZi+8XNDJtA==} peerDependencies: @@ -5849,6 +5730,7 @@ snapshots: eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 + optionalDependencies: zod: 3.23.8 '@ai-sdk/provider-utils@1.0.20(zod@3.23.8)': @@ -5857,14 +5739,7 @@ snapshots: eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 - zod: 3.23.8 - - '@ai-sdk/provider-utils@1.0.22(zod@3.23.8)': - dependencies: - '@ai-sdk/provider': 0.0.26 - eventsource-parser: 1.1.2 - nanoid: 3.3.8 - secure-json-parse: 2.7.0 + optionalDependencies: zod: 3.23.8 '@ai-sdk/provider-utils@1.0.9(zod@3.23.8)': @@ -5873,6 +5748,7 @@ snapshots: eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 + optionalDependencies: zod: 3.23.8 '@ai-sdk/provider-utils@2.0.2(zod@3.23.8)': @@ -5881,6 +5757,16 @@ snapshots: eventsource-parser: 3.0.0 nanoid: 3.3.8 secure-json-parse: 2.7.0 + optionalDependencies: + zod: 3.23.8 + + '@ai-sdk/provider-utils@2.0.3(zod@3.23.8)': + dependencies: + '@ai-sdk/provider': 1.0.1 + eventsource-parser: 3.0.0 + nanoid: 3.3.8 + secure-json-parse: 2.7.0 + optionalDependencies: zod: 3.23.8 '@ai-sdk/provider@0.0.12': @@ -5895,56 +5781,27 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/provider@0.0.26': - dependencies: - json-schema: 0.4.0 - '@ai-sdk/provider@1.0.1': dependencies: json-schema: 0.4.0 - '@ai-sdk/react@0.0.70(react@18.3.1)(zod@3.23.8)': + '@ai-sdk/react@1.0.5(react@18.3.1)(zod@3.23.8)': dependencies: - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - react: 18.3.1 + '@ai-sdk/provider-utils': 2.0.3(zod@3.23.8) + '@ai-sdk/ui-utils': 1.0.4(zod@3.23.8) swr: 2.2.5(react@18.3.1) throttleit: 2.1.0 + optionalDependencies: + react: 18.3.1 zod: 3.23.8 - '@ai-sdk/solid@0.0.54(zod@3.23.8)': + '@ai-sdk/ui-utils@1.0.4(zod@3.23.8)': dependencies: - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - transitivePeerDependencies: - - zod - - '@ai-sdk/svelte@0.0.57(svelte@5.4.0)(zod@3.23.8)': - dependencies: - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - sswr: 2.1.0(svelte@5.4.0) - svelte: 5.4.0 - transitivePeerDependencies: - - zod - - '@ai-sdk/ui-utils@0.0.50(zod@3.23.8)': - dependencies: - '@ai-sdk/provider': 0.0.26 - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - json-schema: 0.4.0 - secure-json-parse: 2.7.0 - zod: 3.23.8 + '@ai-sdk/provider': 1.0.1 + '@ai-sdk/provider-utils': 2.0.3(zod@3.23.8) zod-to-json-schema: 3.23.5(zod@3.23.8) - - '@ai-sdk/vue@0.0.59(vue@3.5.13)(zod@3.23.8)': - dependencies: - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - swrv: 1.0.4(vue@3.5.13) - vue: 3.5.13(typescript@5.7.2) - transitivePeerDependencies: - - zod + optionalDependencies: + zod: 3.23.8 '@ampproject/remapping@2.3.0': dependencies: @@ -6159,19 +6016,19 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@blitz/eslint-plugin@0.1.0(prettier@3.4.1)(typescript@5.7.2)': + '@blitz/eslint-plugin@0.1.0(@types/eslint@8.56.10)(jiti@1.21.6)(prettier@3.4.1)(typescript@5.7.2)': dependencies: - '@stylistic/eslint-plugin-ts': 2.11.0(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0)(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@stylistic/eslint-plugin-ts': 2.11.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/parser': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) common-tags: 1.8.2 - eslint: 9.16.0 - eslint-config-prettier: 9.1.0(eslint@9.16.0) - eslint-plugin-jsonc: 2.18.2(eslint@9.16.0) - eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0)(eslint@9.16.0)(prettier@3.4.1) + eslint: 9.16.0(jiti@1.21.6) + eslint-config-prettier: 9.1.0(eslint@9.16.0(jiti@1.21.6)) + eslint-plugin-jsonc: 2.18.2(eslint@9.16.0(jiti@1.21.6)) + eslint-plugin-prettier: 5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(prettier@3.4.1) globals: 15.13.0 - typescript-eslint: 8.17.0(eslint@9.16.0)(typescript@5.7.2) + typescript-eslint: 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) transitivePeerDependencies: - '@eslint/json' - '@types/eslint' @@ -6623,9 +6480,9 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@eslint-community/eslint-utils@4.4.1(eslint@9.16.0)': + '@eslint-community/eslint-utils@4.4.1(eslint@9.16.0(jiti@1.21.6))': dependencies: - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -6673,7 +6530,7 @@ snapshots: '@floating-ui/core': 1.6.8 '@floating-ui/utils': 0.2.8 - '@floating-ui/react-dom@2.1.2(react-dom@18.3.1)(react@18.3.1)': + '@floating-ui/react-dom@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/dom': 1.6.12 react: 18.3.1 @@ -6956,271 +6813,299 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-context@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-context@1.1.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-dialog@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-dialog@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-remove-scroll: 2.6.0(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-direction@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-dropdown-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-dropdown-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-menu': 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-menu': 2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-id@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-menu@2.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-remove-scroll: 2.6.0(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/rect': 1.1.0 - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-portal@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-portal@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-presence@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-presence@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-slot@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-tooltip@1.1.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': + '@radix-ui/react-tooltip@1.1.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.0 - '@types/react': 18.3.12 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 '@radix-ui/react-use-size@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) - '@types/react': 18.3.12 react: 18.3.1 - - '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1)': - dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1)(react@18.3.1) + optionalDependencies: '@types/react': 18.3.12 - '@types/react-dom': 18.3.1 + + '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 '@radix-ui/rect@1.1.0': {} @@ -7228,6 +7113,7 @@ snapshots: dependencies: '@cloudflare/workers-types': 4.20241127.0 '@remix-run/cloudflare': 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2) + optionalDependencies: typescript: 5.7.2 '@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2)': @@ -7235,9 +7121,10 @@ snapshots: '@cloudflare/kv-asset-handler': 0.1.3 '@cloudflare/workers-types': 4.20241127.0 '@remix-run/server-runtime': 2.15.0(typescript@5.7.2) + optionalDependencies: typescript: 5.7.2 - '@remix-run/dev@2.15.0(@remix-run/react@2.15.0)(sass-embedded@1.81.0)(typescript@5.7.2)(vite@5.4.11)(wrangler@3.91.0)': + '@remix-run/dev@2.15.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@types/node@22.10.1)(sass-embedded@1.81.0)(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0))(wrangler@3.91.0(@cloudflare/workers-types@4.20241127.0))': dependencies: '@babel/core': 7.26.0 '@babel/generator': 7.26.2 @@ -7250,11 +7137,11 @@ snapshots: '@mdx-js/mdx': 2.3.0 '@npmcli/package-json': 4.0.1 '@remix-run/node': 2.15.0(typescript@5.7.2) - '@remix-run/react': 2.15.0(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.2) + '@remix-run/react': 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) '@remix-run/router': 1.21.0 '@remix-run/server-runtime': 2.15.0(typescript@5.7.2) '@types/mdx': 2.0.13 - '@vanilla-extract/integration': 6.5.0(sass-embedded@1.81.0) + '@vanilla-extract/integration': 6.5.0(@types/node@22.10.1)(sass-embedded@1.81.0) arg: 5.0.2 cacache: 17.1.4 chalk: 4.1.2 @@ -7292,12 +7179,13 @@ snapshots: set-cookie-parser: 2.7.1 tar-fs: 2.1.1 tsconfig-paths: 4.2.0 - typescript: 5.7.2 valibot: 0.41.0(typescript@5.7.2) - vite: 5.4.11(sass-embedded@1.81.0) - vite-node: 1.6.0(sass-embedded@1.81.0) - wrangler: 3.91.0(@cloudflare/workers-types@4.20241127.0) + vite-node: 1.6.0(@types/node@22.10.1)(sass-embedded@1.81.0) ws: 7.5.10 + optionalDependencies: + typescript: 5.7.2 + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) + wrangler: 3.91.0(@cloudflare/workers-types@4.20241127.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -7322,18 +7210,20 @@ snapshots: cookie-signature: 1.2.2 source-map-support: 0.5.21 stream-slice: 0.1.2 - typescript: 5.7.2 undici: 6.21.0 + optionalDependencies: + typescript: 5.7.2 - '@remix-run/react@2.15.0(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.2)': + '@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2)': dependencies: '@remix-run/router': 1.21.0 '@remix-run/server-runtime': 2.15.0(typescript@5.7.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-router: 6.28.0(react@18.3.1) - react-router-dom: 6.28.0(react-dom@18.3.1)(react@18.3.1) + react-router-dom: 6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) turbo-stream: 2.4.0 + optionalDependencies: typescript: 5.7.2 '@remix-run/router@1.21.0': {} @@ -7347,6 +7237,7 @@ snapshots: set-cookie-parser: 2.7.1 source-map: 0.7.4 turbo-stream: 2.4.0 + optionalDependencies: typescript: 5.7.2 '@remix-run/web-blob@3.1.0': @@ -7377,17 +7268,21 @@ snapshots: dependencies: web-streams-polyfill: 3.3.3 - '@rollup/plugin-inject@5.0.5': + '@rollup/plugin-inject@5.0.5(rollup@4.28.0)': dependencies: - '@rollup/pluginutils': 5.1.3 + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) estree-walker: 2.0.2 magic-string: 0.30.14 + optionalDependencies: + rollup: 4.28.0 - '@rollup/pluginutils@5.1.3': + '@rollup/pluginutils@5.1.3(rollup@4.28.0)': dependencies: '@types/estree': 1.0.6 estree-walker: 2.0.2 picomatch: 4.0.2 + optionalDependencies: + rollup: 4.28.0 '@rollup/rollup-android-arm-eabi@4.28.0': optional: true @@ -7470,10 +7365,10 @@ snapshots: '@shikijs/vscode-textmate@9.3.0': {} - '@stylistic/eslint-plugin-ts@2.11.0(eslint@9.16.0)(typescript@5.7.2)': + '@stylistic/eslint-plugin-ts@2.11.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)': dependencies: - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) - eslint: 9.16.0 + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + eslint: 9.16.0(jiti@1.21.6) eslint-visitor-keys: 4.2.0 espree: 10.3.0 transitivePeerDependencies: @@ -7494,7 +7389,6 @@ snapshots: '@types/diff@5.2.3': {} - '@types/dom-speech-recognition@0.0.4': {} '@types/eslint@8.56.10': @@ -7558,31 +7452,33 @@ snapshots: '@types/unist@3.0.3': {} - '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0)(eslint@9.16.0)(typescript@5.7.2)': + '@typescript-eslint/eslint-plugin@8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/parser': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) '@typescript-eslint/scope-manager': 8.17.0 - '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/type-utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) '@typescript-eslint/visitor-keys': 8.17.0 - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 ts-api-utils: 1.4.3(typescript@5.7.2) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.17.0(eslint@9.16.0)(typescript@5.7.2)': + '@typescript-eslint/parser@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)': dependencies: '@typescript-eslint/scope-manager': 8.17.0 '@typescript-eslint/types': 8.17.0 '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) '@typescript-eslint/visitor-keys': 8.17.0 debug: 4.3.7 - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -7592,13 +7488,14 @@ snapshots: '@typescript-eslint/types': 8.17.0 '@typescript-eslint/visitor-keys': 8.17.0 - '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0)(typescript@5.7.2)': + '@typescript-eslint/type-utils@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)': dependencies: '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) debug: 4.3.7 - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) ts-api-utils: 1.4.3(typescript@5.7.2) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -7615,17 +7512,19 @@ snapshots: minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.4.3(typescript@5.7.2) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.17.0(eslint@9.16.0)(typescript@5.7.2)': + '@typescript-eslint/utils@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@1.21.6)) '@typescript-eslint/scope-manager': 8.17.0 '@typescript-eslint/types': 8.17.0 '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -7651,20 +7550,21 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@unocss/astro@0.61.9(vite@5.4.11)': + '@unocss/astro@0.61.9(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0))': dependencies: '@unocss/core': 0.61.9 '@unocss/reset': 0.61.9 - '@unocss/vite': 0.61.9(vite@5.4.11) - vite: 5.4.11(sass-embedded@1.81.0) + '@unocss/vite': 0.61.9(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) + optionalDependencies: + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - rollup - supports-color - '@unocss/cli@0.61.9': + '@unocss/cli@0.61.9(rollup@4.28.0)': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.3 + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/preset-uno': 0.61.9 @@ -7793,10 +7693,10 @@ snapshots: dependencies: '@unocss/core': 0.61.9 - '@unocss/vite@0.61.9(vite@5.4.11)': + '@unocss/vite@0.61.9(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0))': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.3 + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) '@unocss/config': 0.61.9 '@unocss/core': 0.61.9 '@unocss/inspector': 0.61.9 @@ -7805,7 +7705,7 @@ snapshots: chokidar: 3.6.0 fast-glob: 3.3.2 magic-string: 0.30.14 - vite: 5.4.11(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - rollup - supports-color @@ -7833,7 +7733,7 @@ snapshots: transitivePeerDependencies: - babel-plugin-macros - '@vanilla-extract/integration@6.5.0(sass-embedded@1.81.0)': + '@vanilla-extract/integration@6.5.0(@types/node@22.10.1)(sass-embedded@1.81.0)': dependencies: '@babel/core': 7.26.0 '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) @@ -7846,8 +7746,8 @@ snapshots: lodash: 4.17.21 mlly: 1.7.3 outdent: 0.8.0 - vite: 5.4.11(sass-embedded@1.81.0) - vite-node: 1.6.0(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) + vite-node: 1.6.0(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -7869,12 +7769,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(vite@5.4.11)': + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.14 - vite: 5.4.11(sass-embedded@1.81.0) + optionalDependencies: + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) '@vitest/pretty-format@2.1.8': dependencies: @@ -7901,60 +7802,6 @@ snapshots: loupe: 3.1.2 tinyrainbow: 1.2.0 - '@vue/compiler-core@3.5.13': - dependencies: - '@babel/parser': 7.26.2 - '@vue/shared': 3.5.13 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - - '@vue/compiler-dom@3.5.13': - dependencies: - '@vue/compiler-core': 3.5.13 - '@vue/shared': 3.5.13 - - '@vue/compiler-sfc@3.5.13': - dependencies: - '@babel/parser': 7.26.2 - '@vue/compiler-core': 3.5.13 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - estree-walker: 2.0.2 - magic-string: 0.30.14 - postcss: 8.4.49 - source-map-js: 1.2.1 - - '@vue/compiler-ssr@3.5.13': - dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 - - '@vue/reactivity@3.5.13': - dependencies: - '@vue/shared': 3.5.13 - - '@vue/runtime-core@3.5.13': - dependencies: - '@vue/reactivity': 3.5.13 - '@vue/shared': 3.5.13 - - '@vue/runtime-dom@3.5.13': - dependencies: - '@vue/reactivity': 3.5.13 - '@vue/runtime-core': 3.5.13 - '@vue/shared': 3.5.13 - csstype: 3.1.3 - - '@vue/server-renderer@3.5.13(vue@3.5.13)': - dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.7.2) - - '@vue/shared@3.5.13': {} - '@web3-storage/multipart-parser@1.0.0': {} '@webcontainer/api@1.3.0-internal.10': {} @@ -7985,10 +7832,6 @@ snapshots: dependencies: acorn: 8.14.0 - acorn-typescript@1.4.13(acorn@8.14.0): - dependencies: - acorn: 8.14.0 - acorn-walk@8.3.4: dependencies: acorn: 8.14.0 @@ -8000,27 +7843,18 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@3.4.33(react@18.3.1)(svelte@5.4.0)(vue@3.5.13)(zod@3.23.8): + ai@4.0.13(react@18.3.1)(zod@3.23.8): dependencies: - '@ai-sdk/provider': 0.0.26 - '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) - '@ai-sdk/react': 0.0.70(react@18.3.1)(zod@3.23.8) - '@ai-sdk/solid': 0.0.54(zod@3.23.8) - '@ai-sdk/svelte': 0.0.57(svelte@5.4.0)(zod@3.23.8) - '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8) - '@ai-sdk/vue': 0.0.59(vue@3.5.13)(zod@3.23.8) + '@ai-sdk/provider': 1.0.1 + '@ai-sdk/provider-utils': 2.0.3(zod@3.23.8) + '@ai-sdk/react': 1.0.5(react@18.3.1)(zod@3.23.8) + '@ai-sdk/ui-utils': 1.0.4(zod@3.23.8) '@opentelemetry/api': 1.9.0 - eventsource-parser: 1.1.2 - json-schema: 0.4.0 jsondiffpatch: 0.6.0 - react: 18.3.1 - secure-json-parse: 2.7.0 - svelte: 5.4.0 - zod: 3.23.8 zod-to-json-schema: 3.23.5(zod@3.23.8) - transitivePeerDependencies: - - solid-js - - vue + optionalDependencies: + react: 18.3.1 + zod: 3.23.8 ajv@6.12.6: dependencies: @@ -8052,8 +7886,6 @@ snapshots: dependencies: tslib: 2.8.1 - aria-query@5.3.2: {} - array-flatten@1.1.1: {} as-table@1.0.55: @@ -8084,8 +7916,6 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 - axobject-query@4.1.0: {} - bail@2.0.2: {} balanced-match@1.0.2: {} @@ -8696,27 +8526,27 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-compat-utils@0.6.4(eslint@9.16.0): + eslint-compat-utils@0.6.4(eslint@9.16.0(jiti@1.21.6)): dependencies: - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) semver: 7.6.3 - eslint-config-prettier@9.1.0(eslint@9.16.0): + eslint-config-prettier@9.1.0(eslint@9.16.0(jiti@1.21.6)): dependencies: - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) - eslint-json-compat-utils@0.2.1(eslint@9.16.0)(jsonc-eslint-parser@2.4.0): + eslint-json-compat-utils@0.2.1(eslint@9.16.0(jiti@1.21.6))(jsonc-eslint-parser@2.4.0): dependencies: - eslint: 9.16.0 + eslint: 9.16.0(jiti@1.21.6) esquery: 1.6.0 jsonc-eslint-parser: 2.4.0 - eslint-plugin-jsonc@2.18.2(eslint@9.16.0): + eslint-plugin-jsonc@2.18.2(eslint@9.16.0(jiti@1.21.6)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0) - eslint: 9.16.0 - eslint-compat-utils: 0.6.4(eslint@9.16.0) - eslint-json-compat-utils: 0.2.1(eslint@9.16.0)(jsonc-eslint-parser@2.4.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@1.21.6)) + eslint: 9.16.0(jiti@1.21.6) + eslint-compat-utils: 0.6.4(eslint@9.16.0(jiti@1.21.6)) + eslint-json-compat-utils: 0.2.1(eslint@9.16.0(jiti@1.21.6))(jsonc-eslint-parser@2.4.0) espree: 9.6.1 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 @@ -8725,13 +8555,15 @@ snapshots: transitivePeerDependencies: - '@eslint/json' - eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0)(eslint@9.16.0)(prettier@3.4.1): + eslint-plugin-prettier@5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(prettier@3.4.1): dependencies: - eslint: 9.16.0 - eslint-config-prettier: 9.1.0(eslint@9.16.0) + eslint: 9.16.0(jiti@1.21.6) prettier: 3.4.1 prettier-linter-helpers: 1.0.0 synckit: 0.9.2 + optionalDependencies: + '@types/eslint': 8.56.10 + eslint-config-prettier: 9.1.0(eslint@9.16.0(jiti@1.21.6)) eslint-scope@8.2.0: dependencies: @@ -8742,9 +8574,9 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.16.0: + eslint@9.16.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@1.21.6)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.0 '@eslint/core': 0.9.0 @@ -8778,11 +8610,11 @@ snapshots: minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 + optionalDependencies: + jiti: 1.21.6 transitivePeerDependencies: - supports-color - esm-env@1.2.1: {} - espree@10.3.0: dependencies: acorn: 8.14.0 @@ -8799,11 +8631,6 @@ snapshots: dependencies: estraverse: 5.3.0 - esrap@1.2.3: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -9005,11 +8832,12 @@ snapshots: forwarded@0.2.0: {} - framer-motion@11.12.0(react-dom@18.3.1)(react@18.3.1): + framer-motion@11.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: + tslib: 2.8.1 + optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - tslib: 2.8.1 fresh@0.5.2: {} @@ -9529,8 +9357,6 @@ snapshots: mlly: 1.7.3 pkg-types: 1.2.1 - locate-character@3.0.0: {} - locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -10491,6 +10317,7 @@ snapshots: '@ai-sdk/provider': 0.0.24 '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) partial-json: 0.1.7 + optionalDependencies: zod: 3.23.8 on-finished@2.4.1: @@ -10664,8 +10491,9 @@ snapshots: postcss-load-config@4.0.2(postcss@8.4.49): dependencies: lilconfig: 3.1.2 - postcss: 8.4.49 yaml: 2.6.1 + optionalDependencies: + postcss: 8.4.49 postcss-modules-extract-imports@3.1.0(postcss@8.4.49): dependencies: @@ -10814,7 +10642,7 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-hotkeys-hook@4.6.1(react-dom@18.3.1)(react@18.3.1): + react-hotkeys-hook@4.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10840,27 +10668,29 @@ snapshots: react-remove-scroll-bar@2.3.6(@types/react@18.3.12)(react@18.3.1): dependencies: - '@types/react': 18.3.12 react: 18.3.1 react-style-singleton: 2.2.1(@types/react@18.3.12)(react@18.3.1) tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.12 react-remove-scroll@2.6.0(@types/react@18.3.12)(react@18.3.1): dependencies: - '@types/react': 18.3.12 react: 18.3.1 react-remove-scroll-bar: 2.3.6(@types/react@18.3.12)(react@18.3.1) react-style-singleton: 2.2.1(@types/react@18.3.12)(react@18.3.1) tslib: 2.8.1 use-callback-ref: 1.3.2(@types/react@18.3.12)(react@18.3.1) use-sidecar: 1.1.2(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 - react-resizable-panels@2.1.7(react-dom@18.3.1)(react@18.3.1): + react-resizable-panels@2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-router-dom@6.28.0(react-dom@18.3.1)(react@18.3.1): + react-router-dom@6.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.21.0 react: 18.3.1 @@ -10874,13 +10704,14 @@ snapshots: react-style-singleton@2.2.1(@types/react@18.3.12)(react@18.3.1): dependencies: - '@types/react': 18.3.12 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.3.1 tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.12 - react-toastify@10.0.6(react-dom@18.3.1)(react@18.3.1): + react-toastify@10.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: clsx: 2.1.1 react: 18.3.1 @@ -11005,19 +10836,22 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 - remix-island@0.2.0(@remix-run/react@2.15.0)(@remix-run/server-runtime@2.15.0)(react-dom@18.3.1)(react@18.3.1): + remix-island@0.2.0(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/server-runtime@2.15.0(typescript@5.7.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@remix-run/react': 2.15.0(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.2) + '@remix-run/react': 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) '@remix-run/server-runtime': 2.15.0(typescript@5.7.2) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - remix-utils@7.7.0(@remix-run/cloudflare@2.15.0)(@remix-run/react@2.15.0)(react@18.3.1)(zod@3.23.8): + remix-utils@7.7.0(@remix-run/cloudflare@2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.0(typescript@5.7.2))(@remix-run/react@2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2))(@remix-run/router@1.21.0)(react@18.3.1)(zod@3.23.8): dependencies: - '@remix-run/cloudflare': 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2) - '@remix-run/react': 2.15.0(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.2) - react: 18.3.1 type-fest: 4.30.0 + optionalDependencies: + '@remix-run/cloudflare': 2.15.0(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2) + '@remix-run/node': 2.15.0(typescript@5.7.2) + '@remix-run/react': 2.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.2) + '@remix-run/router': 1.21.0 + react: 18.3.1 zod: 3.23.8 require-like@0.1.2: {} @@ -11333,11 +11167,6 @@ snapshots: dependencies: minipass: 7.1.2 - sswr@2.1.0(svelte@5.4.0): - dependencies: - svelte: 5.4.0 - swrev: 4.0.0 - stackback@0.0.2: {} stacktracey@2.1.8: @@ -11428,34 +11257,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte@5.4.0: - dependencies: - '@ampproject/remapping': 2.3.0 - '@jridgewell/sourcemap-codec': 1.5.0 - '@types/estree': 1.0.6 - acorn: 8.14.0 - acorn-typescript: 1.4.13(acorn@8.14.0) - aria-query: 5.3.2 - axobject-query: 4.1.0 - esm-env: 1.2.1 - esrap: 1.2.3 - is-reference: 3.0.3 - locate-character: 3.0.0 - magic-string: 0.30.14 - zimmerframe: 1.1.2 - swr@2.2.5(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 use-sync-external-store: 1.2.2(react@18.3.1) - swrev@4.0.0: {} - - swrv@1.0.4(vue@3.5.13): - dependencies: - vue: 3.5.13(typescript@5.7.2) - sync-child-process@1.0.2: dependencies: sync-message-port: 1.1.3 @@ -11539,7 +11346,7 @@ snapshots: typescript: 5.7.2 tsconfck@3.1.4(typescript@5.7.2): - dependencies: + optionalDependencies: typescript: 5.7.2 tsconfig-paths@4.2.0: @@ -11572,12 +11379,13 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typescript-eslint@8.17.0(eslint@9.16.0)(typescript@5.7.2): + typescript-eslint@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0)(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/parser': 8.17.0(eslint@9.16.0)(typescript@5.7.2) - '@typescript-eslint/utils': 8.17.0(eslint@9.16.0)(typescript@5.7.2) - eslint: 9.16.0 + '@typescript-eslint/eslint-plugin': 8.17.0(@typescript-eslint/parser@8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/parser': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + '@typescript-eslint/utils': 8.17.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + eslint: 9.16.0(jiti@1.21.6) + optionalDependencies: typescript: 5.7.2 transitivePeerDependencies: - supports-color @@ -11698,10 +11506,10 @@ snapshots: universalify@2.0.1: {} - unocss@0.61.9(postcss@8.4.49)(vite@5.4.11): + unocss@0.61.9(postcss@8.4.49)(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)): dependencies: - '@unocss/astro': 0.61.9(vite@5.4.11) - '@unocss/cli': 0.61.9 + '@unocss/astro': 0.61.9(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) + '@unocss/cli': 0.61.9(rollup@4.28.0) '@unocss/core': 0.61.9 '@unocss/extractor-arbitrary-variants': 0.61.9 '@unocss/postcss': 0.61.9(postcss@8.4.49) @@ -11719,8 +11527,9 @@ snapshots: '@unocss/transformer-compile-class': 0.61.9 '@unocss/transformer-directives': 0.61.9 '@unocss/transformer-variant-group': 0.61.9 - '@unocss/vite': 0.61.9(vite@5.4.11) - vite: 5.4.11(sass-embedded@1.81.0) + '@unocss/vite': 0.61.9(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) + optionalDependencies: + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - postcss - rollup @@ -11745,16 +11554,18 @@ snapshots: use-callback-ref@1.3.2(@types/react@18.3.12)(react@18.3.1): dependencies: - '@types/react': 18.3.12 react: 18.3.1 tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.12 use-sidecar@1.1.2(@types/react@18.3.12)(react@18.3.1): dependencies: - '@types/react': 18.3.12 detect-node-es: 1.1.0 react: 18.3.1 tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.12 use-sync-external-store@1.2.2(react@18.3.1): dependencies: @@ -11780,7 +11591,7 @@ snapshots: sade: 1.8.1 valibot@0.41.0(typescript@5.7.2): - dependencies: + optionalDependencies: typescript: 5.7.2 validate-npm-package-license@3.0.4: @@ -11823,13 +11634,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-node@1.6.0(sass-embedded@1.81.0): + vite-node@1.6.0(@types/node@22.10.1)(sass-embedded@1.81.0): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 picocolors: 1.1.1 - vite: 5.4.11(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - '@types/node' - less @@ -11841,13 +11652,13 @@ snapshots: - supports-color - terser - vite-node@2.1.8(sass-embedded@1.81.0): + vite-node@2.1.8(@types/node@22.10.1)(sass-embedded@1.81.0): dependencies: cac: 6.7.14 debug: 4.3.7 es-module-lexer: 1.5.4 pathe: 1.1.2 - vite: 5.4.11(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - '@types/node' - less @@ -11859,41 +11670,43 @@ snapshots: - supports-color - terser - vite-plugin-node-polyfills@0.22.0(vite@5.4.11): + vite-plugin-node-polyfills@0.22.0(rollup@4.28.0)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)): dependencies: - '@rollup/plugin-inject': 5.0.5 + '@rollup/plugin-inject': 5.0.5(rollup@4.28.0) node-stdlib-browser: 1.3.0 - vite: 5.4.11(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - rollup - vite-plugin-optimize-css-modules@1.1.0(vite@5.4.11): + vite-plugin-optimize-css-modules@1.1.0(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)): dependencies: - vite: 5.4.11(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) - vite-tsconfig-paths@4.3.2(typescript@5.7.2)(vite@5.4.11): + vite-tsconfig-paths@4.3.2(typescript@5.7.2)(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)): dependencies: debug: 4.3.7 globrex: 0.1.2 tsconfck: 3.1.4(typescript@5.7.2) - vite: 5.4.11(sass-embedded@1.81.0) + optionalDependencies: + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) transitivePeerDependencies: - supports-color - typescript - vite@5.4.11(sass-embedded@1.81.0): + vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0): dependencies: esbuild: 0.21.5 postcss: 8.4.49 rollup: 4.28.0 - sass-embedded: 1.81.0 optionalDependencies: + '@types/node': 22.10.1 fsevents: 2.3.3 + sass-embedded: 1.81.0 - vitest@2.1.8(sass-embedded@1.81.0): + vitest@2.1.8(@types/node@22.10.1)(sass-embedded@1.81.0): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(vite@5.4.11) + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 @@ -11909,9 +11722,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.11(sass-embedded@1.81.0) - vite-node: 2.1.8(sass-embedded@1.81.0) + vite: 5.4.11(@types/node@22.10.1)(sass-embedded@1.81.0) + vite-node: 2.1.8(@types/node@22.10.1)(sass-embedded@1.81.0) why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.1 transitivePeerDependencies: - less - lightningcss @@ -11925,15 +11740,6 @@ snapshots: vm-browserify@1.1.2: {} - vue@3.5.13(typescript@5.7.2): - dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13) - '@vue/shared': 3.5.13 - typescript: 5.7.2 - w3c-keyname@2.2.8: {} wcwidth@1.0.1: @@ -11985,7 +11791,6 @@ snapshots: dependencies: '@cloudflare/kv-asset-handler': 0.3.4 '@cloudflare/workers-shared': 0.9.0 - '@cloudflare/workers-types': 4.20241127.0 '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) blake3-wasm: 2.1.5 @@ -12004,6 +11809,7 @@ snapshots: workerd: 1.20241106.1 xxhash-wasm: 1.1.0 optionalDependencies: + '@cloudflare/workers-types': 4.20241127.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil @@ -12046,8 +11852,6 @@ snapshots: mustache: 4.2.0 stacktracey: 2.1.8 - zimmerframe@1.1.2: {} - zod-to-json-schema@3.23.5(zod@3.23.8): dependencies: zod: 3.23.8 From 85b0322fd6e9c2760805e6372c487fb0432955de Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 13 Dec 2024 15:23:03 +0000 Subject: [PATCH 03/27] chore: update commit hash to d479daa5781a533c68a6f9ffdb3b919914c9305e --- app/commit.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/commit.json b/app/commit.json index 850911fe..5bb65969 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1,2 +1 @@ -{ "commit": "eeafc12522b184dcbded28c5c6606e4a23e6849f" } - +{ "commit": "d479daa5781a533c68a6f9ffdb3b919914c9305e" } From 79ce87ee5d729185bad73a37ebf77964f1488f59 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 14 Dec 2024 08:29:16 +0000 Subject: [PATCH 04/27] chore: update commit hash to a71cfba660f04a8440960ab772670b192e2d066f --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index aa11cbf7..ccf5a8ca 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "4af18c069f2429ffaf410d92702a1e1294af2628" } +{ "commit": "a71cfba660f04a8440960ab772670b192e2d066f" } From 70f88f981a4195b70d3a62f0767c83bcf7894e0d Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Sun, 15 Dec 2024 16:47:16 +0530 Subject: [PATCH 05/27] feat: Experimental Prompt Library Added --- app/commit.json | 2 +- app/components/chat/Chat.client.tsx | 3 +- .../settings/features/FeaturesTab.tsx | 27 +++- app/lib/.server/llm/stream-text.ts | 25 +++- app/lib/common/prompt-library.ts | 49 +++++++ app/lib/common/prompts/optimized.ts | 135 ++++++++++++++++++ .../llm => common/prompts}/prompts.ts | 0 app/lib/hooks/useSettings.tsx | 15 ++ app/lib/stores/settings.ts | 2 + app/lib/stores/workbench.ts | 1 - app/routes/api.chat.ts | 7 +- 11 files changed, 253 insertions(+), 13 deletions(-) create mode 100644 app/lib/common/prompt-library.ts create mode 100644 app/lib/common/prompts/optimized.ts rename app/lib/{.server/llm => common/prompts}/prompts.ts (100%) diff --git a/app/commit.json b/app/commit.json index ccf5a8ca..be6c7229 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "a71cfba660f04a8440960ab772670b192e2d066f" } +{ "commit": "79ce87ee5d729185bad73a37ebf77964f1488f59" } diff --git a/app/components/chat/Chat.client.tsx b/app/components/chat/Chat.client.tsx index 751ea9c6..fe44dd18 100644 --- a/app/components/chat/Chat.client.tsx +++ b/app/components/chat/Chat.client.tsx @@ -93,7 +93,7 @@ export const ChatImpl = memo( const [uploadedFiles, setUploadedFiles] = useState([]); // Move here const [imageDataList, setImageDataList] = useState([]); // Move here const files = useStore(workbenchStore.files); - const { activeProviders } = useSettings(); + const { activeProviders, promptId } = useSettings(); const [model, setModel] = useState(() => { const savedModel = Cookies.get('selectedModel'); @@ -115,6 +115,7 @@ export const ChatImpl = memo( body: { apiKeys, files, + promptId, }, onError: (error) => { logger.error('Request failed\n\n', error); diff --git a/app/components/settings/features/FeaturesTab.tsx b/app/components/settings/features/FeaturesTab.tsx index 9c9e4a00..ff550780 100644 --- a/app/components/settings/features/FeaturesTab.tsx +++ b/app/components/settings/features/FeaturesTab.tsx @@ -1,18 +1,20 @@ import React from 'react'; import { Switch } from '~/components/ui/Switch'; +import { PromptLibrary } from '~/lib/common/prompt-library'; import { useSettings } from '~/lib/hooks/useSettings'; export default function FeaturesTab() { - const { debug, enableDebugMode, isLocalModel, enableLocalModels, eventLogs, enableEventLogs } = useSettings(); + const { debug, enableDebugMode, isLocalModel, enableLocalModels, eventLogs, enableEventLogs, promptId, setPromptId } = + useSettings(); return (

Optional Features

-
+
Debug Info
-
+
Event Logs
@@ -23,10 +25,27 @@ export default function FeaturesTab() {

Disclaimer: Experimental features may be unstable and are subject to change.

-
+
Enable Local Models
+
+
+ Prompt Library +

+ Choose a prompt from the library to use as the system prompt. +

+
+ +
); diff --git a/app/lib/.server/llm/stream-text.ts b/app/lib/.server/llm/stream-text.ts index 11ac99bd..74cdd9d4 100644 --- a/app/lib/.server/llm/stream-text.ts +++ b/app/lib/.server/llm/stream-text.ts @@ -1,10 +1,20 @@ import { convertToCoreMessages, streamText as _streamText } from 'ai'; import { getModel } from '~/lib/.server/llm/model'; import { MAX_TOKENS } from './constants'; -import { getSystemPrompt } from './prompts'; -import { DEFAULT_MODEL, DEFAULT_PROVIDER, getModelList, MODEL_REGEX, PROVIDER_REGEX } from '~/utils/constants'; +import { getSystemPrompt } from '~/lib/common/prompts/prompts'; +import { + DEFAULT_MODEL, + DEFAULT_PROVIDER, + getModelList, + MODEL_REGEX, + MODIFICATIONS_TAG_NAME, + PROVIDER_REGEX, + WORK_DIR, +} from '~/utils/constants'; import ignore from 'ignore'; import type { IProviderSetting } from '~/types/model'; +import { PromptLibrary } from '~/lib/common/prompt-library'; +import { allowedHTMLElements } from '~/utils/markdown'; interface ToolResult { toolCallId: string; @@ -139,8 +149,9 @@ export async function streamText(props: { apiKeys?: Record; files?: FileMap; providerSettings?: Record; + promptId?: string; }) { - const { messages, env, options, apiKeys, files, providerSettings } = props; + const { messages, env, options, apiKeys, files, providerSettings, promptId } = props; let currentModel = DEFAULT_MODEL; let currentProvider = DEFAULT_PROVIDER.name; const MODEL_LIST = await getModelList(apiKeys || {}, providerSettings); @@ -170,11 +181,17 @@ export async function streamText(props: { const dynamicMaxTokens = modelDetails && modelDetails.maxTokenAllowed ? modelDetails.maxTokenAllowed : MAX_TOKENS; - let systemPrompt = getSystemPrompt(); + let systemPrompt = + PromptLibrary.getPropmtFromLibrary(promptId || 'default', { + cwd: WORK_DIR, + allowedHtmlElements: allowedHTMLElements, + modificationTagName: MODIFICATIONS_TAG_NAME, + }) ?? getSystemPrompt(); let codeContext = ''; if (files) { codeContext = createFilesContext(files); + codeContext = ''; systemPrompt = `${systemPrompt}\n\n ${codeContext}`; } diff --git a/app/lib/common/prompt-library.ts b/app/lib/common/prompt-library.ts new file mode 100644 index 00000000..7513e811 --- /dev/null +++ b/app/lib/common/prompt-library.ts @@ -0,0 +1,49 @@ +import { getSystemPrompt } from './prompts/prompts'; +import optimized from './prompts/optimized'; + +export interface PromptOptions { + cwd: string; + allowedHtmlElements: string[]; + modificationTagName: string; +} + +export class PromptLibrary { + static library: Record< + string, + { + label: string; + description: string; + get: (options: PromptOptions) => string; + } + > = { + default: { + label: 'Default Prompt', + description: 'This is the battle tested default system Prompt', + get: (options) => getSystemPrompt(options.cwd), + }, + optimized: { + label: 'Optimized Prompt (experimental)', + description: 'an Experimental version of the prompt for lower token usage', + get: (options) => optimized(options), + }, + }; + static getList() { + return Object.entries(this.library).map(([key, value]) => { + const { label, description } = value; + return { + id: key, + label, + description, + }; + }); + } + static getPropmtFromLibrary(promptId: string, options: PromptOptions) { + const prompt = this.library[promptId]; + + if (!prompt) { + throw 'Prompt Now Found'; + } + + return this.library[promptId]?.get(options); + } +} diff --git a/app/lib/common/prompts/optimized.ts b/app/lib/common/prompts/optimized.ts new file mode 100644 index 00000000..64a1f8f2 --- /dev/null +++ b/app/lib/common/prompts/optimized.ts @@ -0,0 +1,135 @@ +import type { PromptOptions } from '~/lib/common/prompt-library'; + +export default (options: PromptOptions) => { + const { cwd, allowedHtmlElements, modificationTagName } = options; + return ` +You are Bolt, an expert AI assistant and senior software developer. +You have access to a shell and access to write files through the use of artifacts. +Your artifacts will be parsed by automated parser to perform actions on your behalf and will not be visible to the user + + + - Operating in WebContainer, an in-browser Node.js runtime + - Limited Python support: standard library only, no pip + - No C/C++ compiler, native binaries, or Git + - Prefer Node.js scripts over shell scripts + - Use Vite for web servers + - Databases: prefer libsql, sqlite, or non-native solutions + - When for react dont forget to write vite config and index.html to the project + + Available shell commands: cat, cp, ls, mkdir, mv, rm, rmdir, touch, hostname, ps, pwd, uptime, env, node, python3, code, jq, curl, head, sort, tail, clear, which, export, chmod, scho, kill, ln, xxd, alias, getconf, loadenv, wasm, xdg-open, command, exit, source + + + + Use 2 spaces for indentation + + + + Available HTML elements: ${allowedHtmlElements.join(', ')} + + + + File modifications in \`<${modificationTagName}>\` section: + - \`\`: GNU unified diff format + - \`\`: Full new content + + + + do not mention the phrase "chain of thought" + Before solutions, briefly outline implementation steps (2-4 lines max): + - List concrete steps + - Identify key components + - Note potential challenges + - Do not write the actual code just the plan and structure if needed + - Once completed planning start writing the artifacts + + + + Create a single, comprehensive artifact for each project: + - Use \`\` tags with \`title\` and \`id\` attributes + - Use \`\` tags with \`type\` attribute: + - shell: Run commands + - file: Write/update files (use \`filePath\` attribute) + - start: Start dev server (only when necessary) + - Order actions logically + - Install dependencies first + - Provide full, updated content for all files + - Use coding best practices: modular, clean, readable code + + +Key points: +- Always use artifacts for file contents and commands +- Use markdown, avoid HTML tags except in artifacts +- Be concise, explain only when asked +- Think first, then provide comprehensive artifact +- Never use the word "artifact" in responses +- Current working directory: \`${cwd}\` + +Examples: + + + + Create a JavaScript factorial function + + Certainly, I'll create a JavaScript factorial function for you. + + + + function factorial(n) { + return n <= 1 ? 1 : n * factorial(n - 1); + } + console.log(factorial(5)); + + + node factorial.js + + + + This creates a factorial function and tests it with the value 5. + + + + + Set up a basic React project + + Sure, I'll set up a basic React project for you. + + + + { + "name": "react-project", + "version": "1.0.0", + "scripts": { + "dev": "vite" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "vite": "^4.3.9" + } + } + + + npm install + + + import React from 'react'; + function App() { + return

Hello, React!

; + } + export default App; +
+ + npm run dev + +
+ + This sets up a basic React project with Vite as the build tool. +
+
+
+ +Always use artifacts for file contents and commands, following the format shown in these examples. +`; +}; diff --git a/app/lib/.server/llm/prompts.ts b/app/lib/common/prompts/prompts.ts similarity index 100% rename from app/lib/.server/llm/prompts.ts rename to app/lib/common/prompts/prompts.ts diff --git a/app/lib/hooks/useSettings.tsx b/app/lib/hooks/useSettings.tsx index 0e796516..4c74b218 100644 --- a/app/lib/hooks/useSettings.tsx +++ b/app/lib/hooks/useSettings.tsx @@ -4,6 +4,7 @@ import { isEventLogsEnabled, isLocalModelsEnabled, LOCAL_PROVIDERS, + promptStore, providersStore, } from '~/lib/stores/settings'; import { useCallback, useEffect, useState } from 'react'; @@ -15,6 +16,7 @@ export function useSettings() { const providers = useStore(providersStore); const debug = useStore(isDebugMode); const eventLogs = useStore(isEventLogsEnabled); + const promptId = useStore(promptStore); const isLocalModel = useStore(isLocalModelsEnabled); const [activeProviders, setActiveProviders] = useState([]); @@ -60,6 +62,12 @@ export function useSettings() { if (savedLocalModels) { isLocalModelsEnabled.set(savedLocalModels === 'true'); } + + const promptId = Cookies.get('promptId'); + + if (promptId) { + promptStore.set(promptId); + } }, []); // writing values to cookies on change @@ -111,6 +119,11 @@ export function useSettings() { Cookies.set('isLocalModelsEnabled', String(enabled)); }, []); + const setPromptId = useCallback((promptId: string) => { + promptStore.set(promptId); + Cookies.set('promptId', promptId); + }, []); + return { providers, activeProviders, @@ -121,5 +134,7 @@ export function useSettings() { enableEventLogs, isLocalModel, enableLocalModels, + promptId, + setPromptId, }; } diff --git a/app/lib/stores/settings.ts b/app/lib/stores/settings.ts index abbb825d..78682cc0 100644 --- a/app/lib/stores/settings.ts +++ b/app/lib/stores/settings.ts @@ -46,3 +46,5 @@ export const isDebugMode = atom(false); export const isEventLogsEnabled = atom(false); export const isLocalModelsEnabled = atom(true); + +export const promptStore = atom('default'); diff --git a/app/lib/stores/workbench.ts b/app/lib/stores/workbench.ts index bbd537d4..0d46057d 100644 --- a/app/lib/stores/workbench.ts +++ b/app/lib/stores/workbench.ts @@ -297,7 +297,6 @@ export class WorkbenchStore { const action = artifact.runner.actions.get()[data.actionId]; - if (!action || action.executed) { return; } diff --git a/app/routes/api.chat.ts b/app/routes/api.chat.ts index 87ca5c7c..d14e0d75 100644 --- a/app/routes/api.chat.ts +++ b/app/routes/api.chat.ts @@ -1,6 +1,6 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare'; import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS } from '~/lib/.server/llm/constants'; -import { CONTINUE_PROMPT } from '~/lib/.server/llm/prompts'; +import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts'; import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text'; import SwitchableStream from '~/lib/.server/llm/switchable-stream'; import type { IProviderSetting } from '~/types/model'; @@ -30,9 +30,10 @@ function parseCookies(cookieHeader: string) { } async function chatAction({ context, request }: ActionFunctionArgs) { - const { messages, files } = await request.json<{ + const { messages, files, promptId } = await request.json<{ messages: Messages; files: any; + promptId?: string; }>(); const cookieHeader = request.headers.get('Cookie'); @@ -71,6 +72,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) { apiKeys, files, providerSettings, + promptId, }); return stream.switchSource(result.toAIStream()); @@ -84,6 +86,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) { apiKeys, files, providerSettings, + promptId, }); stream.switchSource(result.toAIStream()); From 2b8236f9880984508f2ae17575b587bb9d938e55 Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Sun, 15 Dec 2024 20:28:15 +0530 Subject: [PATCH 06/27] updated readme --- README.md | 1 + app/commit.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 51264377..6a78e29d 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ https://thinktank.ottomator.ai - ✅ Better prompt enhancing (@SujalXplores) - ✅ Attach images to prompts (@atrokhym) - ✅ Detect package.json and commands to auto install and run preview for folder and git import (@wonderwhy-er) +- ✅ PromptLibrary to have different variations of prompts for different use cases (@thecodacus) - ⬜ **HIGH PRIORITY** - Prevent Bolt from rewriting files as often (file locking and diffs) - ⬜ **HIGH PRIORITY** - Better prompting for smaller LLMs (code window sometimes doesn't start) - ⬜ **HIGH PRIORITY** - Run agents in the backend as opposed to a single model call diff --git a/app/commit.json b/app/commit.json index be6c7229..b731c08a 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "79ce87ee5d729185bad73a37ebf77964f1488f59" } +{ "commit": "70f88f981a4195b70d3a62f0767c83bcf7894e0d" } From 6467995ac3b33cc3ebb1336cf63e4d0c0820a970 Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Sun, 15 Dec 2024 20:40:46 +0530 Subject: [PATCH 07/27] updated readme --- README.md | 2 ++ app/commit.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a78e29d..96e487f8 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ https://thinktank.ottomator.ai - ✅ Better prompt enhancing (@SujalXplores) - ✅ Attach images to prompts (@atrokhym) - ✅ Detect package.json and commands to auto install and run preview for folder and git import (@wonderwhy-er) +- ✅ Added Git Clone button (@thecodacus) +- ✅ Git Import from url (@thecodacus) - ✅ PromptLibrary to have different variations of prompts for different use cases (@thecodacus) - ⬜ **HIGH PRIORITY** - Prevent Bolt from rewriting files as often (file locking and diffs) - ⬜ **HIGH PRIORITY** - Better prompting for smaller LLMs (code window sometimes doesn't start) diff --git a/app/commit.json b/app/commit.json index b731c08a..fb908e47 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "70f88f981a4195b70d3a62f0767c83bcf7894e0d" } +{ "commit": "2b8236f9880984508f2ae17575b587bb9d938e55" } From 31706183b48cf5eee8b74be72821b19461b58d3d Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Sun, 15 Dec 2024 22:15:17 +0530 Subject: [PATCH 08/27] updated the examples and added strict rules --- app/commit.json | 2 +- app/components/chat/BaseChat.tsx | 8 +- .../settings/chat-history/ChatHistoryTab.tsx | 6 +- .../settings/features/FeaturesTab.tsx | 3 +- .../settings/providers/ProvidersTab.tsx | 3 +- app/lib/common/prompts/optimized.ts | 160 ++++++++++++------ app/utils/constants.ts | 2 +- 7 files changed, 125 insertions(+), 59 deletions(-) diff --git a/app/commit.json b/app/commit.json index 9d5c6d74..974cc2fe 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "9cd9ee9088467882e1e4efdf491959619307cc9d" } \ No newline at end of file +{ "commit": "9f5c01f5dd40fdbf4ae57bab163fdf8552b937ba" } diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 162241d9..2084cbb3 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -77,7 +77,8 @@ export const BaseChat = React.forwardRef( input = '', enhancingPrompt, handleInputChange, - promptEnhanced, + + // promptEnhanced, enhancePrompt, sendMessage, handleStop, @@ -490,10 +491,7 @@ export const BaseChat = React.forwardRef( { enhancePrompt?.(); toast.success('Prompt enhanced!'); diff --git a/app/components/settings/chat-history/ChatHistoryTab.tsx b/app/components/settings/chat-history/ChatHistoryTab.tsx index bd98f3d5..ea5187b2 100644 --- a/app/components/settings/chat-history/ChatHistoryTab.tsx +++ b/app/components/settings/chat-history/ChatHistoryTab.tsx @@ -22,7 +22,8 @@ export default function ChatHistoryTab() { }; const handleDeleteAllChats = async () => { - const confirmDelete = window.confirm("Are you sure you want to delete all chats? This action cannot be undone."); + const confirmDelete = window.confirm('Are you sure you want to delete all chats? This action cannot be undone.'); + if (!confirmDelete) { return; // Exit if the user cancels } @@ -31,11 +32,13 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to delete chats - DB unavailable', error); toast.error('Database is not available'); + return; } try { setIsDeleting(true); + const allChats = await getAll(db); await Promise.all(allChats.map((chat) => deleteById(db!, chat.id))); logStore.logSystem('All chats deleted successfully', { count: allChats.length }); @@ -55,6 +58,7 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to export chats - DB unavailable', error); toast.error('Database is not available'); + return; } diff --git a/app/components/settings/features/FeaturesTab.tsx b/app/components/settings/features/FeaturesTab.tsx index 815eb14a..91f5526f 100644 --- a/app/components/settings/features/FeaturesTab.tsx +++ b/app/components/settings/features/FeaturesTab.tsx @@ -4,8 +4,7 @@ import { PromptLibrary } from '~/lib/common/prompt-library'; import { useSettings } from '~/lib/hooks/useSettings'; export default function FeaturesTab() { - - const { debug, enableDebugMode, isLocalModel, enableLocalModels, eventLogs, enableEventLogs, promptId, setPromptId } = + const { debug, enableDebugMode, isLocalModel, enableLocalModels, enableEventLogs, promptId, setPromptId } = useSettings(); const handleToggle = (enabled: boolean) => { enableDebugMode(enabled); diff --git a/app/components/settings/providers/ProvidersTab.tsx b/app/components/settings/providers/ProvidersTab.tsx index 1c6e87d8..ab85898b 100644 --- a/app/components/settings/providers/ProvidersTab.tsx +++ b/app/components/settings/providers/ProvidersTab.tsx @@ -56,7 +56,8 @@ export default function ProvidersTab() {
{ // Fallback to default icon on error + onError={(e) => { + // Fallback to default icon on error e.currentTarget.src = DefaultIcon; }} alt={`${provider.name} icon`} diff --git a/app/lib/common/prompts/optimized.ts b/app/lib/common/prompts/optimized.ts index 64a1f8f2..26eb2da5 100644 --- a/app/lib/common/prompts/optimized.ts +++ b/app/lib/common/prompts/optimized.ts @@ -3,9 +3,7 @@ import type { PromptOptions } from '~/lib/common/prompt-library'; export default (options: PromptOptions) => { const { cwd, allowedHtmlElements, modificationTagName } = options; return ` -You are Bolt, an expert AI assistant and senior software developer. -You have access to a shell and access to write files through the use of artifacts. -Your artifacts will be parsed by automated parser to perform actions on your behalf and will not be visible to the user +You are Bolt, an expert AI assistant and exceptional senior software developer with vast knowledge across multiple programming languages, frameworks, and best practices. - Operating in WebContainer, an in-browser Node.js runtime @@ -56,80 +54,146 @@ Your artifacts will be parsed by automated parser to perform actions on your beh - Use coding best practices: modular, clean, readable code -Key points: -- Always use artifacts for file contents and commands -- Use markdown, avoid HTML tags except in artifacts -- Be concise, explain only when asked -- Think first, then provide comprehensive artifact -- Never use the word "artifact" in responses -- Current working directory: \`${cwd}\` + +# CRITICAL RULES - NEVER IGNORE + +## File and Command Handling +1. ALWAYS use artifacts for file contents and commands - NO EXCEPTIONS +2. When writing a file, INCLUDE THE ENTIRE FILE CONTENT - NO PARTIAL UPDATES +3. For modifications, ONLY alter files that require changes - DO NOT touch unaffected files + +## Response Format +4. Use markdown EXCLUSIVELY - HTML tags are ONLY allowed within artifacts +5. Be concise - Explain ONLY when explicitly requested +6. NEVER use the word "artifact" in responses + +## Development Process +7. ALWAYS think and plan comprehensively before providing a solution +8. Current working directory: \`${cwd} \` - Use this for all file paths +9. Don't use cli scaffolding to steup the project, use cwd as Root of the project +11. For nodejs projects ALWAYS install dependencies after writing package.json file + +## Coding Standards +10. ALWAYS create smaller, atomic components and modules +11. Modularity is PARAMOUNT - Break down functionality into logical, reusable parts +12. IMMEDIATELY refactor any file exceeding 250 lines +13. ALWAYS plan refactoring before implementation - Consider impacts on the entire system + +## Artifact Usage +22. Use \`\` tags with \`title\` and \`id\` attributes for each project +23. Use \`\` tags with appropriate \`type\` attribute: + - \`shell\`: For running commands + - \`file\`: For writing/updating files (include \`filePath\` attribute) + - \`start\`: For starting dev servers (use only when necessary/ or new dependencies are installed) +24. Order actions logically - dependencies MUST be installed first +25. For Vite project must include vite config and index.html for entry point +26. Provide COMPLETE, up-to-date content for all files - NO placeholders or partial updates + +CRITICAL: These rules are ABSOLUTE and MUST be followed WITHOUT EXCEPTION in EVERY response. Examples: - - Create a JavaScript factorial function + Can you help me create a JavaScript function to calculate the factorial of a number? - Certainly, I'll create a JavaScript factorial function for you. + Certainly, I can help you create a JavaScript function to calculate the factorial of a number. - - function factorial(n) { - return n <= 1 ? 1 : n * factorial(n - 1); - } - console.log(factorial(5)); + +function factorial(n) { + ... +} + +... - node factorial.js +node index.js - - This creates a factorial function and tests it with the value 5. - Set up a basic React project + Build a snake game - Sure, I'll set up a basic React project for you. + Certainly! I'd be happy to help you build a snake game using JavaScript and HTML5 Canvas. This will be a basic implementation that you can later expand upon. Let's create the game step by step. - + - { - "name": "react-project", - "version": "1.0.0", - "scripts": { - "dev": "vite" - }, - "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "vite": "^4.3.9" - } - } +{ + "name": "snake", + "scripts": { + "dev": "vite" + } + ... +} - npm install +npm install --save-dev vite - - import React from 'react'; - function App() { - return

Hello, React!

; - } - export default App; + +... - npm run dev +npm run dev
- This sets up a basic React project with Vite as the build tool. + Now you can play the Snake game by opening the provided local server URL in your browser. Use the arrow keys to control the snake. Eat the red food to grow and increase your score. The game ends if you hit the wall or your own tail. +
+
+ + + Make a bouncing ball with real gravity using React + + Certainly! I'll create a bouncing ball with real gravity using React. We'll use the react-spring library for physics-based animations. + + + +{ + "name": "bouncing-ball", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-spring": "^9.7.1" + }, + "devDependencies": { + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@vitejs/plugin-react": "^3.1.0", + "vite": "^4.2.0" + } +} + + +... + + +... + + +... + + +... + + +npm run dev + + + + You can now view the bouncing ball animation in the preview. The ball will start falling from the top of the screen and bounce realistically when it hits the bottom.
- Always use artifacts for file contents and commands, following the format shown in these examples. `; }; diff --git a/app/utils/constants.ts b/app/utils/constants.ts index 24c8668b..e83df05c 100644 --- a/app/utils/constants.ts +++ b/app/utils/constants.ts @@ -141,7 +141,7 @@ const PROVIDER_LIST: ProviderInfo[] = [ staticModels: [ { name: 'llama-3.1-8b-instant', label: 'Llama 3.1 8b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-11b-vision-preview', label: 'Llama 3.2 11b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, - { name: 'llama-3.2-90b-vision-preview', label: 'Llama 3.2 90b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, + { name: 'llama-3.2-90b-vision-preview', label: 'Llama 3.2 90b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-3b-preview', label: 'Llama 3.2 3b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-1b-preview', label: 'Llama 3.2 1b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.3-70b-versatile', label: 'Llama 3.3 70b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, From 885e104f279ab8b63d31e0759cbb675c2a409cc5 Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 01:54:24 +0530 Subject: [PATCH 09/27] added auto detect branch name and version tag --- .github/workflows/commit.yaml | 10 ++++- .github/workflows/update-stable.yml | 28 ++----------- app/commit.json | 2 +- app/components/chat/BaseChat.tsx | 6 +-- .../settings/chat-history/ChatHistoryTab.tsx | 6 ++- app/components/settings/debug/DebugTab.tsx | 35 +++++++++------- .../settings/features/FeaturesTab.tsx | 9 ++-- .../settings/providers/ProvidersTab.tsx | 3 +- app/lib/hooks/useSettings.tsx | 41 +++++++++++++------ app/lib/stores/settings.ts | 2 +- app/utils/constants.ts | 2 +- 11 files changed, 79 insertions(+), 65 deletions(-) diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index d5db06b0..d6b3193f 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -20,9 +20,17 @@ jobs: - name: Get the latest commit hash run: echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Update commit file run: | - echo "{ \"commit\": \"$COMMIT_HASH\" }" > app/commit.json + echo CURRENT_VERSION=$(node -p "require('./package.json').version") >> $GITHUB_ENV + echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json - name: Commit and push the update run: | diff --git a/.github/workflows/update-stable.yml b/.github/workflows/update-stable.yml index 2956f64c..e6fc2e58 100644 --- a/.github/workflows/update-stable.yml +++ b/.github/workflows/update-stable.yml @@ -9,30 +9,7 @@ permissions: contents: write jobs: - update-commit: - if: contains(github.event.head_commit.message, '#release') - runs-on: ubuntu-latest - - steps: - - name: Checkout the code - uses: actions/checkout@v3 - - - name: Get the latest commit hash - run: echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV - - - name: Update commit file - run: | - echo "{ \"commit\": \"$COMMIT_HASH\" }" > app/commit.json - - - name: Commit and push the update - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - git add app/commit.json - git commit -m "chore: update commit hash to $COMMIT_HASH" - git push prepare-release: - needs: update-commit if: contains(github.event.head_commit.message, '#release') runs-on: ubuntu-latest @@ -183,8 +160,11 @@ jobs: - name: Commit and Tag Release run: | + echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV + echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV git pull - git add package.json pnpm-lock.yaml changelog.md + echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json + git add package.json pnpm-lock.yaml changelog.md app/commit.json git commit -m "chore: release version ${{ steps.bump_version.outputs.new_version }}" git tag "v${{ steps.bump_version.outputs.new_version }}" git push diff --git a/app/commit.json b/app/commit.json index f60467a1..35ff29cc 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "4016f54933102bf67336b8ae58e14673dfad72ee" } +{ "commit": "c4f94aa517a1b46168aaa4aaf1aff3178fea24f0" } diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 162241d9..edefe058 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -77,7 +77,6 @@ export const BaseChat = React.forwardRef( input = '', enhancingPrompt, handleInputChange, - promptEnhanced, enhancePrompt, sendMessage, handleStop, @@ -490,10 +489,7 @@ export const BaseChat = React.forwardRef( { enhancePrompt?.(); toast.success('Prompt enhanced!'); diff --git a/app/components/settings/chat-history/ChatHistoryTab.tsx b/app/components/settings/chat-history/ChatHistoryTab.tsx index bd98f3d5..ea5187b2 100644 --- a/app/components/settings/chat-history/ChatHistoryTab.tsx +++ b/app/components/settings/chat-history/ChatHistoryTab.tsx @@ -22,7 +22,8 @@ export default function ChatHistoryTab() { }; const handleDeleteAllChats = async () => { - const confirmDelete = window.confirm("Are you sure you want to delete all chats? This action cannot be undone."); + const confirmDelete = window.confirm('Are you sure you want to delete all chats? This action cannot be undone.'); + if (!confirmDelete) { return; // Exit if the user cancels } @@ -31,11 +32,13 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to delete chats - DB unavailable', error); toast.error('Database is not available'); + return; } try { setIsDeleting(true); + const allChats = await getAll(db); await Promise.all(allChats.map((chat) => deleteById(db!, chat.id))); logStore.logSystem('All chats deleted successfully', { count: allChats.length }); @@ -55,6 +58,7 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to export chats - DB unavailable', error); toast.error('Database is not available'); + return; } diff --git a/app/components/settings/debug/DebugTab.tsx b/app/components/settings/debug/DebugTab.tsx index fea78c83..76746a85 100644 --- a/app/components/settings/debug/DebugTab.tsx +++ b/app/components/settings/debug/DebugTab.tsx @@ -34,14 +34,19 @@ interface IProviderConfig { interface CommitData { commit: string; + version?: string; } +const connitJson: CommitData = commit; + const LOCAL_PROVIDERS = ['Ollama', 'LMStudio', 'OpenAILike']; -const versionHash = commit.commit; +const versionHash = connitJson.commit; +const versionTag = connitJson.version; const GITHUB_URLS = { original: 'https://api.github.com/repos/stackblitz-labs/bolt.diy/commits/main', fork: 'https://api.github.com/repos/Stijnus/bolt.new-any-llm/commits/main', - commitJson: (branch: string) => `https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/${branch}/app/commit.json`, + commitJson: (branch: string) => + `https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/${branch}/app/commit.json`, }; function getSystemInfo(): SystemInfo { @@ -206,7 +211,7 @@ const checkProviderStatus = async (url: string | null, providerName: string): Pr }; export default function DebugTab() { - const { providers, useLatestBranch } = useSettings(); + const { providers, latestBranch } = useSettings(); const [activeProviders, setActiveProviders] = useState([]); const [updateMessage, setUpdateMessage] = useState(''); const [systemInfo] = useState(getSystemInfo()); @@ -227,19 +232,20 @@ export default function DebugTab() { provider.name.toLowerCase() === 'ollama' ? 'OLLAMA_API_BASE_URL' : provider.name.toLowerCase() === 'lmstudio' - ? 'LMSTUDIO_API_BASE_URL' - : `REACT_APP_${provider.name.toUpperCase()}_URL`; + ? 'LMSTUDIO_API_BASE_URL' + : `REACT_APP_${provider.name.toUpperCase()}_URL`; // Access environment variables through import.meta.env const url = import.meta.env[envVarName] || provider.settings.baseUrl || null; // Ensure baseUrl is used console.log(`[Debug] Using URL for ${provider.name}:`, url, `(from ${envVarName})`); const status = await checkProviderStatus(url, provider.name); + return { ...status, enabled: provider.settings.enabled ?? false, }; - }) + }), ); setActiveProviders(statuses); @@ -265,23 +271,24 @@ export default function DebugTab() { setIsCheckingUpdate(true); setUpdateMessage('Checking for updates...'); - const branchToCheck = useLatestBranch ? 'main' : 'stable'; + const branchToCheck = latestBranch ? 'main' : 'stable'; console.log(`[Debug] Checking for updates against ${branchToCheck} branch`); const localCommitResponse = await fetch(GITHUB_URLS.commitJson(branchToCheck)); + if (!localCommitResponse.ok) { throw new Error('Failed to fetch local commit info'); } - const localCommitData = await localCommitResponse.json() as CommitData; + const localCommitData = (await localCommitResponse.json()) as CommitData; const remoteCommitHash = localCommitData.commit; const currentCommitHash = versionHash; if (remoteCommitHash !== currentCommitHash) { setUpdateMessage( `Update available from ${branchToCheck} branch!\n` + - `Current: ${currentCommitHash.slice(0, 7)}\n` + - `Latest: ${remoteCommitHash.slice(0, 7)}` + `Current: ${currentCommitHash.slice(0, 7)}\n` + + `Latest: ${remoteCommitHash.slice(0, 7)}`, ); } else { setUpdateMessage(`You are on the latest version from the ${branchToCheck} branch`); @@ -292,7 +299,7 @@ export default function DebugTab() { } finally { setIsCheckingUpdate(false); } - }, [isCheckingUpdate, useLatestBranch]); + }, [isCheckingUpdate, latestBranch]); const handleCopyToClipboard = useCallback(() => { const debugInfo = { @@ -309,7 +316,7 @@ export default function DebugTab() { })), Version: { hash: versionHash.slice(0, 7), - branch: useLatestBranch ? 'main' : 'stable' + branch: latestBranch ? 'main' : 'stable', }, Timestamp: new Date().toISOString(), }; @@ -317,7 +324,7 @@ export default function DebugTab() { navigator.clipboard.writeText(JSON.stringify(debugInfo, null, 2)).then(() => { toast.success('Debug information copied to clipboard!'); }); - }, [activeProviders, systemInfo, useLatestBranch]); + }, [activeProviders, systemInfo, latestBranch]); return (
@@ -403,7 +410,7 @@ export default function DebugTab() {

{versionHash.slice(0, 7)} - ({new Date().toLocaleDateString()}) + (v{versionTag}) - {latestBranch ? 'nightly' : 'stable'}

diff --git a/app/components/settings/features/FeaturesTab.tsx b/app/components/settings/features/FeaturesTab.tsx index c0b33add..410f7ca0 100644 --- a/app/components/settings/features/FeaturesTab.tsx +++ b/app/components/settings/features/FeaturesTab.tsx @@ -3,7 +3,8 @@ import { Switch } from '~/components/ui/Switch'; import { useSettings } from '~/lib/hooks/useSettings'; export default function FeaturesTab() { - const { debug, enableDebugMode, isLocalModel, enableLocalModels, eventLogs, enableEventLogs, useLatestBranch, enableLatestBranch } = useSettings(); + const { debug, enableDebugMode, isLocalModel, enableLocalModels, enableEventLogs, latestBranch, enableLatestBranch } = + useSettings(); const handleToggle = (enabled: boolean) => { enableDebugMode(enabled); @@ -22,9 +23,11 @@ export default function FeaturesTab() {
Use Main Branch -

Check for updates against the main branch instead of stable

+

+ Check for updates against the main branch instead of stable +

- +
diff --git a/app/components/settings/providers/ProvidersTab.tsx b/app/components/settings/providers/ProvidersTab.tsx index 1c6e87d8..ab85898b 100644 --- a/app/components/settings/providers/ProvidersTab.tsx +++ b/app/components/settings/providers/ProvidersTab.tsx @@ -56,7 +56,8 @@ export default function ProvidersTab() {
{ // Fallback to default icon on error + onError={(e) => { + // Fallback to default icon on error e.currentTarget.src = DefaultIcon; }} alt={`${provider.name} icon`} diff --git a/app/lib/hooks/useSettings.tsx b/app/lib/hooks/useSettings.tsx index 0a7d65eb..36eefb42 100644 --- a/app/lib/hooks/useSettings.tsx +++ b/app/lib/hooks/useSettings.tsx @@ -5,7 +5,7 @@ import { isLocalModelsEnabled, LOCAL_PROVIDERS, providersStore, - latestBranch, + latestBranchStore, } from '~/lib/stores/settings'; import { useCallback, useEffect, useState } from 'react'; import Cookies from 'js-cookie'; @@ -15,25 +15,33 @@ import commit from '~/commit.json'; interface CommitData { commit: string; + version?: string; } +const commitJson: CommitData = commit; + export function useSettings() { const providers = useStore(providersStore); const debug = useStore(isDebugMode); const eventLogs = useStore(isEventLogsEnabled); const isLocalModel = useStore(isLocalModelsEnabled); - const useLatest = useStore(latestBranch); + const latestBranch = useStore(latestBranchStore); const [activeProviders, setActiveProviders] = useState([]); // Function to check if we're on stable version const checkIsStableVersion = async () => { try { - const stableResponse = await fetch('https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/stable/app/commit.json'); + const stableResponse = await fetch( + `https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/refs/tags/v${commitJson.version}/app/commit.json`, + ); + if (!stableResponse.ok) { console.warn('Failed to fetch stable commit info'); return false; } - const stableData = await stableResponse.json() as CommitData; + + const stableData = (await stableResponse.json()) as CommitData; + return commit.commit === stableData.commit; } catch (error) { console.warn('Error checking stable version:', error); @@ -85,16 +93,23 @@ export function useSettings() { } // load latest branch setting from cookies or determine based on version - const savedLatestBranch = Cookies.get('useLatestBranch'); - if (savedLatestBranch === undefined) { + const savedLatestBranch = Cookies.get('latestBranch'); + let checkCommit = Cookies.get('commitHash'); + + if (checkCommit === undefined) { + checkCommit = commit.commit; + } + + if (savedLatestBranch === undefined || checkCommit !== commit.commit) { // If setting hasn't been set by user, check version - checkIsStableVersion().then(isStable => { + checkIsStableVersion().then((isStable) => { const shouldUseLatest = !isStable; - latestBranch.set(shouldUseLatest); - Cookies.set('useLatestBranch', String(shouldUseLatest)); + latestBranchStore.set(shouldUseLatest); + Cookies.set('latestBranch', String(shouldUseLatest)); + Cookies.set('commitHash', String(commit.commit)); }); } else { - latestBranch.set(savedLatestBranch === 'true'); + latestBranchStore.set(savedLatestBranch === 'true'); } }, []); @@ -148,9 +163,9 @@ export function useSettings() { }, []); const enableLatestBranch = useCallback((enabled: boolean) => { - latestBranch.set(enabled); + latestBranchStore.set(enabled); logStore.logSystem(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`); - Cookies.set('useLatestBranch', String(enabled)); + Cookies.set('latestBranch', String(enabled)); }, []); return { @@ -163,7 +178,7 @@ export function useSettings() { enableEventLogs, isLocalModel, enableLocalModels, - useLatestBranch: useLatest, + latestBranch, enableLatestBranch, }; } diff --git a/app/lib/stores/settings.ts b/app/lib/stores/settings.ts index 2e410a60..b2f41335 100644 --- a/app/lib/stores/settings.ts +++ b/app/lib/stores/settings.ts @@ -47,4 +47,4 @@ export const isEventLogsEnabled = atom(false); export const isLocalModelsEnabled = atom(true); -export const latestBranch = atom(false); +export const latestBranchStore = atom(false); diff --git a/app/utils/constants.ts b/app/utils/constants.ts index 24c8668b..e83df05c 100644 --- a/app/utils/constants.ts +++ b/app/utils/constants.ts @@ -141,7 +141,7 @@ const PROVIDER_LIST: ProviderInfo[] = [ staticModels: [ { name: 'llama-3.1-8b-instant', label: 'Llama 3.1 8b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-11b-vision-preview', label: 'Llama 3.2 11b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, - { name: 'llama-3.2-90b-vision-preview', label: 'Llama 3.2 90b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, + { name: 'llama-3.2-90b-vision-preview', label: 'Llama 3.2 90b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-3b-preview', label: 'Llama 3.2 3b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.2-1b-preview', label: 'Llama 3.2 1b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, { name: 'llama-3.3-70b-versatile', label: 'Llama 3.3 70b (Groq)', provider: 'Groq', maxTokenAllowed: 8000 }, From d3727459aa594505efd0cef58c4218eaf48d5baf Mon Sep 17 00:00:00 2001 From: Stijnus <72551117+Stijnus@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:27:07 +0100 Subject: [PATCH 10/27] Update DebugTab.tsx Fix debug information --- app/commit.json | 2 +- app/components/settings/debug/DebugTab.tsx | 119 ++++++++++++++++++++- 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/app/commit.json b/app/commit.json index 5bb65969..fd149318 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "d479daa5781a533c68a6f9ffdb3b919914c9305e" } +{ "commit": "85b0322fd6e9c2760805e6372c487fb0432955de" } diff --git a/app/components/settings/debug/DebugTab.tsx b/app/components/settings/debug/DebugTab.tsx index e18607d6..03f2fa86 100644 --- a/app/components/settings/debug/DebugTab.tsx +++ b/app/components/settings/debug/DebugTab.tsx @@ -21,6 +21,12 @@ interface SystemInfo { timezone: string; memory: string; cores: number; + deviceType: string; + colorDepth: string; + pixelRatio: number; + online: boolean; + cookiesEnabled: boolean; + doNotTrack: boolean; } interface IProviderConfig { @@ -50,14 +56,100 @@ function getSystemInfo(): SystemInfo { return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; + const getBrowserInfo = (): string => { + const ua = navigator.userAgent; + let browser = 'Unknown'; + + if (ua.includes('Firefox/')) { + browser = 'Firefox'; + } else if (ua.includes('Chrome/')) { + if (ua.includes('Edg/')) { + browser = 'Edge'; + } else if (ua.includes('OPR/')) { + browser = 'Opera'; + } else { + browser = 'Chrome'; + } + } else if (ua.includes('Safari/')) { + if (!ua.includes('Chrome')) { + browser = 'Safari'; + } + } + + // Extract version number + const match = ua.match(new RegExp(`${browser}\\/([\\d.]+)`)); + const version = match ? ` ${match[1]}` : ''; + + return `${browser}${version}`; + }; + + const getOperatingSystem = (): string => { + const ua = navigator.userAgent; + const platform = navigator.platform; + + if (ua.includes('Win')) { + return 'Windows'; + } + + if (ua.includes('Mac')) { + if (ua.includes('iPhone') || ua.includes('iPad')) { + return 'iOS'; + } + + return 'macOS'; + } + + if (ua.includes('Linux')) { + return 'Linux'; + } + + if (ua.includes('Android')) { + return 'Android'; + } + + return platform || 'Unknown'; + }; + + const getDeviceType = (): string => { + const ua = navigator.userAgent; + + if (ua.includes('Mobile')) { + return 'Mobile'; + } + + if (ua.includes('Tablet')) { + return 'Tablet'; + } + + return 'Desktop'; + }; + + // Get more detailed memory info if available + const getMemoryInfo = (): string => { + if ('memory' in performance) { + const memory = (performance as any).memory; + return `${formatBytes(memory.jsHeapSizeLimit)} (Used: ${formatBytes(memory.usedJSHeapSize)})`; + } + + return 'Not available'; + }; + return { - os: navigator.platform, - browser: navigator.userAgent.split(' ').slice(-1)[0], + os: getOperatingSystem(), + browser: getBrowserInfo(), screen: `${window.screen.width}x${window.screen.height}`, language: navigator.language, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, - memory: formatBytes(performance?.memory?.jsHeapSizeLimit || 0), + memory: getMemoryInfo(), cores: navigator.hardwareConcurrency || 0, + deviceType: getDeviceType(), + + // Add new fields + colorDepth: `${window.screen.colorDepth}-bit`, + pixelRatio: window.devicePixelRatio, + online: navigator.onLine, + cookiesEnabled: navigator.cookieEnabled, + doNotTrack: navigator.doNotTrack === '1', }; } @@ -371,10 +463,31 @@ export default function DebugTab() {

Operating System

{systemInfo.os}

+
+

Device Type

+

{systemInfo.deviceType}

+

Browser

{systemInfo.browser}

+
+

Display

+

+ {systemInfo.screen} ({systemInfo.colorDepth}) @{systemInfo.pixelRatio}x +

+
+
+

Connection

+

+ + + {systemInfo.online ? 'Online' : 'Offline'} + +

+

Screen Resolution

{systemInfo.screen}

From bc6b84851f56a87f5f9589505a25908158f14dc6 Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 02:08:58 +0530 Subject: [PATCH 11/27] fix --- app/commit.json | 2 +- app/components/settings/debug/DebugTab.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/commit.json b/app/commit.json index 35ff29cc..4e78ac77 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "c4f94aa517a1b46168aaa4aaf1aff3178fea24f0" } +{ "commit": "885e104f279ab8b63d31e0759cbb675c2a409cc5" } diff --git a/app/components/settings/debug/DebugTab.tsx b/app/components/settings/debug/DebugTab.tsx index 76746a85..cd40806a 100644 --- a/app/components/settings/debug/DebugTab.tsx +++ b/app/components/settings/debug/DebugTab.tsx @@ -410,7 +410,7 @@ export default function DebugTab() {

{versionHash.slice(0, 7)} - (v{versionTag}) - {latestBranch ? 'nightly' : 'stable'} + (v{versionTag || '0.0.1'}) - {latestBranch ? 'nightly' : 'stable'}

From 039e616bf57dbc080f0e7698e7c5d31369afe552 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 15 Dec 2024 22:15:59 +0000 Subject: [PATCH 12/27] chore: update commit hash to d3727459aa594505efd0cef58c4218eaf48d5baf --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index fd149318..1c1e2be0 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "85b0322fd6e9c2760805e6372c487fb0432955de" } +{ "commit": "d3727459aa594505efd0cef58c4218eaf48d5baf" } From 225b55387669c9216f60896514e762515b8b1838 Mon Sep 17 00:00:00 2001 From: eduardruzga Date: Mon, 16 Dec 2024 11:01:41 +0200 Subject: [PATCH 13/27] Another attempt to add toek usage info --- app/commit.json | 2 +- app/components/chat/AssistantMessage.tsx | 12 +++++++- app/components/chat/UserMessage.tsx | 36 ++++++++++-------------- app/lib/.server/llm/switchable-stream.ts | 2 +- app/routes/api.chat.ts | 25 ++++++++++++++++ app/utils/constants.ts | 1 + 6 files changed, 54 insertions(+), 24 deletions(-) diff --git a/app/commit.json b/app/commit.json index 46c97342..018af740 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "fcb61ba49990d1d0cc13d05a0958007b6e9c1c38" } +{ "commit": "2e05270bab264d7ee83d7a1dd5408c969f648a68" } diff --git a/app/components/chat/AssistantMessage.tsx b/app/components/chat/AssistantMessage.tsx index a5698e97..7cdddda3 100644 --- a/app/components/chat/AssistantMessage.tsx +++ b/app/components/chat/AssistantMessage.tsx @@ -1,14 +1,24 @@ import { memo } from 'react'; import { Markdown } from './Markdown'; +import { USAGE_REGEX } from '~/utils/constants'; interface AssistantMessageProps { content: string; } export const AssistantMessage = memo(({ content }: AssistantMessageProps) => { + const match = content.match(USAGE_REGEX); + const usage = match ? JSON.parse(match[1]) : null; + const cleanContent = content.replace(USAGE_REGEX, '').trim(); + return (
- {content} + {usage && ( +
+ Tokens: {usage.totalTokens} (prompt: {usage.promptTokens}, completion: {usage.completionTokens}) +
+ )} + {cleanContent}
); }); diff --git a/app/components/chat/UserMessage.tsx b/app/components/chat/UserMessage.tsx index 3e6485bf..6fd6fc0d 100644 --- a/app/components/chat/UserMessage.tsx +++ b/app/components/chat/UserMessage.tsx @@ -12,42 +12,36 @@ interface UserMessageProps { export function UserMessage({ content }: UserMessageProps) { if (Array.isArray(content)) { const textItem = content.find((item) => item.type === 'text'); - const textContent = sanitizeUserMessage(textItem?.text || ''); + const textContent = stripMetadata(textItem?.text || ''); const images = content.filter((item) => item.type === 'image' && item.image); return (
-
-
- {textContent} -
- {images.length > 0 && ( -
- {images.map((item, index) => ( -
- {`Uploaded -
- ))} -
- )} +
+ {textContent && {textContent}} + {images.map((item, index) => ( + {`Image + ))}
); } - const textContent = sanitizeUserMessage(content); + const textContent = stripMetadata(content); return (
- {textContent} + {textContent}
); } -function sanitizeUserMessage(content: string) { +function stripMetadata(content: string) { return content.replace(MODEL_REGEX, '').replace(PROVIDER_REGEX, ''); } diff --git a/app/lib/.server/llm/switchable-stream.ts b/app/lib/.server/llm/switchable-stream.ts index 638db7a4..51f46ff2 100644 --- a/app/lib/.server/llm/switchable-stream.ts +++ b/app/lib/.server/llm/switchable-stream.ts @@ -1,5 +1,5 @@ export default class SwitchableStream extends TransformStream { - private _controller: TransformStreamDefaultController | null = null; + _controller: TransformStreamDefaultController | null = null; private _currentReader: ReadableStreamDefaultReader | null = null; private _switches = 0; diff --git a/app/routes/api.chat.ts b/app/routes/api.chat.ts index 34dea349..c7d63839 100644 --- a/app/routes/api.chat.ts +++ b/app/routes/api.chat.ts @@ -41,12 +41,36 @@ async function chatAction({ context, request }: ActionFunctionArgs) { const stream = new SwitchableStream(); + const cumulativeUsage = { + completionTokens: 0, + promptTokens: 0, + totalTokens: 0, + }; + try { const options: StreamingOptions = { toolChoice: 'none', onFinish: async ({ text: content, finishReason, usage }) => { console.log('usage', usage); + if (usage && stream._controller) { + cumulativeUsage.completionTokens += usage.completionTokens || 0; + cumulativeUsage.promptTokens += usage.promptTokens || 0; + cumulativeUsage.totalTokens += usage.totalTokens || 0; + + // Send usage info in message metadata for assistant messages + const usageMetadata = `0:"[Usage: ${JSON.stringify({ + completionTokens: cumulativeUsage.completionTokens, + promptTokens: cumulativeUsage.promptTokens, + totalTokens: cumulativeUsage.totalTokens, + })}\n]"`; + + console.log(usageMetadata); + + const encodedData = new TextEncoder().encode(usageMetadata); + stream._controller.enqueue(encodedData); + } + if (finishReason !== 'length') { return stream.close(); } @@ -83,6 +107,7 @@ async function chatAction({ context, request }: ActionFunctionArgs) { files, providerSettings, }); + stream.switchSource(result.toDataStream()); return new Response(stream.readable, { diff --git a/app/utils/constants.ts b/app/utils/constants.ts index cc2aafc9..2ab6cfbf 100644 --- a/app/utils/constants.ts +++ b/app/utils/constants.ts @@ -9,6 +9,7 @@ export const WORK_DIR = `/home/${WORK_DIR_NAME}`; export const MODIFICATIONS_TAG_NAME = 'bolt_file_modifications'; export const MODEL_REGEX = /^\[Model: (.*?)\]\n\n/; export const PROVIDER_REGEX = /\[Provider: (.*?)\]\n\n/; +export const USAGE_REGEX = /\[Usage: ({.*?})\]/; // Keep this regex for assistant messages export const DEFAULT_MODEL = 'claude-3-5-sonnet-latest'; export const PROMPT_COOKIE_KEY = 'cachedPrompt'; From 070e911be17e1e1f3994220c3ed89b0060c67bd2 Mon Sep 17 00:00:00 2001 From: eduardruzga Date: Mon, 16 Dec 2024 11:09:35 +0200 Subject: [PATCH 14/27] Lint fix --- app/components/chat/BaseChat.tsx | 6 +----- .../settings/chat-history/ChatHistoryTab.tsx | 6 +++++- app/components/settings/debug/DebugTab.tsx | 19 +++++++++++-------- .../settings/features/FeaturesTab.tsx | 14 ++++++++++++-- .../settings/providers/ProvidersTab.tsx | 3 ++- app/lib/hooks/useSettings.tsx | 12 +++++++++--- 6 files changed, 40 insertions(+), 20 deletions(-) diff --git a/app/components/chat/BaseChat.tsx b/app/components/chat/BaseChat.tsx index 162241d9..edefe058 100644 --- a/app/components/chat/BaseChat.tsx +++ b/app/components/chat/BaseChat.tsx @@ -77,7 +77,6 @@ export const BaseChat = React.forwardRef( input = '', enhancingPrompt, handleInputChange, - promptEnhanced, enhancePrompt, sendMessage, handleStop, @@ -490,10 +489,7 @@ export const BaseChat = React.forwardRef( { enhancePrompt?.(); toast.success('Prompt enhanced!'); diff --git a/app/components/settings/chat-history/ChatHistoryTab.tsx b/app/components/settings/chat-history/ChatHistoryTab.tsx index bd98f3d5..ea5187b2 100644 --- a/app/components/settings/chat-history/ChatHistoryTab.tsx +++ b/app/components/settings/chat-history/ChatHistoryTab.tsx @@ -22,7 +22,8 @@ export default function ChatHistoryTab() { }; const handleDeleteAllChats = async () => { - const confirmDelete = window.confirm("Are you sure you want to delete all chats? This action cannot be undone."); + const confirmDelete = window.confirm('Are you sure you want to delete all chats? This action cannot be undone.'); + if (!confirmDelete) { return; // Exit if the user cancels } @@ -31,11 +32,13 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to delete chats - DB unavailable', error); toast.error('Database is not available'); + return; } try { setIsDeleting(true); + const allChats = await getAll(db); await Promise.all(allChats.map((chat) => deleteById(db!, chat.id))); logStore.logSystem('All chats deleted successfully', { count: allChats.length }); @@ -55,6 +58,7 @@ export default function ChatHistoryTab() { const error = new Error('Database is not available'); logStore.logError('Failed to export chats - DB unavailable', error); toast.error('Database is not available'); + return; } diff --git a/app/components/settings/debug/DebugTab.tsx b/app/components/settings/debug/DebugTab.tsx index fea78c83..a7021f7e 100644 --- a/app/components/settings/debug/DebugTab.tsx +++ b/app/components/settings/debug/DebugTab.tsx @@ -41,7 +41,8 @@ const versionHash = commit.commit; const GITHUB_URLS = { original: 'https://api.github.com/repos/stackblitz-labs/bolt.diy/commits/main', fork: 'https://api.github.com/repos/Stijnus/bolt.new-any-llm/commits/main', - commitJson: (branch: string) => `https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/${branch}/app/commit.json`, + commitJson: (branch: string) => + `https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/${branch}/app/commit.json`, }; function getSystemInfo(): SystemInfo { @@ -227,19 +228,20 @@ export default function DebugTab() { provider.name.toLowerCase() === 'ollama' ? 'OLLAMA_API_BASE_URL' : provider.name.toLowerCase() === 'lmstudio' - ? 'LMSTUDIO_API_BASE_URL' - : `REACT_APP_${provider.name.toUpperCase()}_URL`; + ? 'LMSTUDIO_API_BASE_URL' + : `REACT_APP_${provider.name.toUpperCase()}_URL`; // Access environment variables through import.meta.env const url = import.meta.env[envVarName] || provider.settings.baseUrl || null; // Ensure baseUrl is used console.log(`[Debug] Using URL for ${provider.name}:`, url, `(from ${envVarName})`); const status = await checkProviderStatus(url, provider.name); + return { ...status, enabled: provider.settings.enabled ?? false, }; - }) + }), ); setActiveProviders(statuses); @@ -269,19 +271,20 @@ export default function DebugTab() { console.log(`[Debug] Checking for updates against ${branchToCheck} branch`); const localCommitResponse = await fetch(GITHUB_URLS.commitJson(branchToCheck)); + if (!localCommitResponse.ok) { throw new Error('Failed to fetch local commit info'); } - const localCommitData = await localCommitResponse.json() as CommitData; + const localCommitData = (await localCommitResponse.json()) as CommitData; const remoteCommitHash = localCommitData.commit; const currentCommitHash = versionHash; if (remoteCommitHash !== currentCommitHash) { setUpdateMessage( `Update available from ${branchToCheck} branch!\n` + - `Current: ${currentCommitHash.slice(0, 7)}\n` + - `Latest: ${remoteCommitHash.slice(0, 7)}` + `Current: ${currentCommitHash.slice(0, 7)}\n` + + `Latest: ${remoteCommitHash.slice(0, 7)}`, ); } else { setUpdateMessage(`You are on the latest version from the ${branchToCheck} branch`); @@ -309,7 +312,7 @@ export default function DebugTab() { })), Version: { hash: versionHash.slice(0, 7), - branch: useLatestBranch ? 'main' : 'stable' + branch: useLatestBranch ? 'main' : 'stable', }, Timestamp: new Date().toISOString(), }; diff --git a/app/components/settings/features/FeaturesTab.tsx b/app/components/settings/features/FeaturesTab.tsx index c0b33add..d16d6850 100644 --- a/app/components/settings/features/FeaturesTab.tsx +++ b/app/components/settings/features/FeaturesTab.tsx @@ -3,7 +3,15 @@ import { Switch } from '~/components/ui/Switch'; import { useSettings } from '~/lib/hooks/useSettings'; export default function FeaturesTab() { - const { debug, enableDebugMode, isLocalModel, enableLocalModels, eventLogs, enableEventLogs, useLatestBranch, enableLatestBranch } = useSettings(); + const { + debug, + enableDebugMode, + isLocalModel, + enableLocalModels, + enableEventLogs, + useLatestBranch, + enableLatestBranch, + } = useSettings(); const handleToggle = (enabled: boolean) => { enableDebugMode(enabled); @@ -22,7 +30,9 @@ export default function FeaturesTab() {
Use Main Branch -

Check for updates against the main branch instead of stable

+

+ Check for updates against the main branch instead of stable +

diff --git a/app/components/settings/providers/ProvidersTab.tsx b/app/components/settings/providers/ProvidersTab.tsx index 926a3c89..281b4c80 100644 --- a/app/components/settings/providers/ProvidersTab.tsx +++ b/app/components/settings/providers/ProvidersTab.tsx @@ -56,7 +56,8 @@ export default function ProvidersTab() {
{ // Fallback to default icon on error + onError={(e) => { + // Fallback to default icon on error e.currentTarget.src = DefaultIcon; }} alt={`${provider.name} icon`} diff --git a/app/lib/hooks/useSettings.tsx b/app/lib/hooks/useSettings.tsx index 0a7d65eb..c8b19689 100644 --- a/app/lib/hooks/useSettings.tsx +++ b/app/lib/hooks/useSettings.tsx @@ -28,12 +28,17 @@ export function useSettings() { // Function to check if we're on stable version const checkIsStableVersion = async () => { try { - const stableResponse = await fetch('https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/stable/app/commit.json'); + const stableResponse = await fetch( + 'https://raw.githubusercontent.com/stackblitz-labs/bolt.diy/stable/app/commit.json', + ); + if (!stableResponse.ok) { console.warn('Failed to fetch stable commit info'); return false; } - const stableData = await stableResponse.json() as CommitData; + + const stableData = (await stableResponse.json()) as CommitData; + return commit.commit === stableData.commit; } catch (error) { console.warn('Error checking stable version:', error); @@ -86,9 +91,10 @@ export function useSettings() { // load latest branch setting from cookies or determine based on version const savedLatestBranch = Cookies.get('useLatestBranch'); + if (savedLatestBranch === undefined) { // If setting hasn't been set by user, check version - checkIsStableVersion().then(isStable => { + checkIsStableVersion().then((isStable) => { const shouldUseLatest = !isStable; latestBranch.set(shouldUseLatest); Cookies.set('useLatestBranch', String(shouldUseLatest)); From 3b8d251a55661ae5483e03f7c6af776de2223c3d Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 19:47:18 +0530 Subject: [PATCH 15/27] updated implementation --- app/commit.json | 2 +- app/components/chat/AssistantMessage.tsx | 19 +++++++++----- app/components/chat/Messages.client.tsx | 6 ++++- app/lib/.server/llm/switchable-stream.ts | 2 +- app/routes/api.chat.ts | 33 ++++++++++++++---------- app/utils/constants.ts | 1 - 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/app/commit.json b/app/commit.json index d39a9804..ab67c57b 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "6ba93974a02a98c83badf2f0002ff4812b8f75a9" } +{ "commit": "070e911be17e1e1f3994220c3ed89b0060c67bd2" } diff --git a/app/components/chat/AssistantMessage.tsx b/app/components/chat/AssistantMessage.tsx index 7cdddda3..be304c7b 100644 --- a/app/components/chat/AssistantMessage.tsx +++ b/app/components/chat/AssistantMessage.tsx @@ -1,15 +1,22 @@ import { memo } from 'react'; import { Markdown } from './Markdown'; -import { USAGE_REGEX } from '~/utils/constants'; +import type { JSONValue } from 'ai'; interface AssistantMessageProps { content: string; + annotations?: JSONValue[]; } -export const AssistantMessage = memo(({ content }: AssistantMessageProps) => { - const match = content.match(USAGE_REGEX); - const usage = match ? JSON.parse(match[1]) : null; - const cleanContent = content.replace(USAGE_REGEX, '').trim(); +export const AssistantMessage = memo(({ content, annotations }: AssistantMessageProps) => { + const filteredAnnotations = (annotations?.filter( + (annotation: JSONValue) => annotation && typeof annotation === 'object' && Object.keys(annotation).includes('type'), + ) || []) as { type: string; value: any }[]; + + const usage: { + completionTokens: number; + promptTokens: number; + totalTokens: number; + } = filteredAnnotations.find((annotation) => annotation.type === 'usage')?.value; return (
@@ -18,7 +25,7 @@ export const AssistantMessage = memo(({ content }: AssistantMessageProps) => { Tokens: {usage.totalTokens} (prompt: {usage.promptTokens}, completion: {usage.completionTokens})
)} - {cleanContent} + {content}
); }); diff --git a/app/components/chat/Messages.client.tsx b/app/components/chat/Messages.client.tsx index 4a2ac6ac..f81ae091 100644 --- a/app/components/chat/Messages.client.tsx +++ b/app/components/chat/Messages.client.tsx @@ -65,7 +65,11 @@ export const Messages = React.forwardRef((props:
)}
- {isUserMessage ? : } + {isUserMessage ? ( + + ) : ( + + )}
{!isUserMessage && (
diff --git a/app/lib/.server/llm/switchable-stream.ts b/app/lib/.server/llm/switchable-stream.ts index 51f46ff2..638db7a4 100644 --- a/app/lib/.server/llm/switchable-stream.ts +++ b/app/lib/.server/llm/switchable-stream.ts @@ -1,5 +1,5 @@ export default class SwitchableStream extends TransformStream { - _controller: TransformStreamDefaultController | null = null; + private _controller: TransformStreamDefaultController | null = null; private _currentReader: ReadableStreamDefaultReader | null = null; private _switches = 0; diff --git a/app/routes/api.chat.ts b/app/routes/api.chat.ts index c7d63839..2c47054d 100644 --- a/app/routes/api.chat.ts +++ b/app/routes/api.chat.ts @@ -1,4 +1,5 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare'; +import { createDataStream } from 'ai'; import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS } from '~/lib/.server/llm/constants'; import { CONTINUE_PROMPT } from '~/lib/.server/llm/prompts'; import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text'; @@ -53,26 +54,30 @@ async function chatAction({ context, request }: ActionFunctionArgs) { onFinish: async ({ text: content, finishReason, usage }) => { console.log('usage', usage); - if (usage && stream._controller) { + if (usage) { cumulativeUsage.completionTokens += usage.completionTokens || 0; cumulativeUsage.promptTokens += usage.promptTokens || 0; cumulativeUsage.totalTokens += usage.totalTokens || 0; - - // Send usage info in message metadata for assistant messages - const usageMetadata = `0:"[Usage: ${JSON.stringify({ - completionTokens: cumulativeUsage.completionTokens, - promptTokens: cumulativeUsage.promptTokens, - totalTokens: cumulativeUsage.totalTokens, - })}\n]"`; - - console.log(usageMetadata); - - const encodedData = new TextEncoder().encode(usageMetadata); - stream._controller.enqueue(encodedData); } if (finishReason !== 'length') { - return stream.close(); + return stream + .switchSource( + createDataStream({ + async execute(dataStream) { + dataStream.writeMessageAnnotation({ + type: 'usage', + value: { + completionTokens: cumulativeUsage.completionTokens, + promptTokens: cumulativeUsage.promptTokens, + totalTokens: cumulativeUsage.totalTokens, + }, + }); + }, + onError: (error: any) => `Custom error: ${error.message}`, + }), + ) + .then(() => stream.close()); } if (stream.switches >= MAX_RESPONSE_SEGMENTS) { diff --git a/app/utils/constants.ts b/app/utils/constants.ts index 5531c4b0..64259954 100644 --- a/app/utils/constants.ts +++ b/app/utils/constants.ts @@ -9,7 +9,6 @@ export const WORK_DIR = `/home/${WORK_DIR_NAME}`; export const MODIFICATIONS_TAG_NAME = 'bolt_file_modifications'; export const MODEL_REGEX = /^\[Model: (.*?)\]\n\n/; export const PROVIDER_REGEX = /\[Provider: (.*?)\]\n\n/; -export const USAGE_REGEX = /\[Usage: ({.*?})\]/; // Keep this regex for assistant messages export const DEFAULT_MODEL = 'claude-3-5-sonnet-latest'; export const PROMPT_COOKIE_KEY = 'cachedPrompt'; From dd24ccc298cd09681e20ecea191b417dff41c6bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 14:23:52 +0000 Subject: [PATCH 16/27] chore: update commit hash to 77073a5e7f759ae8e5752628131d0c56df6b5c34 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index f60fd7b1..94b0df86 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "6ba93974a02a98c83badf2f0002ff4812b8f75a9" } \ No newline at end of file +{ "commit": "77073a5e7f759ae8e5752628131d0c56df6b5c34" , "version": "" } From 976676399edc1450ee6f648794e473ff5f6a7c16 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 15:10:11 +0000 Subject: [PATCH 17/27] chore: update commit hash to 78505ed2f347dd3a7778b4c1c7c38c89ecacedd3 --- app/commit.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/commit.json b/app/commit.json index 4e738f29..91446afb 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1,2 +1 @@ -{ "commit": "77073a5e7f759ae8e5752628131d0c56df6b5c34" , "version": "0.0.1" } - +{ "commit": "78505ed2f347dd3a7778b4c1c7c38c89ecacedd3" , "version": "" } From c2766cb5fc8fc2bd425e44a733012e76caadb9de Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 15:33:38 +0000 Subject: [PATCH 18/27] chore: update commit hash to f752bf7da532ec6196dafff1c388250d44db4de5 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index ed3bc2cf..5da0e32b 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "78505ed2f347dd3a7778b4c1c7c38c89ecacedd3" , "version": "" } \ No newline at end of file +{ "commit": "f752bf7da532ec6196dafff1c388250d44db4de5" , "version": "" } From 951b11005f3864bb39fa2b3239ec8f82947e675c Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 21:28:38 +0530 Subject: [PATCH 19/27] added missing icons for safari --- app/commit.json | 2 +- .../settings/features/FeaturesTab.tsx | 4 ++-- app/lib/hooks/useSettings.tsx | 1 + public/apple-touch-icon-precomposed.png | Bin 0 -> 36882 bytes public/apple-touch-icon.png | Bin 0 -> 36882 bytes 5 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 public/apple-touch-icon-precomposed.png create mode 100644 public/apple-touch-icon.png diff --git a/app/commit.json b/app/commit.json index 91446afb..5813fbb2 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "78505ed2f347dd3a7778b4c1c7c38c89ecacedd3" , "version": "" } +{ "commit": "255381441671859b8682573172f252a9ca679d74" } diff --git a/app/components/settings/features/FeaturesTab.tsx b/app/components/settings/features/FeaturesTab.tsx index c5e1b3a1..410f7ca0 100644 --- a/app/components/settings/features/FeaturesTab.tsx +++ b/app/components/settings/features/FeaturesTab.tsx @@ -3,8 +3,8 @@ import { Switch } from '~/components/ui/Switch'; import { useSettings } from '~/lib/hooks/useSettings'; export default function FeaturesTab() { - - const { debug, enableDebugMode, isLocalModel, enableLocalModels, enableEventLogs, latestBranch, enableLatestBranch } = useSettings(); + const { debug, enableDebugMode, isLocalModel, enableLocalModels, enableEventLogs, latestBranch, enableLatestBranch } = + useSettings(); const handleToggle = (enabled: boolean) => { enableDebugMode(enabled); diff --git a/app/lib/hooks/useSettings.tsx b/app/lib/hooks/useSettings.tsx index d093d5f3..36eefb42 100644 --- a/app/lib/hooks/useSettings.tsx +++ b/app/lib/hooks/useSettings.tsx @@ -99,6 +99,7 @@ export function useSettings() { if (checkCommit === undefined) { checkCommit = commit.commit; } + if (savedLatestBranch === undefined || checkCommit !== commit.commit) { // If setting hasn't been set by user, check version checkIsStableVersion().then((isStable) => { diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..ef0af6653583959d5ac75dd35e5afed90ce0f0dc GIT binary patch literal 36882 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 i+-^^G!3)%I{civV?J%aABgLlx0000-2 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef0af6653583959d5ac75dd35e5afed90ce0f0dc GIT binary patch literal 36882 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 i+-^^G!3)%I{civV?J%aABgLlx0000-2 literal 0 HcmV?d00001 From 278322d5445a2cc7bcc93042f6ca3bcf14187ec1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 15:59:54 +0000 Subject: [PATCH 20/27] chore: update commit hash to 995fb81ac7a03eb1a6d1c56cf2fc92a60028c024 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index 5da0e32b..f835d034 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "f752bf7da532ec6196dafff1c388250d44db4de5" , "version": "" } +{ "commit": "995fb81ac7a03eb1a6d1c56cf2fc92a60028c024" , "version": "" } From 15ce03598f22a7d0d642f056de0961c5580a87ce Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 16:02:04 +0000 Subject: [PATCH 21/27] chore: update commit hash to 8aee6ebf477c08d896b4419fbdeb670cc2bb8f29 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index a8490a68..90d1f203 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "995fb81ac7a03eb1a6d1c56cf2fc92a60028c024" , "version": "" } \ No newline at end of file +{ "commit": "8aee6ebf477c08d896b4419fbdeb670cc2bb8f29" , "version": "" } From 9f6ce6ab703cdbff3a72a7a9625191b62d8169aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 16:06:45 +0000 Subject: [PATCH 22/27] chore: update commit hash to 6987ceae9e1e91bec301f9e25ed9e8e03449d806 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index 90d1f203..d109cabb 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "8aee6ebf477c08d896b4419fbdeb670cc2bb8f29" , "version": "" } +{ "commit": "6987ceae9e1e91bec301f9e25ed9e8e03449d806" , "version": "" } From 647d2dc0cb167e86df2e217587e41e7925f7990b Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 21:40:57 +0530 Subject: [PATCH 23/27] commit workflow fix --- .github/workflows/commit.yaml | 2 +- app/commit.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index d6b3193f..150948ae 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -29,7 +29,7 @@ jobs: - name: Update commit file run: | - echo CURRENT_VERSION=$(node -p "require('./package.json').version") >> $GITHUB_ENV + echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json - name: Commit and push the update diff --git a/app/commit.json b/app/commit.json index d109cabb..ba3285fd 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "6987ceae9e1e91bec301f9e25ed9e8e03449d806" , "version": "" } +{ "commit": "f15dbd2a4e1a1548382442173f23db75906b1c6c" } From 412f290e81f3864ee044e1e1f4153f8057e5fd7c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 16:12:13 +0000 Subject: [PATCH 24/27] chore: update commit hash to eb1d5417e77e699e0489f09814e87fb5afed9dd5 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index ba3285fd..e6f6db03 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "f15dbd2a4e1a1548382442173f23db75906b1c6c" } +{ "commit": "eb1d5417e77e699e0489f09814e87fb5afed9dd5" , "version": "" } From 00d871bacedf018866f0ff70aea2b4497e118684 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 16:18:25 +0000 Subject: [PATCH 25/27] chore: update commit hash to de2cb43d170033c43a6cf436af02e033f66a7e4d --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index 54c81df7..d46475e3 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "bb941802094c6186e805f99a6c165431ae86d216" } +{ "commit": "de2cb43d170033c43a6cf436af02e033f66a7e4d" , "version": "" } From e601da9612e48a932139ee6bda394f534d1e6c13 Mon Sep 17 00:00:00 2001 From: Anirban Kar Date: Mon, 16 Dec 2024 22:04:33 +0530 Subject: [PATCH 26/27] updated workflow for commit and stable release --- .github/workflows/commit.yaml | 12 +++++------- .github/workflows/update-stable.yml | 5 ++++- app/commit.json | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index 150948ae..4e8545b0 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -17,19 +17,17 @@ jobs: - name: Checkout the code uses: actions/checkout@v3 - - name: Get the latest commit hash - run: echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV - - - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' - - + - name: Get the latest commit hash + run: | + echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV + echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV + - name: Update commit file run: | - echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json - name: Commit and push the update diff --git a/.github/workflows/update-stable.yml b/.github/workflows/update-stable.yml index e6fc2e58..d930fbd1 100644 --- a/.github/workflows/update-stable.yml +++ b/.github/workflows/update-stable.yml @@ -158,10 +158,13 @@ jobs: echo "$CHANGELOG_CONTENT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - - name: Commit and Tag Release + - name: Get the latest commit hash and version tag run: | echo "COMMIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV echo "CURRENT_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV + + - name: Commit and Tag Release + run: | git pull echo "{ \"commit\": \"$COMMIT_HASH\" , \"version\": \"$CURRENT_VERSION\" }" > app/commit.json git add package.json pnpm-lock.yaml changelog.md app/commit.json diff --git a/app/commit.json b/app/commit.json index d46475e3..27b04a24 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "de2cb43d170033c43a6cf436af02e033f66a7e4d" , "version": "" } +{ "commit": "47a1def87778d223b21b8468fcfd974b9498be5a" } From 92476dd2d75d640296ca61382e1cb5170a443185 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 16:55:53 +0000 Subject: [PATCH 27/27] chore: update commit hash to 49b02dd885919e24a201f07b1a7b0fd0371b4f85 --- app/commit.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/commit.json b/app/commit.json index 27b04a24..b3f011d2 100644 --- a/app/commit.json +++ b/app/commit.json @@ -1 +1 @@ -{ "commit": "47a1def87778d223b21b8468fcfd974b9498be5a" } +{ "commit": "49b02dd885919e24a201f07b1a7b0fd0371b4f85" , "version": "0.0.1" }