mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-05-04 12:21:29 +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
|
<select
|
||||||
value={provider?.name}
|
value={provider?.name}
|
||||||
onChange={(e) => {
|
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);
|
const firstModel = [...modelList].find((m) => m.provider == e.target.value);
|
||||||
setModel(firstModel ? firstModel.name : '');
|
setModel(firstModel ? firstModel.name : '');
|
||||||
}}
|
}}
|
||||||
@ -51,7 +51,7 @@ const ModelSelector = ({ model, setModel, provider, setProvider, modelList, prov
|
|||||||
key={provider?.name}
|
key={provider?.name}
|
||||||
value={model}
|
value={model}
|
||||||
onChange={(e) => setModel(e.target.value)}
|
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"
|
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]
|
{[...modelList]
|
||||||
@ -93,32 +93,34 @@ interface BaseChatProps {
|
|||||||
setImageDataList?: (dataList: string[]) => void;
|
setImageDataList?: (dataList: string[]) => void;
|
||||||
}
|
}
|
||||||
export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||||
({
|
(
|
||||||
textareaRef,
|
{
|
||||||
messageRef,
|
textareaRef,
|
||||||
scrollRef,
|
messageRef,
|
||||||
showChat,
|
scrollRef,
|
||||||
chatStarted = false,
|
showChat = true,
|
||||||
isStreaming = false,
|
chatStarted = false,
|
||||||
model,
|
isStreaming = false,
|
||||||
setModel,
|
model,
|
||||||
provider,
|
setModel,
|
||||||
setProvider,
|
provider,
|
||||||
input = '',
|
setProvider,
|
||||||
enhancingPrompt,
|
input = '',
|
||||||
handleInputChange,
|
enhancingPrompt,
|
||||||
promptEnhanced,
|
handleInputChange,
|
||||||
enhancePrompt,
|
promptEnhanced,
|
||||||
sendMessage,
|
enhancePrompt,
|
||||||
handleStop,
|
sendMessage,
|
||||||
uploadedFiles,
|
handleStop,
|
||||||
setUploadedFiles,
|
uploadedFiles,
|
||||||
imageDataList,
|
setUploadedFiles,
|
||||||
setImageDataList,
|
imageDataList,
|
||||||
messages,
|
setImageDataList,
|
||||||
children, // Add this
|
messages,
|
||||||
}, ref) => {
|
children, // Add this
|
||||||
console.log(provider);
|
},
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
|
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
|
||||||
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});
|
||||||
const [modelList, setModelList] = useState(MODEL_LIST);
|
const [modelList, setModelList] = useState(MODEL_LIST);
|
||||||
@ -139,7 +141,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
Cookies.remove('apiKeys');
|
Cookies.remove('apiKeys');
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeModelList().then(modelList => {
|
initializeModelList().then((modelList) => {
|
||||||
setModelList(modelList);
|
setModelList(modelList);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
@ -239,12 +241,13 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
setProvider={setProvider}
|
setProvider={setProvider}
|
||||||
providerList={PROVIDER_LIST}
|
providerList={PROVIDER_LIST}
|
||||||
/>
|
/>
|
||||||
{provider &&
|
{provider && (
|
||||||
<APIKeyManager
|
<APIKeyManager
|
||||||
provider={provider}
|
provider={provider}
|
||||||
apiKey={apiKeys[provider.name] || ''}
|
apiKey={apiKeys[provider.name] || ''}
|
||||||
setApiKey={(key) => updateApiKey(provider.name, key)}
|
setApiKey={(key) => updateApiKey(provider.name, key)}
|
||||||
/>}
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<FilePreview
|
<FilePreview
|
||||||
files={uploadedFiles}
|
files={uploadedFiles}
|
||||||
@ -309,7 +312,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|||||||
className="transition-all"
|
className="transition-all"
|
||||||
onClick={() => handleFileUpload()}
|
onClick={() => handleFileUpload()}
|
||||||
>
|
>
|
||||||
<div className="i-ph:upload text-xl"></div>
|
<div className="i-ph:paperclip text-xl"></div>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|
||||||
<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 React from 'react';
|
||||||
import { X } from 'lucide-react';
|
|
||||||
|
|
||||||
|
// Rest of the interface remains the same
|
||||||
interface FilePreviewProps {
|
interface FilePreviewProps {
|
||||||
files: File[];
|
files: File[];
|
||||||
imageDataList: string[]; // or imagePreviews: string[]
|
imageDataList: string[];
|
||||||
onRemove: (index: number) => void;
|
onRemove: (index: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilePreview: React.FC<FilePreviewProps> = ({ files, imageDataList, onRemove }) => {
|
const FilePreview: React.FC<FilePreviewProps> = ({ files, imageDataList, onRemove }) => {
|
||||||
if (!files || files.length === 0) {
|
if (!files || files.length === 0) {
|
||||||
return null; // Or render a placeholder if desired
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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) => (
|
{files.map((file, index) => (
|
||||||
<div key={file.name + file.size} className="mr-2 relative">
|
<div key={file.name + file.size} className="mr-2 relative">
|
||||||
{/* Display image preview or file icon */}
|
|
||||||
{imageDataList[index] && (
|
{imageDataList[index] && (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<img src={imageDataList[index]} alt={file.name} className="max-h-20" />
|
<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"
|
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">
|
<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>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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}}>) {
|
function sanitizeUserMessage(content: string | Array<{type: string, text?: string, image_url?: {url: string}}>) {
|
||||||
if (Array.isArray(content)) {
|
if (Array.isArray(content)) {
|
||||||
return content.map(item => {
|
return content.map(item => {
|
||||||
|
@ -45,12 +45,12 @@ function extractPropertiesFromMessage(message: Message): { model: string; provid
|
|||||||
if (item.type === 'text') {
|
if (item.type === 'text') {
|
||||||
return {
|
return {
|
||||||
type: 'text',
|
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
|
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 };
|
return { model, provider, content: cleanedContent };
|
||||||
}
|
}
|
||||||
@ -80,16 +80,6 @@ export function streamText(
|
|||||||
return message; // No changes for non-user messages
|
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({
|
return _streamText({
|
||||||
model: getModel(currentProvider, currentModel, env, apiKeys),
|
model: getModel(currentProvider, currentModel, env, apiKeys),
|
||||||
system: getSystemPrompt(),
|
system: getSystemPrompt(),
|
||||||
|
@ -30,8 +30,6 @@ function parseCookies(cookieHeader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function chatAction({ context, request }: ActionFunctionArgs) {
|
async function chatAction({ context, request }: ActionFunctionArgs) {
|
||||||
// console.log('=== API CHAT LOGGING START ===');
|
|
||||||
// console.log('Request received:', request.url);
|
|
||||||
|
|
||||||
const { messages, imageData } = await request.json<{
|
const { messages, imageData } = await request.json<{
|
||||||
messages: Messages,
|
messages: Messages,
|
||||||
@ -39,6 +37,8 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const cookieHeader = request.headers.get("Cookie");
|
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 apiKeys = JSON.parse(parseCookies(cookieHeader).apiKeys || "{}");
|
||||||
|
|
||||||
const stream = new SwitchableStream();
|
const stream = new SwitchableStream();
|
||||||
@ -71,13 +71,6 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
|
|
||||||
const result = await streamText(messages, context.cloudflare.env, options, apiKeys);
|
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());
|
stream.switchSource(result.toAIStream());
|
||||||
|
|
||||||
return new Response(stream.readable, {
|
return new Response(stream.readable, {
|
||||||
|
@ -74,7 +74,6 @@
|
|||||||
"jose": "^5.6.3",
|
"jose": "^5.6.3",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"lucide-react": "^0.460.0",
|
|
||||||
"nanostores": "^0.10.3",
|
"nanostores": "^0.10.3",
|
||||||
"ollama-ai-provider": "^0.15.2",
|
"ollama-ai-provider": "^0.15.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
@ -155,9 +155,6 @@ importers:
|
|||||||
jszip:
|
jszip:
|
||||||
specifier: ^3.10.1
|
specifier: ^3.10.1
|
||||||
version: 3.10.1
|
version: 3.10.1
|
||||||
lucide-react:
|
|
||||||
specifier: ^0.460.0
|
|
||||||
version: 0.460.0(react@18.3.1)
|
|
||||||
nanostores:
|
nanostores:
|
||||||
specifier: ^0.10.3
|
specifier: ^0.10.3
|
||||||
version: 0.10.3
|
version: 0.10.3
|
||||||
@ -3674,11 +3671,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
|
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
|
||||||
engines: {node: '>=12'}
|
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:
|
magic-string@0.25.9:
|
||||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||||
|
|
||||||
@ -9492,10 +9484,6 @@ snapshots:
|
|||||||
|
|
||||||
lru-cache@7.18.3: {}
|
lru-cache@7.18.3: {}
|
||||||
|
|
||||||
lucide-react@0.460.0(react@18.3.1):
|
|
||||||
dependencies:
|
|
||||||
react: 18.3.1
|
|
||||||
|
|
||||||
magic-string@0.25.9:
|
magic-string@0.25.9:
|
||||||
dependencies:
|
dependencies:
|
||||||
sourcemap-codec: 1.4.8
|
sourcemap-codec: 1.4.8
|
||||||
|
Loading…
Reference in New Issue
Block a user