mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
base commit
more fixes fix background fix chat history Update ci.yaml remove hardcoded api key
This commit is contained in:
parent
afd60de0ef
commit
1c15d13156
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@ -22,6 +22,3 @@ jobs:
|
|||||||
|
|
||||||
# - name: Run ESLint
|
# - name: Run ESLint
|
||||||
# run: pnpm run lint
|
# run: pnpm run lint
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
run: pnpm run test
|
|
||||||
|
@ -12,7 +12,7 @@ import { classNames } from '~/utils/classNames';
|
|||||||
import { PROVIDER_LIST } from '~/utils/constants';
|
import { PROVIDER_LIST } from '~/utils/constants';
|
||||||
import { Messages } from './Messages.client';
|
import { Messages } from './Messages.client';
|
||||||
import { SendButton } from './SendButton.client';
|
import { SendButton } from './SendButton.client';
|
||||||
import { APIKeyManager, getApiKeysFromCookies } from './APIKeyManager';
|
import { getApiKeysFromCookies } from './APIKeyManager';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import * as Tooltip from '@radix-ui/react-tooltip';
|
import * as Tooltip from '@radix-ui/react-tooltip';
|
||||||
|
|
||||||
@ -35,8 +35,6 @@ import type { ModelInfo } from '~/lib/modules/llm/types';
|
|||||||
import ProgressCompilation from './ProgressCompilation';
|
import ProgressCompilation from './ProgressCompilation';
|
||||||
import type { ProgressAnnotation } from '~/types/context';
|
import type { ProgressAnnotation } from '~/types/context';
|
||||||
import type { ActionRunner } from '~/lib/runtime/action-runner';
|
import type { ActionRunner } from '~/lib/runtime/action-runner';
|
||||||
import { LOCAL_PROVIDERS } from '~/lib/stores/settings';
|
|
||||||
import { useLoaderData } from '@remix-run/react';
|
|
||||||
|
|
||||||
const TEXTAREA_MIN_HEIGHT = 76;
|
const TEXTAREA_MIN_HEIGHT = 76;
|
||||||
|
|
||||||
@ -121,8 +119,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
const [isModelLoading, setIsModelLoading] = useState<string | undefined>('all');
|
const [isModelLoading, setIsModelLoading] = useState<string | undefined>('all');
|
||||||
const [progressAnnotations, setProgressAnnotations] = useState<ProgressAnnotation[]>([]);
|
const [progressAnnotations, setProgressAnnotations] = useState<ProgressAnnotation[]>([]);
|
||||||
|
|
||||||
const { hideBaseChat, canImportChat } = useLoaderData<{ hideBaseChat?: boolean; canImportChat?: boolean }>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
const progressList = data.filter(
|
const progressList = data.filter(
|
||||||
@ -199,30 +195,32 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
}
|
}
|
||||||
}, [providerList, provider]);
|
}, [providerList, provider]);
|
||||||
|
|
||||||
const onApiKeysChange = async (providerName: string, apiKey: string) => {
|
/*
|
||||||
const newApiKeys = { ...apiKeys, [providerName]: apiKey };
|
* const onApiKeysChange = async (providerName: string, apiKey: string) => {
|
||||||
setApiKeys(newApiKeys);
|
* const newApiKeys = { ...apiKeys, [providerName]: apiKey };
|
||||||
Cookies.set('apiKeys', JSON.stringify(newApiKeys));
|
* setApiKeys(newApiKeys);
|
||||||
|
* Cookies.set('apiKeys', JSON.stringify(newApiKeys));
|
||||||
setIsModelLoading(providerName);
|
*
|
||||||
|
* setIsModelLoading(providerName);
|
||||||
let providerModels: ModelInfo[] = [];
|
*
|
||||||
|
* let providerModels: ModelInfo[] = [];
|
||||||
try {
|
*
|
||||||
const response = await fetch(`/code-editor/api/models/${encodeURIComponent(providerName)}`);
|
* try {
|
||||||
const data = await response.json();
|
* const response = await fetch(`/code-editor/api/models/${encodeURIComponent(providerName)}`);
|
||||||
providerModels = (data as { modelList: ModelInfo[] }).modelList;
|
* const data = await response.json();
|
||||||
} catch (error) {
|
* providerModels = (data as { modelList: ModelInfo[] }).modelList;
|
||||||
console.error('Error loading dynamic models for:', providerName, error);
|
* } catch (error) {
|
||||||
}
|
* console.error('Error loading dynamic models for:', providerName, error);
|
||||||
|
* }
|
||||||
// Only update models for the specific provider
|
*
|
||||||
setModelList((prevModels) => {
|
* // Only update models for the specific provider
|
||||||
const otherModels = prevModels.filter((model) => model.provider !== providerName);
|
* setModelList((prevModels) => {
|
||||||
return [...otherModels, ...providerModels];
|
* const otherModels = prevModels.filter((model) => model.provider !== providerName);
|
||||||
});
|
* return [...otherModels, ...providerModels];
|
||||||
setIsModelLoading(undefined);
|
* });
|
||||||
};
|
* setIsModelLoading(undefined);
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
|
||||||
const startListening = () => {
|
const startListening = () => {
|
||||||
if (recognition) {
|
if (recognition) {
|
||||||
@ -417,6 +415,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
apiKeys={apiKeys}
|
apiKeys={apiKeys}
|
||||||
modelLoading={isModelLoading}
|
modelLoading={isModelLoading}
|
||||||
/>
|
/>
|
||||||
|
{/*
|
||||||
{(providerList || []).length > 0 &&
|
{(providerList || []).length > 0 &&
|
||||||
provider &&
|
provider &&
|
||||||
(!LOCAL_PROVIDERS.includes(provider.name) || 'OpenAILike') && (
|
(!LOCAL_PROVIDERS.includes(provider.name) || 'OpenAILike') && (
|
||||||
@ -427,7 +426,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
onApiKeysChange(provider.name, key);
|
onApiKeysChange(provider.name, key);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
@ -522,7 +521,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
minHeight: TEXTAREA_MIN_HEIGHT,
|
minHeight: TEXTAREA_MIN_HEIGHT,
|
||||||
maxHeight: TEXTAREA_MAX_HEIGHT,
|
maxHeight: TEXTAREA_MAX_HEIGHT,
|
||||||
}}
|
}}
|
||||||
placeholder="How can Bolt help you today?"
|
placeholder="How can RapidCanvas help you today?"
|
||||||
translate="no"
|
translate="no"
|
||||||
/>
|
/>
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
@ -632,20 +631,6 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return <Tooltip.Provider delayDuration={200}>{baseChat}</Tooltip.Provider>;
|
||||||
<Tooltip.Provider delayDuration={200}>
|
|
||||||
{!hideBaseChat ? (
|
|
||||||
baseChat
|
|
||||||
) : (
|
|
||||||
<div ref={ref} className={classNames(styles.BaseChat, 'relative flex h-full w-full overflow-hidden')}>
|
|
||||||
<ClientOnly>{() => <Menu />}</ClientOnly>
|
|
||||||
<div className="flex justify-center gap-2 items-start mt-10% w-full">
|
|
||||||
{ImportButtons(importChat, canImportChat)}
|
|
||||||
<GitCloneButton importChat={importChat} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Tooltip.Provider>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -12,7 +12,7 @@ import { useMessageParser, usePromptEnhancer, useShortcuts, useSnapScroll } from
|
|||||||
import { description, useChatHistory } from '~/lib/persistence';
|
import { description, useChatHistory } from '~/lib/persistence';
|
||||||
import { chatStore } from '~/lib/stores/chat';
|
import { chatStore } from '~/lib/stores/chat';
|
||||||
import { workbenchStore } from '~/lib/stores/workbench';
|
import { workbenchStore } from '~/lib/stores/workbench';
|
||||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER, PROMPT_COOKIE_KEY, PROVIDER_LIST } from '~/utils/constants';
|
import { PROMPT_COOKIE_KEY, PROVIDER_LIST } from '~/utils/constants';
|
||||||
import { cubicEasingFn } from '~/utils/easings';
|
import { cubicEasingFn } from '~/utils/easings';
|
||||||
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
import { createScopedLogger, renderLogger } from '~/utils/logger';
|
||||||
import { BaseChat } from './BaseChat';
|
import { BaseChat } from './BaseChat';
|
||||||
@ -45,7 +45,9 @@ export function Chat() {
|
|||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [error, setError] = useState<Error | null>(null);
|
const [error, setError] = useState<Error | null>(null);
|
||||||
|
|
||||||
const { ready, initialMessages, resetMessages, storeMessageHistory, importChat, exportChat } = useChatHistory();
|
const { ready, initialMessages, storeMessageHistory, importChat, exportChat } = useChatHistory();
|
||||||
|
|
||||||
|
console.log('initialMessages', initialMessages);
|
||||||
|
|
||||||
const title = useStore(description);
|
const title = useStore(description);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -55,12 +57,6 @@ export function Chat() {
|
|||||||
const { id: mixedId } = useLoaderData<{ id?: string }>();
|
const { id: mixedId } = useLoaderData<{ id?: string }>();
|
||||||
const token = getToken();
|
const token = getToken();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (initialMessages.length > 0) {
|
|
||||||
resetMessages();
|
|
||||||
}
|
|
||||||
}, [initialMessages]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!mixedId) {
|
if (!mixedId) {
|
||||||
setError(new Error('No dataApp ID'));
|
setError(new Error('No dataApp ID'));
|
||||||
@ -73,7 +69,7 @@ export function Chat() {
|
|||||||
|
|
||||||
loadFilesFromDataApp(mixedId, token!)
|
loadFilesFromDataApp(mixedId, token!)
|
||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
await importChat(data.folderName, data.messages);
|
await importChat(data.folderName, !!initialMessages.length ? initialMessages : data.messages);
|
||||||
saveFilesToWorkbench({ fileArtifacts: data.updatedArtifacts.files });
|
saveFilesToWorkbench({ fileArtifacts: data.updatedArtifacts.files });
|
||||||
removeTokenFromUrl();
|
removeTokenFromUrl();
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@ -164,8 +160,6 @@ export const ChatImpl = memo(
|
|||||||
({ description, initialMessages, storeMessageHistory, importChat, exportChat }: ChatProps) => {
|
({ description, initialMessages, storeMessageHistory, importChat, exportChat }: ChatProps) => {
|
||||||
useShortcuts();
|
useShortcuts();
|
||||||
|
|
||||||
const { showChat } = useLoaderData<{ showChat: boolean }>();
|
|
||||||
|
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
const [chatStarted, setChatStarted] = useState(initialMessages.length > 0);
|
const [chatStarted, setChatStarted] = useState(initialMessages.length > 0);
|
||||||
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
|
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
|
||||||
@ -178,11 +172,10 @@ export const ChatImpl = memo(
|
|||||||
|
|
||||||
const [model, setModel] = useState(() => {
|
const [model, setModel] = useState(() => {
|
||||||
const savedModel = Cookies.get('selectedModel');
|
const savedModel = Cookies.get('selectedModel');
|
||||||
return savedModel || DEFAULT_MODEL;
|
return savedModel || 'gpt-4o-mini';
|
||||||
});
|
});
|
||||||
const [provider, setProvider] = useState(() => {
|
const [provider, setProvider] = useState(() => {
|
||||||
const savedProvider = Cookies.get('selectedProvider');
|
return PROVIDER_LIST.find((p) => p.name === 'OpenAI') as ProviderInfo;
|
||||||
return (PROVIDER_LIST.find((p) => p.name === savedProvider) || DEFAULT_PROVIDER) as ProviderInfo;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const [animationScope, animate] = useAnimate();
|
const [animationScope, animate] = useAnimate();
|
||||||
@ -541,7 +534,7 @@ export const ChatImpl = memo(
|
|||||||
ref={animationScope}
|
ref={animationScope}
|
||||||
textareaRef={textareaRef}
|
textareaRef={textareaRef}
|
||||||
input={input}
|
input={input}
|
||||||
showChat={showChat}
|
showChat={true}
|
||||||
chatStarted={chatStarted}
|
chatStarted={chatStarted}
|
||||||
isStreaming={isLoading || fakeLoading}
|
isStreaming={isLoading || fakeLoading}
|
||||||
onStreamingChange={(streaming) => {
|
onStreamingChange={(streaming) => {
|
||||||
|
@ -14,8 +14,8 @@ export default function ChatAlert({ alert, clearAlert, postMessage }: Props) {
|
|||||||
const isPreview = source === 'preview';
|
const isPreview = source === 'preview';
|
||||||
const title = isPreview ? 'Preview Error' : 'Terminal Error';
|
const title = isPreview ? 'Preview Error' : 'Terminal Error';
|
||||||
const message = isPreview
|
const message = isPreview
|
||||||
? 'We encountered an error while running the preview. Would you like Bolt to analyze and help resolve this issue?'
|
? 'We encountered an error while running the preview. Would you like RapidCanvas to analyze and help resolve this issue?'
|
||||||
: 'We encountered an error while running terminal commands. Would you like Bolt to analyze and help resolve this issue?';
|
: 'We encountered an error while running terminal commands. Would you like RapidCanvas to analyze and help resolve this issue?';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
@ -84,7 +84,7 @@ export default function ChatAlert({ alert, clearAlert, postMessage }: Props) {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="i-ph:chat-circle-duotone"></div>
|
<div className="i-ph:chat-circle-duotone"></div>
|
||||||
Ask Bolt
|
Ask RapidCanvas
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={clearAlert}
|
onClick={clearAlert}
|
||||||
|
@ -168,6 +168,7 @@ export const ModelSelector = ({
|
|||||||
<div className="mb-2 flex gap-2 flex-col sm:flex-row">
|
<div className="mb-2 flex gap-2 flex-col sm:flex-row">
|
||||||
<select
|
<select
|
||||||
value={provider?.name ?? ''}
|
value={provider?.name ?? ''}
|
||||||
|
disabled
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const newProvider = providerList.find((p: ProviderInfo) => p.name === e.target.value);
|
const newProvider = providerList.find((p: ProviderInfo) => p.name === e.target.value);
|
||||||
|
|
||||||
@ -256,7 +257,7 @@ export const ModelSelector = ({
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'max-h-60 overflow-y-auto',
|
'max-h-[60px] overflow-y-auto',
|
||||||
'sm:scrollbar-none',
|
'sm:scrollbar-none',
|
||||||
'[&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar]:h-2',
|
'[&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar]:h-2',
|
||||||
'[&::-webkit-scrollbar-thumb]:bg-bolt-elements-borderColor',
|
'[&::-webkit-scrollbar-thumb]:bg-bolt-elements-borderColor',
|
||||||
|
@ -7,7 +7,6 @@ import { workbenchStore } from '~/lib/stores/workbench';
|
|||||||
import { logStore } from '~/lib/stores/logs'; // Import logStore
|
import { logStore } from '~/lib/stores/logs'; // Import logStore
|
||||||
import {
|
import {
|
||||||
getMessages,
|
getMessages,
|
||||||
getNextId,
|
|
||||||
getUrlId,
|
getUrlId,
|
||||||
openDatabase,
|
openDatabase,
|
||||||
setMessages,
|
setMessages,
|
||||||
@ -84,7 +83,7 @@ export function useChatHistory() {
|
|||||||
startingIdx = -1;
|
startingIdx = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let filteredMessages = storedMessages.messages.slice(startingIdx + 1, endingIdx);
|
let filteredMessages = storedMessages.messages;
|
||||||
let archivedMessages: Message[] = [];
|
let archivedMessages: Message[] = [];
|
||||||
|
|
||||||
if (startingIdx >= 0) {
|
if (startingIdx >= 0) {
|
||||||
@ -186,7 +185,7 @@ ${value.content}
|
|||||||
|
|
||||||
setInitialMessages(filteredMessages);
|
setInitialMessages(filteredMessages);
|
||||||
|
|
||||||
setUrlId(storedMessages.urlId);
|
setUrlId(mixedId!);
|
||||||
description.set(storedMessages.description);
|
description.set(storedMessages.description);
|
||||||
chatId.set(storedMessages.id);
|
chatId.set(storedMessages.id);
|
||||||
chatMetadata.set(storedMessages.metadata);
|
chatMetadata.set(storedMessages.metadata);
|
||||||
@ -319,16 +318,6 @@ ${value.content}
|
|||||||
description.set(firstArtifact?.title);
|
description.set(firstArtifact?.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialMessages.length === 0 && !chatId.get()) {
|
|
||||||
const nextId = await getNextId(db);
|
|
||||||
|
|
||||||
chatId.set(nextId);
|
|
||||||
|
|
||||||
if (!urlId) {
|
|
||||||
navigateChat(nextId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await setMessages(
|
await setMessages(
|
||||||
db,
|
db,
|
||||||
chatId.get() as string,
|
chatId.get() as string,
|
||||||
@ -362,8 +351,10 @@ ${value.content}
|
|||||||
const currentId = mixedId || chatId.get();
|
const currentId = mixedId || chatId.get();
|
||||||
|
|
||||||
if (currentId) {
|
if (currentId) {
|
||||||
await setMessages(db, currentId, messages, urlId, description, undefined, metadata);
|
const chat = await getMessages(db, currentId);
|
||||||
setInitialMessages(messages);
|
const chatMessages = chat.messages.length > 0 ? chat.messages : messages;
|
||||||
|
await setMessages(db, currentId, chatMessages, urlId, description, undefined, metadata);
|
||||||
|
setInitialMessages(chatMessages);
|
||||||
setArchivedMessages([]);
|
setArchivedMessages([]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -19,24 +19,6 @@ export const action = withAuth(async (args: ActionFunctionArgs) => {
|
|||||||
|
|
||||||
const logger = createScopedLogger('api.chat');
|
const logger = createScopedLogger('api.chat');
|
||||||
|
|
||||||
function parseCookies(cookieHeader: string): Record<string, string> {
|
|
||||||
const cookies: Record<string, string> = {};
|
|
||||||
|
|
||||||
const items = cookieHeader.split(';').map((cookie) => cookie.trim());
|
|
||||||
|
|
||||||
items.forEach((item) => {
|
|
||||||
const [name, ...rest] = item.split('=');
|
|
||||||
|
|
||||||
if (name && rest) {
|
|
||||||
const decodedName = decodeURIComponent(name.trim());
|
|
||||||
const decodedValue = decodeURIComponent(rest.join('=').trim());
|
|
||||||
cookies[decodedName] = decodedValue;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return cookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function chatAction({ context, request }: ActionFunctionArgs) {
|
async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||||
const { messages, files, promptId, contextOptimization } = await request.json<{
|
const { messages, files, promptId, contextOptimization } = await request.json<{
|
||||||
messages: Messages;
|
messages: Messages;
|
||||||
@ -45,11 +27,15 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
contextOptimization: boolean;
|
contextOptimization: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const cookieHeader = request.headers.get('Cookie');
|
const apiKeys = {
|
||||||
const apiKeys = JSON.parse(parseCookies(cookieHeader || '').apiKeys || '{}');
|
OpenAI: context.cloudflare?.env?.OPENAI_API_KEY || process.env.OPENAI_API_KEY || '',
|
||||||
const providerSettings: Record<string, IProviderSetting> = JSON.parse(
|
};
|
||||||
parseCookies(cookieHeader || '').providers || '{}',
|
|
||||||
);
|
if (!apiKeys.OpenAI) {
|
||||||
|
throw new Error('OpenAI API key is not configured. Please set OPENAI_API_KEY in your environment variables.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerSettings: Record<string, IProviderSetting> = { OpenAI: { enabled: true } };
|
||||||
|
|
||||||
const stream = new SwitchableStream();
|
const stream = new SwitchableStream();
|
||||||
|
|
||||||
@ -224,6 +210,8 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
|
|
||||||
const lastUserMessage = messages.filter((x) => x.role == 'user').slice(-1)[0];
|
const lastUserMessage = messages.filter((x) => x.role == 'user').slice(-1)[0];
|
||||||
const { model, provider } = extractPropertiesFromMessage(lastUserMessage);
|
const { model, provider } = extractPropertiesFromMessage(lastUserMessage);
|
||||||
|
console.log('model', model);
|
||||||
|
console.log('provider', provider);
|
||||||
messages.push({ id: generateId(), role: 'assistant', content });
|
messages.push({ id: generateId(), role: 'assistant', content });
|
||||||
messages.push({
|
messages.push({
|
||||||
id: generateId(),
|
id: generateId(),
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
--bolt-elements-actions-background: theme('colors.white');
|
--bolt-elements-actions-background: theme('colors.white');
|
||||||
--bolt-elements-actions-code-background: theme('colors.gray.800');
|
--bolt-elements-actions-code-background: theme('colors.gray.800');
|
||||||
|
|
||||||
--bolt-elements-messages-background: theme('colors.gray.100');
|
--bolt-elements-messages-background: theme('colors.white');
|
||||||
--bolt-elements-messages-linkColor: theme('colors.accent.500');
|
--bolt-elements-messages-linkColor: theme('colors.accent.500');
|
||||||
--bolt-elements-messages-code-background: theme('colors.gray.800');
|
--bolt-elements-messages-code-background: theme('colors.gray.800');
|
||||||
--bolt-elements-messages-inlineCode-background: theme('colors.gray.200');
|
--bolt-elements-messages-inlineCode-background: theme('colors.gray.200');
|
||||||
|
Loading…
Reference in New Issue
Block a user