diff --git a/app/components/chat/GitCloneButton.tsx b/app/components/chat/GitCloneButton.tsx index 376d59d..bc98924 100644 --- a/app/components/chat/GitCloneButton.tsx +++ b/app/components/chat/GitCloneButton.tsx @@ -1,11 +1,12 @@ import ignore from 'ignore'; import { useGit } from '~/lib/hooks/useGit'; import type { Message } from 'ai'; -import { detectProjectCommands, createCommandsMessage } from '~/utils/projectCommands'; +import { detectProjectCommands, createCommandsMessage, escapeBoltTags } from '~/utils/projectCommands'; import { generateId } from '~/utils/fileUtils'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { LoadingOverlay } from '~/components/ui/LoadingOverlay'; +import type { IChatMetadata } from '~/lib/persistence'; const IGNORE_PATTERNS = [ 'node_modules/**', @@ -35,7 +36,7 @@ const ig = ignore().add(IGNORE_PATTERNS); interface GitCloneButtonProps { className?: string; - importChat?: (description: string, messages: Message[]) => Promise; + importChat?: (description: string, messages: Message[], metadata?: IChatMetadata) => Promise; } export default function GitCloneButton({ importChat }: GitCloneButtonProps) { @@ -83,7 +84,7 @@ ${fileContents .map( (file) => ` -${file.content} +${escapeBoltTags(file.content)} `, ) .join('\n')} @@ -98,7 +99,7 @@ ${file.content} messages.push(commandsMessage); } - await importChat(`Git Project:${repoUrl.split('/').slice(-1)[0]}`, messages); + await importChat(`Git Project:${repoUrl.split('/').slice(-1)[0]}`, messages, { gitUrl: repoUrl }); } } catch (error) { console.error('Error during import:', error); diff --git a/app/components/chat/Markdown.tsx b/app/components/chat/Markdown.tsx index 07b6a67..46cffd4 100644 --- a/app/components/chat/Markdown.tsx +++ b/app/components/chat/Markdown.tsx @@ -7,6 +7,7 @@ import { Artifact } from './Artifact'; import { CodeBlock } from './CodeBlock'; import styles from './Markdown.module.scss'; +import ThoughtBox from './ThoughtBox'; const logger = createScopedLogger('MarkdownComponent'); @@ -22,6 +23,8 @@ export const Markdown = memo(({ children, html = false, limitedMarkdown = false const components = useMemo(() => { return { div: ({ className, children, node, ...props }) => { + console.log(className, node); + if (className?.includes('__boltArtifact__')) { const messageId = node?.properties.dataMessageId as string; @@ -32,6 +35,10 @@ export const Markdown = memo(({ children, html = false, limitedMarkdown = false return ; } + if (className?.includes('__boltThought__')) { + return {children}; + } + return (
{children} diff --git a/app/components/chat/ThoughtBox.tsx b/app/components/chat/ThoughtBox.tsx new file mode 100644 index 0000000..3c70e1a --- /dev/null +++ b/app/components/chat/ThoughtBox.tsx @@ -0,0 +1,43 @@ +import { useState, type PropsWithChildren } from 'react'; + +const ThoughtBox = ({ title, children }: PropsWithChildren<{ title: string }>) => { + const [isExpanded, setIsExpanded] = useState(false); + + return ( +
setIsExpanded(!isExpanded)} + className={` + bg-bolt-elements-background-depth-2 + shadow-md + rounded-lg + cursor-pointer + transition-all + duration-300 + ${isExpanded ? 'max-h-96' : 'max-h-13'} + overflow-auto + border border-bolt-elements-borderColor + `} + > +
+
+
+ {title}{' '} + {!isExpanded && - Click to expand} +
+
+
+ {children} +
+
+ ); +}; + +export default ThoughtBox; diff --git a/app/components/git/GitUrlImport.client.tsx b/app/components/git/GitUrlImport.client.tsx index fe8b346..9085370 100644 --- a/app/components/git/GitUrlImport.client.tsx +++ b/app/components/git/GitUrlImport.client.tsx @@ -7,7 +7,7 @@ import { BaseChat } from '~/components/chat/BaseChat'; import { Chat } from '~/components/chat/Chat.client'; import { useGit } from '~/lib/hooks/useGit'; import { useChatHistory } from '~/lib/persistence'; -import { createCommandsMessage, detectProjectCommands } from '~/utils/projectCommands'; +import { createCommandsMessage, detectProjectCommands, escapeBoltTags } from '~/utils/projectCommands'; import { LoadingOverlay } from '~/components/ui/LoadingOverlay'; import { toast } from 'react-toastify'; @@ -74,12 +74,12 @@ export function GitUrlImport() { const filesMessage: Message = { role: 'assistant', content: `Cloning the repo ${repoUrl} into ${workdir} - + ${fileContents .map( (file) => ` -${file.content} +${escapeBoltTags(file.content)} `, ) .join('\n')} @@ -94,7 +94,7 @@ ${file.content} messages.push(commandsMessage); } - await importChat(`Git Project:${repoUrl.split('/').slice(-1)[0]}`, messages); + await importChat(`Git Project:${repoUrl.split('/').slice(-1)[0]}`, messages, { gitUrl: repoUrl }); } } catch (error) { console.error('Error during import:', error); diff --git a/app/components/workbench/Workbench.client.tsx b/app/components/workbench/Workbench.client.tsx index 0e34b59..be74b77 100644 --- a/app/components/workbench/Workbench.client.tsx +++ b/app/components/workbench/Workbench.client.tsx @@ -18,6 +18,7 @@ import { EditorPanel } from './EditorPanel'; import { Preview } from './Preview'; import useViewport from '~/lib/hooks'; import Cookies from 'js-cookie'; +import { chatMetadata, useChatHistory } from '~/lib/persistence'; interface WorkspaceProps { chatStarted?: boolean; @@ -66,6 +67,8 @@ export const Workbench = memo(({ chatStarted, isStreaming }: WorkspaceProps) => const unsavedFiles = useStore(workbenchStore.unsavedFiles); const files = useStore(workbenchStore.files); const selectedView = useStore(workbenchStore.currentView); + const metadata = useStore(chatMetadata); + const { updateChatMestaData } = useChatHistory(); const isSmallViewport = useViewport(1024); @@ -171,18 +174,28 @@ export const Workbench = memo(({ chatStarted, isStreaming }: WorkspaceProps) => { - const repoName = prompt( - 'Please enter a name for your new GitHub repository:', - 'bolt-generated-project', - ); + let repoName = metadata?.gitUrl?.split('/').slice(-1)[0]?.replace('.git', '') || null; + let repoConfirmed: boolean = true; + + if (repoName) { + repoConfirmed = confirm(`Do you want to push to the repository ${repoName}?`); + } + + if (!repoName || !repoConfirmed) { + repoName = prompt( + 'Please enter a name for your new GitHub repository:', + 'bolt-generated-project', + ); + } else { + } if (!repoName) { alert('Repository name is required. Push to GitHub cancelled.'); return; } - const githubUsername = Cookies.get('githubUsername'); - const githubToken = Cookies.get('githubToken'); + let githubUsername = Cookies.get('githubUsername'); + let githubToken = Cookies.get('githubToken'); if (!githubUsername || !githubToken) { const usernameInput = prompt('Please enter your GitHub username:'); @@ -193,9 +206,26 @@ export const Workbench = memo(({ chatStarted, isStreaming }: WorkspaceProps) => return; } - workbenchStore.pushToGitHub(repoName, usernameInput, tokenInput); - } else { - workbenchStore.pushToGitHub(repoName, githubUsername, githubToken); + githubUsername = usernameInput; + githubToken = tokenInput; + + Cookies.set('githubUsername', usernameInput); + Cookies.set('githubToken', tokenInput); + Cookies.set( + 'git:github.com', + JSON.stringify({ username: tokenInput, password: 'x-oauth-basic' }), + ); + } + + const commitMessage = + prompt('Please enter a commit message:', 'Initial commit') || 'Initial commit'; + workbenchStore.pushToGitHub(repoName, commitMessage, githubUsername, githubToken); + + if (!metadata?.gitUrl) { + updateChatMestaData({ + ...(metadata || {}), + gitUrl: `https://github.com/${githubUsername}/${repoName}.git`, + }); } }} > diff --git a/app/lib/hooks/useGit.ts b/app/lib/hooks/useGit.ts index 2efc6e8..82c650c 100644 --- a/app/lib/hooks/useGit.ts +++ b/app/lib/hooks/useGit.ts @@ -92,6 +92,7 @@ export function useGit() { }, onAuthFailure: (url, _auth) => { toast.error(`Error Authenticating with ${url.split('/')[2]}`); + throw `Error Authenticating with ${url.split('/')[2]}`; }, onAuthSuccess: (url, auth) => { saveGitAuth(url, auth); @@ -107,6 +108,8 @@ export function useGit() { return { workdir: webcontainer.workdir, data }; } catch (error) { console.error('Git clone error:', error); + + // toast.error(`Git clone error ${(error as any).message||""}`); throw error; } }, diff --git a/app/lib/modules/llm/providers/deepseek.ts b/app/lib/modules/llm/providers/deepseek.ts index d53bb26..e0e7257 100644 --- a/app/lib/modules/llm/providers/deepseek.ts +++ b/app/lib/modules/llm/providers/deepseek.ts @@ -2,7 +2,7 @@ import { BaseProvider } from '~/lib/modules/llm/base-provider'; import type { ModelInfo } from '~/lib/modules/llm/types'; import type { IProviderSetting } from '~/types/model'; import type { LanguageModelV1 } from 'ai'; -import { createOpenAI } from '@ai-sdk/openai'; +import { createDeepSeek } from '@ai-sdk/deepseek'; export default class DeepseekProvider extends BaseProvider { name = 'Deepseek'; @@ -38,11 +38,12 @@ export default class DeepseekProvider extends BaseProvider { throw new Error(`Missing API key for ${this.name} provider`); } - const openai = createOpenAI({ - baseURL: 'https://api.deepseek.com/beta', + const deepseek = createDeepSeek({ apiKey, }); - return openai(model); + return deepseek(model, { + // simulateStreaming: true, + }); } } diff --git a/app/lib/modules/llm/providers/groq.ts b/app/lib/modules/llm/providers/groq.ts index 034dab1..24d4f15 100644 --- a/app/lib/modules/llm/providers/groq.ts +++ b/app/lib/modules/llm/providers/groq.ts @@ -19,6 +19,7 @@ export default class GroqProvider extends BaseProvider { { 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 }, + { name: 'deepseek-r1-distill-llama-70b', label: 'Deepseek R1 Distill Llama 70b (Groq)', provider: 'Groq', maxTokenAllowed: 131072 }, ]; getModelInstance(options: { diff --git a/app/lib/modules/llm/providers/lmstudio.ts b/app/lib/modules/llm/providers/lmstudio.ts index ba319ac..9dabc3e 100644 --- a/app/lib/modules/llm/providers/lmstudio.ts +++ b/app/lib/modules/llm/providers/lmstudio.ts @@ -40,7 +40,7 @@ export default class LMStudioProvider extends BaseProvider { * Running in Server * Backend: Check if we're running in Docker */ - const isDocker = process.env.RUNNING_IN_DOCKER === 'true'; + const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true'; baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl; baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl; @@ -58,7 +58,7 @@ export default class LMStudioProvider extends BaseProvider { } getModelInstance: (options: { model: string; - serverEnv: Env; + serverEnv?: Env; apiKeys?: Record; providerSettings?: Record; }) => LanguageModelV1 = (options) => { @@ -75,8 +75,9 @@ export default class LMStudioProvider extends BaseProvider { throw new Error('No baseUrl found for LMStudio provider'); } + const isDocker = process.env.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true'; + if (typeof window === 'undefined') { - const isDocker = process.env.RUNNING_IN_DOCKER === 'true'; baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl; baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl; } @@ -84,7 +85,7 @@ export default class LMStudioProvider extends BaseProvider { logger.debug('LMStudio Base Url used: ', baseUrl); const lmstudio = createOpenAI({ - baseUrl: `${baseUrl}/v1`, + baseURL: `${baseUrl}/v1`, apiKey: '', }); diff --git a/app/lib/modules/llm/providers/ollama.ts b/app/lib/modules/llm/providers/ollama.ts index 11cf6a2..a3974ab 100644 --- a/app/lib/modules/llm/providers/ollama.ts +++ b/app/lib/modules/llm/providers/ollama.ts @@ -63,7 +63,7 @@ export default class OllamaProvider extends BaseProvider { * Running in Server * Backend: Check if we're running in Docker */ - const isDocker = process.env.RUNNING_IN_DOCKER === 'true'; + const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true'; baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl; baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl; @@ -83,7 +83,7 @@ export default class OllamaProvider extends BaseProvider { } getModelInstance: (options: { model: string; - serverEnv: Env; + serverEnv?: Env; apiKeys?: Record; providerSettings?: Record; }) => LanguageModelV1 = (options) => { @@ -101,7 +101,7 @@ export default class OllamaProvider extends BaseProvider { throw new Error('No baseUrl found for OLLAMA provider'); } - const isDocker = process.env.RUNNING_IN_DOCKER === 'true'; + const isDocker = process?.env?.RUNNING_IN_DOCKER === 'true' || serverEnv?.RUNNING_IN_DOCKER === 'true'; baseUrl = isDocker ? baseUrl.replace('localhost', 'host.docker.internal') : baseUrl; baseUrl = isDocker ? baseUrl.replace('127.0.0.1', 'host.docker.internal') : baseUrl; diff --git a/app/lib/persistence/db.ts b/app/lib/persistence/db.ts index 64aea1c..2f346f6 100644 --- a/app/lib/persistence/db.ts +++ b/app/lib/persistence/db.ts @@ -2,6 +2,11 @@ import type { Message } from 'ai'; import { createScopedLogger } from '~/utils/logger'; import type { ChatHistoryItem } from './useChatHistory'; +export interface IChatMetadata { + gitUrl: string; + gitBranch?: string; +} + const logger = createScopedLogger('ChatHistory'); // this is used at the top level and never rejects @@ -53,6 +58,7 @@ export async function setMessages( urlId?: string, description?: string, timestamp?: string, + metadata?: IChatMetadata, ): Promise { return new Promise((resolve, reject) => { const transaction = db.transaction('chats', 'readwrite'); @@ -69,6 +75,7 @@ export async function setMessages( urlId, description, timestamp: timestamp ?? new Date().toISOString(), + metadata, }); request.onsuccess = () => resolve(); @@ -204,6 +211,7 @@ export async function createChatFromMessages( db: IDBDatabase, description: string, messages: Message[], + metadata?: IChatMetadata, ): Promise { const newId = await getNextId(db); const newUrlId = await getUrlId(db, newId); // Get a new urlId for the duplicated chat @@ -214,6 +222,8 @@ export async function createChatFromMessages( messages, newUrlId, // Use the new urlId description, + undefined, // Use the current timestamp + metadata, ); return newUrlId; // Return the urlId instead of id for navigation @@ -230,5 +240,19 @@ export async function updateChatDescription(db: IDBDatabase, id: string, descrip throw new Error('Description cannot be empty'); } - await setMessages(db, id, chat.messages, chat.urlId, description, chat.timestamp); + await setMessages(db, id, chat.messages, chat.urlId, description, chat.timestamp, chat.metadata); +} + +export async function updateChatMetadata( + db: IDBDatabase, + id: string, + metadata: IChatMetadata | undefined, +): Promise { + const chat = await getMessages(db, id); + + if (!chat) { + throw new Error('Chat not found'); + } + + await setMessages(db, id, chat.messages, chat.urlId, chat.description, chat.timestamp, metadata); } diff --git a/app/lib/persistence/useChatHistory.ts b/app/lib/persistence/useChatHistory.ts index 0a8eeb5..7baefa5 100644 --- a/app/lib/persistence/useChatHistory.ts +++ b/app/lib/persistence/useChatHistory.ts @@ -13,6 +13,7 @@ import { setMessages, duplicateChat, createChatFromMessages, + type IChatMetadata, } from './db'; export interface ChatHistoryItem { @@ -21,6 +22,7 @@ export interface ChatHistoryItem { description?: string; messages: Message[]; timestamp: string; + metadata?: IChatMetadata; } const persistenceEnabled = !import.meta.env.VITE_DISABLE_PERSISTENCE; @@ -29,7 +31,7 @@ export const db = persistenceEnabled ? await openDatabase() : undefined; export const chatId = atom(undefined); export const description = atom(undefined); - +export const chatMetadata = atom(undefined); export function useChatHistory() { const navigate = useNavigate(); const { id: mixedId } = useLoaderData<{ id?: string }>(); @@ -65,6 +67,7 @@ export function useChatHistory() { setUrlId(storedMessages.urlId); description.set(storedMessages.description); chatId.set(storedMessages.id); + chatMetadata.set(storedMessages.metadata); } else { navigate('/', { replace: true }); } @@ -81,6 +84,21 @@ export function useChatHistory() { return { ready: !mixedId || ready, initialMessages, + updateChatMestaData: async (metadata: IChatMetadata) => { + const id = chatId.get(); + + if (!db || !id) { + return; + } + + try { + await setMessages(db, id, initialMessages, urlId, description.get(), undefined, metadata); + chatMetadata.set(metadata); + } catch (error) { + toast.error('Failed to update chat metadata'); + console.error(error); + } + }, storeMessageHistory: async (messages: Message[]) => { if (!db || messages.length === 0) { return; @@ -109,7 +127,7 @@ export function useChatHistory() { } } - await setMessages(db, chatId.get() as string, messages, urlId, description.get()); + await setMessages(db, chatId.get() as string, messages, urlId, description.get(), undefined, chatMetadata.get()); }, duplicateCurrentChat: async (listItemId: string) => { if (!db || (!mixedId && !listItemId)) { @@ -125,13 +143,13 @@ export function useChatHistory() { console.log(error); } }, - importChat: async (description: string, messages: Message[]) => { + importChat: async (description: string, messages: Message[], metadata?: IChatMetadata) => { if (!db) { return; } try { - const newId = await createChatFromMessages(db, description, messages); + const newId = await createChatFromMessages(db, description, messages, metadata); window.location.href = `/chat/${newId}`; toast.success('Chat imported successfully'); } catch (error) { diff --git a/app/lib/runtime/message-parser.ts b/app/lib/runtime/message-parser.ts index 2757179..3b41b6d 100644 --- a/app/lib/runtime/message-parser.ts +++ b/app/lib/runtime/message-parser.ts @@ -64,6 +64,10 @@ function cleanoutMarkdownSyntax(content: string) { return content; } } + +function cleanEscapedTags(content: string) { + return content.replace(/</g, '<').replace(/>/g, '>'); +} export class StreamingMessageParser { #messages = new Map(); @@ -110,6 +114,7 @@ export class StreamingMessageParser { // Remove markdown code block syntax if present and file is not markdown if (!currentAction.filePath.endsWith('.md')) { content = cleanoutMarkdownSyntax(content); + content = cleanEscapedTags(content); } content += '\n'; @@ -141,6 +146,7 @@ export class StreamingMessageParser { if (!currentAction.filePath.endsWith('.md')) { content = cleanoutMarkdownSyntax(content); + content = cleanEscapedTags(content); } this._options.callbacks?.onActionStream?.({ diff --git a/app/lib/stores/workbench.ts b/app/lib/stores/workbench.ts index 92c3508..32d5b89 100644 --- a/app/lib/stores/workbench.ts +++ b/app/lib/stores/workbench.ts @@ -434,7 +434,7 @@ export class WorkbenchStore { return syncedFiles; } - async pushToGitHub(repoName: string, githubUsername?: string, ghToken?: string) { + async pushToGitHub(repoName: string, commitMessage?: string, githubUsername?: string, ghToken?: string) { try { // Use cookies if username and token are not provided const githubToken = ghToken || Cookies.get('githubToken'); @@ -523,7 +523,7 @@ export class WorkbenchStore { const { data: newCommit } = await octokit.git.createCommit({ owner: repo.owner.login, repo: repo.name, - message: 'Initial commit from your app', + message: commitMessage || 'Initial commit from your app', tree: newTree.sha, parents: [latestCommitSha], }); diff --git a/app/routes/api.chat.ts b/app/routes/api.chat.ts index aacaacf..8564baf 100644 --- a/app/routes/api.chat.ts +++ b/app/routes/api.chat.ts @@ -63,6 +63,8 @@ async function chatAction({ context, request }: ActionFunctionArgs) { const totalMessageContent = messages.reduce((acc, message) => acc + message.content, ''); logger.debug(`Total message length: ${totalMessageContent.split(' ').length}, words`); + let lastChunk: string | undefined = undefined; + const dataStream = createDataStream({ async execute(dataStream) { const filePaths = getFilePaths(files || {}); @@ -247,15 +249,42 @@ async function chatAction({ context, request }: ActionFunctionArgs) { } } })(); - result.mergeIntoDataStream(dataStream); }, onError: (error: any) => `Custom error: ${error.message}`, }).pipeThrough( new TransformStream({ transform: (chunk, controller) => { + if (!lastChunk) { + lastChunk = ' '; + } + + if (typeof chunk === 'string') { + if (chunk.startsWith('g') && !lastChunk.startsWith('g')) { + controller.enqueue(encoder.encode(`0: "
"\n`)); + } + + if (lastChunk.startsWith('g') && !chunk.startsWith('g')) { + controller.enqueue(encoder.encode(`0: "
\\n"\n`)); + } + } + + lastChunk = chunk; + + let transformedChunk = chunk; + + if (typeof chunk === 'string' && chunk.startsWith('g')) { + let content = chunk.split(':').slice(1).join(':'); + + if (content.endsWith('\n')) { + content = content.slice(0, content.length - 1); + } + + transformedChunk = `0:${content}\n`; + } + // Convert the string stream to a byte stream - const str = typeof chunk === 'string' ? chunk : JSON.stringify(chunk); + const str = typeof transformedChunk === 'string' ? transformedChunk : JSON.stringify(transformedChunk); controller.enqueue(encoder.encode(str)); }, }), diff --git a/app/routes/api.models.ts b/app/routes/api.models.ts index 13588f9..f751222 100644 --- a/app/routes/api.models.ts +++ b/app/routes/api.models.ts @@ -41,11 +41,17 @@ function getProviderInfo(llmManager: LLMManager) { export async function loader({ request, params, + context, }: { request: Request; params: { provider?: string }; + context: { + cloudflare?: { + env: Record; + }; + }; }): Promise { - const llmManager = LLMManager.getInstance(import.meta.env); + const llmManager = LLMManager.getInstance(context.cloudflare?.env); // Get client side maintained API keys and provider settings from cookies const cookieHeader = request.headers.get('Cookie'); @@ -63,7 +69,7 @@ export async function loader({ if (provider) { const staticModels = provider.staticModels; const dynamicModels = provider.getDynamicModels - ? await provider.getDynamicModels(apiKeys, providerSettings, import.meta.env) + ? await provider.getDynamicModels(apiKeys, providerSettings, context.cloudflare?.env) : []; modelList = [...staticModels, ...dynamicModels]; } @@ -72,7 +78,7 @@ export async function loader({ modelList = await llmManager.updateModelList({ apiKeys, providerSettings, - serverEnv: import.meta.env, + serverEnv: context.cloudflare?.env, }); } diff --git a/app/utils/folderImport.ts b/app/utils/folderImport.ts index 759df10..98bbe31 100644 --- a/app/utils/folderImport.ts +++ b/app/utils/folderImport.ts @@ -1,6 +1,6 @@ import type { Message } from 'ai'; import { generateId } from './fileUtils'; -import { detectProjectCommands, createCommandsMessage } from './projectCommands'; +import { detectProjectCommands, createCommandsMessage, escapeBoltTags } from './projectCommands'; export const createChatFromFolder = async ( files: File[], @@ -42,7 +42,7 @@ export const createChatFromFolder = async ( ${fileArtifacts .map( (file) => ` -${file.content} +${escapeBoltTags(file.content)} `, ) .join('\n\n')} diff --git a/app/utils/markdown.ts b/app/utils/markdown.ts index 4409b85..262222b 100644 --- a/app/utils/markdown.ts +++ b/app/utils/markdown.ts @@ -61,7 +61,13 @@ const rehypeSanitizeOptions: RehypeSanitizeOptions = { tagNames: allowedHTMLElements, attributes: { ...defaultSchema.attributes, - div: [...(defaultSchema.attributes?.div ?? []), 'data*', ['className', '__boltArtifact__']], + div: [ + ...(defaultSchema.attributes?.div ?? []), + 'data*', + ['className', '__boltArtifact__', '__boltThought__'], + + // ['className', '__boltThought__'] + ], }, strip: [], }; diff --git a/app/utils/projectCommands.ts b/app/utils/projectCommands.ts index 050663a..e734dff 100644 --- a/app/utils/projectCommands.ts +++ b/app/utils/projectCommands.ts @@ -78,3 +78,39 @@ ${commands.setupCommand} createdAt: new Date(), }; } + +export function escapeBoltArtifactTags(input: string) { + // Regular expression to match boltArtifact tags and their content + const regex = /(]*>)([\s\S]*?)(<\/boltArtifact>)/g; + + return input.replace(regex, (match, openTag, content, closeTag) => { + // Escape the opening tag + const escapedOpenTag = openTag.replace(//g, '>'); + + // Escape the closing tag + const escapedCloseTag = closeTag.replace(//g, '>'); + + // Return the escaped version + return `${escapedOpenTag}${content}${escapedCloseTag}`; + }); +} + +export function escapeBoltAActionTags(input: string) { + // Regular expression to match boltArtifact tags and their content + const regex = /(]*>)([\s\S]*?)(<\/boltAction>)/g; + + return input.replace(regex, (match, openTag, content, closeTag) => { + // Escape the opening tag + const escapedOpenTag = openTag.replace(//g, '>'); + + // Escape the closing tag + const escapedCloseTag = closeTag.replace(//g, '>'); + + // Return the escaped version + return `${escapedOpenTag}${content}${escapedCloseTag}`; + }); +} + +export function escapeBoltTags(input: string) { + return escapeBoltArtifactTags(escapeBoltAActionTags(input)); +} diff --git a/bindings.sh b/bindings.sh index c8a86ea..f4a6732 100755 --- a/bindings.sh +++ b/bindings.sh @@ -2,15 +2,32 @@ bindings="" -while IFS= read -r line || [ -n "$line" ]; do - if [[ ! "$line" =~ ^# ]] && [[ -n "$line" ]]; then - name=$(echo "$line" | cut -d '=' -f 1) - value=$(echo "$line" | cut -d '=' -f 2-) - value=$(echo $value | sed 's/^"\(.*\)"$/\1/') - bindings+="--binding ${name}=${value} " - fi -done < .env.local +# Function to extract variable names from the TypeScript interface +extract_env_vars() { + grep -o '[A-Z_]\+:' worker-configuration.d.ts | sed 's/://' +} + +# First try to read from .env.local if it exists +if [ -f ".env.local" ]; then + while IFS= read -r line || [ -n "$line" ]; do + if [[ ! "$line" =~ ^# ]] && [[ -n "$line" ]]; then + name=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + value=$(echo $value | sed 's/^"\(.*\)"$/\1/') + bindings+="--binding ${name}=${value} " + fi + done < .env.local +else + # If .env.local doesn't exist, use environment variables defined in .d.ts + env_vars=($(extract_env_vars)) + # Generate bindings for each environment variable if it exists + for var in "${env_vars[@]}"; do + if [ -n "${!var}" ]; then + bindings+="--binding ${var}=${!var} " + fi + done +fi bindings=$(echo $bindings | sed 's/[[:space:]]*$//') -echo $bindings +echo $bindings \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 47938e0..2452557 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -72,3 +72,21 @@ services: - "5173:5173" command: pnpm run dev --host 0.0.0.0 profiles: ["development", "default"] + + app-prebuild: + image: ghcr.io/stackblitz-labs/bolt.diy:latest + ports: + - "5173:5173" + environment: + - NODE_ENV=production + - COMPOSE_PROFILES=production + # No strictly needed but serving as hints for Coolify + - PORT=5173 + - OLLAMA_API_BASE_URL=http://127.0.0.1:11434 + - DEFAULT_NUM_CTX=${DEFAULT_NUM_CTX:-32768} + - RUNNING_IN_DOCKER=true + extra_hosts: + - "host.docker.internal:host-gateway" + command: pnpm run dockerstart + profiles: + - prebuilt \ No newline at end of file diff --git a/package.json b/package.json index 1c2687e..08396bd 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ "@ai-sdk/amazon-bedrock": "1.0.6", "@ai-sdk/anthropic": "^0.0.39", "@ai-sdk/cohere": "^1.0.3", + "@ai-sdk/deepseek": "^0.1.3", "@ai-sdk/google": "^0.0.52", "@ai-sdk/mistral": "^0.0.43", - "@ai-sdk/openai": "^0.0.66", + "@ai-sdk/openai": "^1.1.2", "@codemirror/autocomplete": "^6.18.3", "@codemirror/commands": "^6.7.1", "@codemirror/lang-cpp": "^6.0.2", @@ -80,7 +81,7 @@ "@xterm/addon-fit": "^0.10.0", "@xterm/addon-web-links": "^0.11.0", "@xterm/xterm": "^5.5.0", - "ai": "^4.0.13", + "ai": "^4.1.2", "chalk": "^5.4.1", "chart.js": "^4.4.7", "class-variance-authority": "^0.7.1", @@ -147,7 +148,7 @@ "vite-tsconfig-paths": "^4.3.2", "vitest": "^2.1.7", "wrangler": "^3.91.0", - "zod": "^3.23.8" + "zod": "^3.24.1" }, "resolutions": { "@typescript-eslint/utils": "^8.0.0-alpha.30" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2f5e66..393d298 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,22 +13,25 @@ importers: dependencies: '@ai-sdk/amazon-bedrock': specifier: 1.0.6 - version: 1.0.6(zod@3.23.8) + version: 1.0.6(zod@3.24.1) '@ai-sdk/anthropic': specifier: ^0.0.39 - version: 0.0.39(zod@3.23.8) + version: 0.0.39(zod@3.24.1) '@ai-sdk/cohere': specifier: ^1.0.3 - version: 1.0.3(zod@3.23.8) + version: 1.0.3(zod@3.24.1) + '@ai-sdk/deepseek': + specifier: ^0.1.3 + version: 0.1.3(zod@3.24.1) '@ai-sdk/google': specifier: ^0.0.52 - version: 0.0.52(zod@3.23.8) + version: 0.0.52(zod@3.24.1) '@ai-sdk/mistral': specifier: ^0.0.43 - version: 0.0.43(zod@3.23.8) + version: 0.0.43(zod@3.24.1) '@ai-sdk/openai': - specifier: ^0.0.66 - version: 0.0.66(zod@3.23.8) + specifier: ^1.1.2 + version: 1.1.2(zod@3.24.1) '@codemirror/autocomplete': specifier: ^6.18.3 version: 6.18.3(@codemirror/language@6.10.6)(@codemirror/state@6.4.1)(@codemirror/view@6.35.0)(@lezer/common@1.2.3) @@ -97,13 +100,13 @@ importers: version: 13.6.2 '@openrouter/ai-sdk-provider': specifier: ^0.0.5 - version: 0.0.5(zod@3.23.8) '@phosphor-icons/react': specifier: ^2.1.7 version: 2.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-collapsible': specifier: ^1.0.3 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) + version: 0.0.5(zod@3.24.1) '@radix-ui/react-context-menu': specifier: ^2.2.2 version: 2.2.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) @@ -162,8 +165,8 @@ importers: specifier: ^5.5.0 version: 5.5.0 ai: - specifier: ^4.0.13 - version: 4.0.18(react@18.3.1)(zod@3.23.8) + specifier: ^4.1.2 + version: 4.1.2(react@18.3.1)(zod@3.24.1) chalk: specifier: ^5.4.1 version: 5.4.1 @@ -220,7 +223,7 @@ importers: version: 15.1.5(@babel/core@7.26.0)(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ollama-ai-provider: specifier: ^0.15.2 - version: 0.15.2(zod@3.23.8) + version: 0.15.2(zod@3.24.1) react: specifier: ^18.3.1 version: 18.3.1 @@ -358,8 +361,8 @@ importers: specifier: ^3.91.0 version: 3.91.0(@cloudflare/workers-types@4.20241127.0) zod: - specifier: ^3.23.8 - version: 3.23.8 + specifier: ^3.24.1 + version: 3.24.1 packages: @@ -381,6 +384,12 @@ packages: peerDependencies: zod: ^3.0.0 + '@ai-sdk/deepseek@0.1.3': + resolution: {integrity: sha512-cj0uYgFk0TWWtHKtwB8v17frttquLll9hCpRWtKpiZO69SbiZOwNSjENaoyZvN1sHMLQoQkw+hnbMGtWuU2yOg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + '@ai-sdk/google@0.0.52': resolution: {integrity: sha512-bfsA/1Ae0SQ6NfLwWKs5SU4MBwlzJjVhK6bTVBicYFjUxg9liK/W76P1Tq/qK9OlrODACz3i1STOIWsFPpIOuQ==} engines: {node: '>=18'} @@ -393,8 +402,14 @@ packages: peerDependencies: zod: ^3.0.0 - '@ai-sdk/openai@0.0.66': - resolution: {integrity: sha512-V4XeDnlNl5/AY3GB3ozJUjqnBLU5pK3DacKTbCNH3zH8/MggJoH6B8wRGdLUPVFMcsMz60mtvh4DC9JsIVFrKw==} + '@ai-sdk/openai-compatible@0.1.3': + resolution: {integrity: sha512-3dr81jVNTd7Tg4i6JwGKHX47DnQ+jn3zOuxLvu6bM2hFylchtIFn/ut3Et7VfsdMWf4gj9tXp/9rUiQ0JokkrQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + + '@ai-sdk/openai@1.1.2': + resolution: {integrity: sha512-9rfcwjl4g1/Bdr2SmgFQr+aw81r62MvIKE7QDHMC4ulFd/Hej2oClROSMpDFZHXzs7RGeb32VkRyCHUWWgN3RQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -435,8 +450,8 @@ packages: zod: optional: true - '@ai-sdk/provider-utils@2.0.4': - resolution: {integrity: sha512-GMhcQCZbwM6RoZCri0MWeEWXRt/T+uCxsmHEsTwNvEH3GDjNzchfX25C8ftry2MeEOOn6KfqCLSKomcgK6RoOg==} + '@ai-sdk/provider-utils@2.0.5': + resolution: {integrity: sha512-2M7vLhYN0ThGjNlzow7oO/lsL+DyMxvGMIYmVQvEYaCWhDzxH5dOp78VNjJIVwHzVLMbBDigX3rJuzAs853idw==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -444,8 +459,8 @@ packages: zod: optional: true - '@ai-sdk/provider-utils@2.0.5': - resolution: {integrity: sha512-2M7vLhYN0ThGjNlzow7oO/lsL+DyMxvGMIYmVQvEYaCWhDzxH5dOp78VNjJIVwHzVLMbBDigX3rJuzAs853idw==} + '@ai-sdk/provider-utils@2.1.2': + resolution: {integrity: sha512-ezpQT6kzy/2O4yyn/2YigMqynBYjZIOam3/EMNVzju+Ogj+Z+pf27c/Th78ce0A2ltgrXx6xN14sal/HHZNOOw==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -469,16 +484,16 @@ packages: resolution: {integrity: sha512-mV+3iNDkzUsZ0pR2jG0sVzU6xtQY5DtSCBy3JFycLp6PwjyLw/iodfL3MwdmMCRJWgs3dadcHejRnMvF9nGTBg==} engines: {node: '>=18'} - '@ai-sdk/provider@1.0.2': - resolution: {integrity: sha512-YYtP6xWQyaAf5LiWLJ+ycGTOeBLWrED7LUrvc+SQIWhGaneylqbaGsyQL7VouQUeQ4JZ1qKYZuhmi3W56HADPA==} - engines: {node: '>=18'} - '@ai-sdk/provider@1.0.3': resolution: {integrity: sha512-WiuJEpHTrltOIzv3x2wx4gwksAHW0h6nK3SoDzjqCOJLu/2OJ1yASESTIX+f07ChFykHElVoP80Ol/fe9dw6tQ==} engines: {node: '>=18'} - '@ai-sdk/react@1.0.6': - resolution: {integrity: sha512-8Hkserq0Ge6AEi7N4hlv2FkfglAGbkoAXEZ8YSp255c3PbnZz6+/5fppw+aROmZMOfNwallSRuy1i/iPa2rBpQ==} + '@ai-sdk/provider@1.0.6': + resolution: {integrity: sha512-hwj/gFNxpDgEfTaYzCYoslmw01IY9kWLKl/wf8xuPvHtQIzlfXWmmUwc8PnCwxyt8cKzIuV0dfUghCf68HQ0SA==} + engines: {node: '>=18'} + + '@ai-sdk/react@1.1.2': + resolution: {integrity: sha512-bBcRsDaNHzCKSIBbPngMeqbnwZ1RFadXQo9XzHoGrvLANYRwuphGNB8XTXYVLC/eXjoaGVGw2wWf/TYigEnCuA==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -489,8 +504,8 @@ packages: zod: optional: true - '@ai-sdk/ui-utils@1.0.5': - resolution: {integrity: sha512-DGJSbDf+vJyWmFNexSPUsS1AAy7gtsmFmoSyNbNbJjwl9hRIf2dknfA1V0ahx6pg3NNklNYFm53L8Nphjovfvg==} + '@ai-sdk/ui-utils@1.1.2': + resolution: {integrity: sha512-+0kfBF4Y9jmlg1KlbNKIxchmXx9PzuReSpgRNWhpU10vfl1eeer4xK/XL2qHnzAWhsMFe/SVZXJIQObk44zNEQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.0.0 @@ -3212,8 +3227,8 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@4.0.18: - resolution: {integrity: sha512-BTWzalLNE1LQphEka5xzJXDs5v4xXy1Uzr7dAVk+C/CnO3WNpuMBgrCymwUv0VrWaWc8xMQuh+OqsT7P7JyekQ==} + ai@4.1.2: + resolution: {integrity: sha512-11efhPorWFphIpeCgjW6r/jk4wB5RWUGjxayHblBXCq6YEc7o5ki7vlmSnESprsDkMEfmONBWb/xM8pWjR5O2g==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -6821,112 +6836,125 @@ packages: youch@3.3.4: resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} - zod-to-json-schema@3.23.5: - resolution: {integrity: sha512-5wlSS0bXfF/BrL4jPAbz9da5hDlDptdEppYfe+x4eIJ7jioqKG9uUxOwPzqof09u/XeVdrgFu29lZi+8XNDJtA==} + zod-to-json-schema@3.24.1: + resolution: {integrity: sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==} peerDependencies: - zod: ^3.23.3 + zod: ^3.24.1 - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zod@3.24.1: + resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: - '@ai-sdk/amazon-bedrock@1.0.6(zod@3.23.8)': + '@ai-sdk/amazon-bedrock@1.0.6(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.3 - '@ai-sdk/provider-utils': 2.0.5(zod@3.23.8) + '@ai-sdk/provider-utils': 2.0.5(zod@3.24.1) '@aws-sdk/client-bedrock-runtime': 3.716.0 - zod: 3.23.8 + zod: 3.24.1 transitivePeerDependencies: - aws-crt - '@ai-sdk/anthropic@0.0.39(zod@3.23.8)': + '@ai-sdk/anthropic@0.0.39(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.17 - '@ai-sdk/provider-utils': 1.0.9(zod@3.23.8) - zod: 3.23.8 + '@ai-sdk/provider-utils': 1.0.9(zod@3.24.1) + zod: 3.24.1 - '@ai-sdk/cohere@1.0.3(zod@3.23.8)': + '@ai-sdk/cohere@1.0.3(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.1 - '@ai-sdk/provider-utils': 2.0.2(zod@3.23.8) - zod: 3.23.8 + '@ai-sdk/provider-utils': 2.0.2(zod@3.24.1) + zod: 3.24.1 - '@ai-sdk/google@0.0.52(zod@3.23.8)': + '@ai-sdk/deepseek@0.1.3(zod@3.24.1)': + dependencies: + '@ai-sdk/openai-compatible': 0.1.3(zod@3.24.1) + '@ai-sdk/provider': 1.0.6 + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + zod: 3.24.1 + + '@ai-sdk/google@0.0.52(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.24 - '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.20(zod@3.24.1) json-schema: 0.4.0 - zod: 3.23.8 + zod: 3.24.1 - '@ai-sdk/mistral@0.0.43(zod@3.23.8)': + '@ai-sdk/mistral@0.0.43(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.24 - '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) - zod: 3.23.8 + '@ai-sdk/provider-utils': 1.0.20(zod@3.24.1) + zod: 3.24.1 - '@ai-sdk/openai@0.0.66(zod@3.23.8)': + '@ai-sdk/openai-compatible@0.1.3(zod@3.24.1)': dependencies: - '@ai-sdk/provider': 0.0.24 - '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) - zod: 3.23.8 + '@ai-sdk/provider': 1.0.6 + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + zod: 3.24.1 - '@ai-sdk/provider-utils@1.0.2(zod@3.23.8)': + '@ai-sdk/openai@1.1.2(zod@3.24.1)': + dependencies: + '@ai-sdk/provider': 1.0.6 + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + zod: 3.24.1 + + '@ai-sdk/provider-utils@1.0.2(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.12 eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 - '@ai-sdk/provider-utils@1.0.20(zod@3.23.8)': + '@ai-sdk/provider-utils@1.0.20(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.24 eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 - '@ai-sdk/provider-utils@1.0.9(zod@3.23.8)': + '@ai-sdk/provider-utils@1.0.9(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.17 eventsource-parser: 1.1.2 nanoid: 3.3.6 secure-json-parse: 2.7.0 optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 - '@ai-sdk/provider-utils@2.0.2(zod@3.23.8)': + '@ai-sdk/provider-utils@2.0.2(zod@3.24.1)': 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 + zod: 3.24.1 - '@ai-sdk/provider-utils@2.0.4(zod@3.23.8)': - dependencies: - '@ai-sdk/provider': 1.0.2 - 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.5(zod@3.23.8)': + '@ai-sdk/provider-utils@2.0.5(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.3 eventsource-parser: 3.0.0 nanoid: 3.3.8 secure-json-parse: 2.7.0 optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 + + '@ai-sdk/provider-utils@2.1.2(zod@3.24.1)': + dependencies: + '@ai-sdk/provider': 1.0.6 + eventsource-parser: 3.0.0 + nanoid: 3.3.8 + secure-json-parse: 2.7.0 + optionalDependencies: + zod: 3.24.1 '@ai-sdk/provider@0.0.12': dependencies: @@ -6944,31 +6972,31 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/provider@1.0.2': - dependencies: - json-schema: 0.4.0 - '@ai-sdk/provider@1.0.3': dependencies: json-schema: 0.4.0 - '@ai-sdk/react@1.0.6(react@18.3.1)(zod@3.23.8)': + '@ai-sdk/provider@1.0.6': dependencies: - '@ai-sdk/provider-utils': 2.0.4(zod@3.23.8) - '@ai-sdk/ui-utils': 1.0.5(zod@3.23.8) + json-schema: 0.4.0 + + '@ai-sdk/react@1.1.2(react@18.3.1)(zod@3.24.1)': + dependencies: + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + '@ai-sdk/ui-utils': 1.1.2(zod@3.24.1) swr: 2.2.5(react@18.3.1) throttleit: 2.1.0 optionalDependencies: react: 18.3.1 - zod: 3.23.8 + zod: 3.24.1 - '@ai-sdk/ui-utils@1.0.5(zod@3.23.8)': + '@ai-sdk/ui-utils@1.1.2(zod@3.24.1)': dependencies: - '@ai-sdk/provider': 1.0.2 - '@ai-sdk/provider-utils': 2.0.4(zod@3.23.8) - zod-to-json-schema: 3.23.5(zod@3.23.8) + '@ai-sdk/provider': 1.0.6 + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + zod-to-json-schema: 3.24.1(zod@3.24.1) optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 '@ampproject/remapping@2.3.0': dependencies: @@ -7664,7 +7692,7 @@ snapshots: '@cloudflare/workers-shared@0.9.0': dependencies: mime: 3.0.0 - zod: 3.23.8 + zod: 3.24.1 '@cloudflare/workers-types@4.20241127.0': {} @@ -8535,11 +8563,11 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 - '@openrouter/ai-sdk-provider@0.0.5(zod@3.23.8)': + '@openrouter/ai-sdk-provider@0.0.5(zod@3.24.1)': dependencies: '@ai-sdk/provider': 0.0.12 - '@ai-sdk/provider-utils': 1.0.2(zod@3.23.8) - zod: 3.23.8 + '@ai-sdk/provider-utils': 1.0.2(zod@3.24.1) + zod: 3.24.1 '@opentelemetry/api@1.9.0': {} @@ -10151,18 +10179,17 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@4.0.18(react@18.3.1)(zod@3.23.8): + ai@4.1.2(react@18.3.1)(zod@3.24.1): dependencies: - '@ai-sdk/provider': 1.0.2 - '@ai-sdk/provider-utils': 2.0.4(zod@3.23.8) - '@ai-sdk/react': 1.0.6(react@18.3.1)(zod@3.23.8) - '@ai-sdk/ui-utils': 1.0.5(zod@3.23.8) + '@ai-sdk/provider': 1.0.6 + '@ai-sdk/provider-utils': 2.1.2(zod@3.24.1) + '@ai-sdk/react': 1.1.2(react@18.3.1)(zod@3.24.1) + '@ai-sdk/ui-utils': 1.1.2(zod@3.24.1) '@opentelemetry/api': 1.9.0 jsondiffpatch: 0.6.0 - zod-to-json-schema: 3.23.5(zod@3.23.8) optionalDependencies: react: 18.3.1 - zod: 3.23.8 + zod: 3.24.1 ajv@6.12.6: dependencies: @@ -12535,7 +12562,7 @@ snapshots: workerd: 1.20241106.1 ws: 8.18.0 youch: 3.3.4 - zod: 3.23.8 + zod: 3.24.1 transitivePeerDependencies: - bufferutil - supports-color @@ -12753,13 +12780,13 @@ snapshots: ohash@1.1.4: {} - ollama-ai-provider@0.15.2(zod@3.23.8): + ollama-ai-provider@0.15.2(zod@3.24.1): dependencies: '@ai-sdk/provider': 0.0.24 - '@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) + '@ai-sdk/provider-utils': 1.0.20(zod@3.24.1) partial-json: 0.1.7 optionalDependencies: - zod: 3.23.8 + zod: 3.24.1 on-finished@2.4.1: dependencies: @@ -13371,7 +13398,6 @@ snapshots: '@remix-run/server-runtime': 2.15.2(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.2(@cloudflare/workers-types@4.20241127.0)(typescript@5.7.2))(@remix-run/node@2.15.2(typescript@5.7.2))(@remix-run/react@2.15.2(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: type-fest: 4.30.0 @@ -13381,7 +13407,7 @@ snapshots: '@remix-run/react': 2.15.2(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 + zod: 3.24.1 require-like@0.1.2: {} @@ -14473,10 +14499,10 @@ snapshots: mustache: 4.2.0 stacktracey: 2.1.8 - zod-to-json-schema@3.23.5(zod@3.23.8): + zod-to-json-schema@3.24.1(zod@3.24.1): dependencies: - zod: 3.23.8 + zod: 3.24.1 - zod@3.23.8: {} + zod@3.24.1: {} zwitch@2.0.4: {} diff --git a/worker-configuration.d.ts b/worker-configuration.d.ts index 099fba9..b2ae1ce 100644 --- a/worker-configuration.d.ts +++ b/worker-configuration.d.ts @@ -1,5 +1,6 @@ interface Env { - DEFAULT_NUM_CTX:Settings; + RUNNING_IN_DOCKER: Settings; + DEFAULT_NUM_CTX: Settings; ANTHROPIC_API_KEY: string; OPENAI_API_KEY: string; GROQ_API_KEY: string;