mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-05-03 03:42:52 +00:00
changing based on PR review
This commit is contained in:
parent
4b236e934e
commit
fe3ea8005e
@ -35,7 +35,7 @@ const ModelSelector = ({ model, setModel, provider, setProvider, modelList, prov
|
||||
<select
|
||||
value={provider?.name}
|
||||
onChange={(e) => {
|
||||
setProvider(providerList.find(p => p.name === e.target.value));
|
||||
setProvider(providerList.find((p) => p.name === e.target.value));
|
||||
const firstModel = [...modelList].find((m) => m.provider == e.target.value);
|
||||
setModel(firstModel ? firstModel.name : '');
|
||||
}}
|
||||
@ -51,7 +51,7 @@ const ModelSelector = ({ model, setModel, provider, setProvider, modelList, prov
|
||||
key={provider?.name}
|
||||
value={model}
|
||||
onChange={(e) => setModel(e.target.value)}
|
||||
style={{ maxWidth: "70%" }}
|
||||
style={{ maxWidth: '70%' }}
|
||||
className="flex-1 p-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary focus:outline-none focus:ring-2 focus:ring-bolt-elements-focus transition-all"
|
||||
>
|
||||
{[...modelList]
|
||||
@ -93,32 +93,34 @@ interface BaseChatProps {
|
||||
setImageDataList?: (dataList: string[]) => void;
|
||||
}
|
||||
export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
({
|
||||
textareaRef,
|
||||
messageRef,
|
||||
scrollRef,
|
||||
showChat,
|
||||
chatStarted = false,
|
||||
isStreaming = false,
|
||||
model,
|
||||
setModel,
|
||||
provider,
|
||||
setProvider,
|
||||
input = '',
|
||||
enhancingPrompt,
|
||||
handleInputChange,
|
||||
promptEnhanced,
|
||||
enhancePrompt,
|
||||
sendMessage,
|
||||
handleStop,
|
||||
uploadedFiles,
|
||||
setUploadedFiles,
|
||||
imageDataList,
|
||||
setImageDataList,
|
||||
messages,
|
||||
children, // Add this
|
||||
}, ref) => {
|
||||
console.log(provider);
|
||||
(
|
||||
{
|
||||
textareaRef,
|
||||
messageRef,
|
||||
scrollRef,
|
||||
showChat = true,
|
||||
chatStarted = false,
|
||||
isStreaming = false,
|
||||
model,
|
||||
setModel,
|
||||
provider,
|
||||
setProvider,
|
||||
input = '',
|
||||
enhancingPrompt,
|
||||
handleInputChange,
|
||||
promptEnhanced,
|
||||
enhancePrompt,
|
||||
sendMessage,
|
||||
handleStop,
|
||||
uploadedFiles,
|
||||
setUploadedFiles,
|
||||
imageDataList,
|
||||
setImageDataList,
|
||||
messages,
|
||||
children, // Add this
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
|
||||
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
||||
const [modelList, setModelList] = useState(MODEL_LIST);
|
||||
@ -139,7 +141,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
Cookies.remove('apiKeys');
|
||||
}
|
||||
|
||||
initializeModelList().then(modelList => {
|
||||
initializeModelList().then((modelList) => {
|
||||
setModelList(modelList);
|
||||
});
|
||||
}, []);
|
||||
@ -239,12 +241,13 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
setProvider={setProvider}
|
||||
providerList={PROVIDER_LIST}
|
||||
/>
|
||||
{provider &&
|
||||
{provider && (
|
||||
<APIKeyManager
|
||||
provider={provider}
|
||||
apiKey={apiKeys[provider.name] || ''}
|
||||
setApiKey={(key) => updateApiKey(provider.name, key)}
|
||||
/>}
|
||||
/>
|
||||
)}
|
||||
|
||||
<FilePreview
|
||||
files={uploadedFiles}
|
||||
@ -309,7 +312,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
className="transition-all"
|
||||
onClick={() => handleFileUpload()}
|
||||
>
|
||||
<div className="i-ph:upload text-xl"></div>
|
||||
<div className="i-ph:paperclip text-xl"></div>
|
||||
</IconButton>
|
||||
|
||||
<IconButton
|
||||
@ -374,6 +377,3 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
@ -1,23 +1,22 @@
|
||||
// FilePreview.tsx
|
||||
// Remove the lucide-react import
|
||||
import React from 'react';
|
||||
import { X } from 'lucide-react';
|
||||
|
||||
// Rest of the interface remains the same
|
||||
interface FilePreviewProps {
|
||||
files: File[];
|
||||
imageDataList: string[]; // or imagePreviews: string[]
|
||||
imageDataList: string[];
|
||||
onRemove: (index: number) => void;
|
||||
}
|
||||
|
||||
const FilePreview: React.FC<FilePreviewProps> = ({ files, imageDataList, onRemove }) => {
|
||||
if (!files || files.length === 0) {
|
||||
return null; // Or render a placeholder if desired
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-row overflow-x-auto"> {/* Add horizontal scrolling if needed */}
|
||||
<div className="flex flex-row overflow-x-auto">
|
||||
{files.map((file, index) => (
|
||||
<div key={file.name + file.size} className="mr-2 relative">
|
||||
{/* Display image preview or file icon */}
|
||||
{imageDataList[index] && (
|
||||
<div className="relative">
|
||||
<img src={imageDataList[index]} alt={file.name} className="max-h-20" />
|
||||
@ -26,7 +25,7 @@ const FilePreview: React.FC<FilePreviewProps> = ({ files, imageDataList, onRemov
|
||||
className="absolute -top-2 -right-2 z-10 bg-white rounded-full p-1 shadow-md hover:bg-gray-100"
|
||||
>
|
||||
<div className="bg-black rounded-full p-1">
|
||||
<X className="w-3 h-3 text-gray-400" strokeWidth={2.5} />
|
||||
<div className="i-ph:x w-3 h-3 text-gray-400" />
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -21,9 +21,6 @@ export function UserMessage({ content }: UserMessageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// function sanitizeUserMessage(content: string) {
|
||||
// return content.replace(modificationsRegex, '').replace(MODEL_REGEX, 'Using: $1').replace(PROVIDER_REGEX, ' ($1)\n\n').trim();
|
||||
// }
|
||||
function sanitizeUserMessage(content: string | Array<{type: string, text?: string, image_url?: {url: string}}>) {
|
||||
if (Array.isArray(content)) {
|
||||
return content.map(item => {
|
||||
|
@ -45,12 +45,12 @@ function extractPropertiesFromMessage(message: Message): { model: string; provid
|
||||
if (item.type === 'text') {
|
||||
return {
|
||||
type: 'text',
|
||||
text: item.text?.replace(/\[Model:.*?\]\n\n/, '').replace(/\[Provider:.*?\]\n\n/, '')
|
||||
text: item.text?.replace(MODEL_REGEX, '').replace(PROVIDER_REGEX, '')
|
||||
};
|
||||
}
|
||||
return item; // Preserve image_url and other types as is
|
||||
})
|
||||
: textContent.replace(/\[Model:.*?\]\n\n/, '').replace(/\[Provider:.*?\]\n\n/, '');
|
||||
: textContent.replace(MODEL_REGEX, '').replace(PROVIDER_REGEX, '');
|
||||
|
||||
return { model, provider, content: cleanedContent };
|
||||
}
|
||||
@ -80,16 +80,6 @@ export function streamText(
|
||||
return message; // No changes for non-user messages
|
||||
});
|
||||
|
||||
// const modelConfig = getModel(currentProvider, currentModel, env, apiKeys);
|
||||
// const coreMessages = convertToCoreMessages(processedMessages);
|
||||
|
||||
// console.log('Debug streamText:', JSON.stringify({
|
||||
// model: modelConfig,
|
||||
// messages: processedMessages,
|
||||
// coreMessages: coreMessages,
|
||||
// system: getSystemPrompt()
|
||||
// }, null, 2));
|
||||
|
||||
return _streamText({
|
||||
model: getModel(currentProvider, currentModel, env, apiKeys),
|
||||
system: getSystemPrompt(),
|
||||
|
@ -30,15 +30,15 @@ function parseCookies(cookieHeader) {
|
||||
}
|
||||
|
||||
async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||
// console.log('=== API CHAT LOGGING START ===');
|
||||
// console.log('Request received:', request.url);
|
||||
|
||||
|
||||
const { messages, imageData } = await request.json<{
|
||||
messages: Messages,
|
||||
imageData?: string[]
|
||||
}>();
|
||||
|
||||
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();
|
||||
@ -71,13 +71,6 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||
|
||||
const result = await streamText(messages, context.cloudflare.env, options, apiKeys);
|
||||
|
||||
// console.log('=== API CHAT LOGGING START ===');
|
||||
// console.log('StreamText:', JSON.stringify({
|
||||
// messages,
|
||||
// result,
|
||||
// }, null, 2));
|
||||
// console.log('=== API CHAT LOGGING END ===');
|
||||
|
||||
stream.switchSource(result.toAIStream());
|
||||
|
||||
return new Response(stream.readable, {
|
||||
|
@ -74,7 +74,6 @@
|
||||
"jose": "^5.6.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.460.0",
|
||||
"nanostores": "^0.10.3",
|
||||
"ollama-ai-provider": "^0.15.2",
|
||||
"react": "^18.2.0",
|
||||
|
@ -155,9 +155,6 @@ importers:
|
||||
jszip:
|
||||
specifier: ^3.10.1
|
||||
version: 3.10.1
|
||||
lucide-react:
|
||||
specifier: ^0.460.0
|
||||
version: 0.460.0(react@18.3.1)
|
||||
nanostores:
|
||||
specifier: ^0.10.3
|
||||
version: 0.10.3
|
||||
@ -3674,11 +3671,6 @@ packages:
|
||||
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
lucide-react@0.460.0:
|
||||
resolution: {integrity: sha512-BVtq/DykVeIvRTJvRAgCsOwaGL8Un3Bxh8MbDxMhEWlZay3T4IpEKDEpwt5KZ0KJMHzgm6jrltxlT5eXOWXDHg==}
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc
|
||||
|
||||
magic-string@0.25.9:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
|
||||
@ -9492,10 +9484,6 @@ snapshots:
|
||||
|
||||
lru-cache@7.18.3: {}
|
||||
|
||||
lucide-react@0.460.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
magic-string@0.25.9:
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
|
Loading…
Reference in New Issue
Block a user