changing based on PR review

This commit is contained in:
Andrew Trokhymenko 2024-11-19 20:37:23 -05:00
parent 4b236e934e
commit fe3ea8005e
7 changed files with 46 additions and 80 deletions

View File

@ -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>(
); );
}, },
); );

View File

@ -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>

View File

@ -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 => {

View File

@ -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(),

View File

@ -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, {

View File

@ -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",

View File

@ -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