Skip to content

Commit

Permalink
Bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
wonderwhy-er committed Nov 12, 2024
1 parent a2cca14 commit 756d3f2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 29 deletions.
14 changes: 12 additions & 2 deletions app/components/chat/APIKeyManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ interface APIKeyManagerProps {
provider: ProviderInfo;
apiKey: string;
setApiKey: (key: string) => void;
getApiKeyLink?: string;
labelForGetApiKey?: string;
}

export const APIKeyManager: React.FC<APIKeyManagerProps> = ({ provider, apiKey, setApiKey }) => {
export const APIKeyManager: React.FC<APIKeyManagerProps> = ({
provider,
apiKey,
setApiKey,
}) => {
const [isEditing, setIsEditing] = useState(false);
const [tempKey, setTempKey] = useState(apiKey);

Expand Down Expand Up @@ -43,7 +49,11 @@ export const APIKeyManager: React.FC<APIKeyManagerProps> = ({ provider, apiKey,
<IconButton onClick={() => setIsEditing(true)} title="Edit API Key">
<div className="i-ph:pencil-simple" />
</IconButton>
{!!provider?.getApiKeyLink ? <a href={provider?.getApiKeyLink}>{provider?.labelForGetApiKey || "Get API Key"}</a> : "" }

{provider?.getApiKeyLink && <IconButton onClick={() => window.open(provider?.getApiKeyLink)} title="Edit API Key">
<span className="mr-2">{provider?.labelForGetApiKey || 'Get API Key'}</span>
<div className={provider?.icon || "i-ph:key"} />
</IconButton>}
</>
)}
</div>
Expand Down
24 changes: 13 additions & 11 deletions app/components/chat/BaseChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Menu } from '~/components/sidebar/Menu.client';
import { IconButton } from '~/components/ui/IconButton';
import { Workbench } from '~/components/workbench/Workbench.client';
import { classNames } from '~/utils/classNames';
import { MODEL_LIST, DEFAULT_PROVIDER, PROVIDER_LIST } from '~/utils/constants';
import { MODEL_LIST, DEFAULT_PROVIDER, PROVIDER_LIST, ProviderInfo } from '~/utils/constants';
import { Messages } from './Messages.client';
import { SendButton } from './SendButton.client';
import { useState } from 'react';
Expand All @@ -30,9 +30,9 @@ const ModelSelector = ({ model, setModel, provider, setProvider, modelList, prov
return (
<div className="mb-2 flex gap-2">
<select
value={provider}
value={provider?.name}
onChange={(e) => {
setProvider(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 : '');
}}
Expand All @@ -49,7 +49,7 @@ const ModelSelector = ({ model, setModel, provider, setProvider, modelList, prov
onChange={(e) => setModel(e.target.value)}
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].filter(e => e.provider == provider && e.name).map((modelOption) => (
{[...modelList].filter(e => e.provider == provider?.name && e.name).map((modelOption) => (
<option key={modelOption.name} value={modelOption.name}>
{modelOption.label}
</option>
Expand All @@ -74,8 +74,8 @@ interface BaseChatProps {
input?: string;
model: string;
setModel: (model: string) => void;
provider: string;
setProvider: (provider: string) => void;
provider: ProviderInfo;
setProvider: (provider: ProviderInfo) => void;
handleStop?: () => void;
sendMessage?: (event: React.UIEvent, messageInput?: string) => void;
handleInputChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
Expand Down Expand Up @@ -106,6 +106,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
},
ref,
) => {
console.log(provider);
const TEXTAREA_MAX_HEIGHT = chatStarted ? 400 : 200;
const [apiKeys, setApiKeys] = useState<Record<string, string>>({});

Expand Down Expand Up @@ -194,11 +195,12 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
setProvider={setProvider}
providerList={providerList}
/>
<APIKeyManager
provider={provider}
apiKey={apiKeys[provider] || ''}
setApiKey={(key) => updateApiKey(provider, key)}
/>
{provider &&
<APIKeyManager
provider={provider}
apiKey={apiKeys[provider.name] || ''}
setApiKey={(key) => updateApiKey(provider.name, key)}
/>}
<div
className={classNames(
'shadow-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background backdrop-filter backdrop-blur-[8px] rounded-lg overflow-hidden transition-all',
Expand Down
4 changes: 2 additions & 2 deletions app/components/chat/Chat.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,15 @@ export const ChatImpl = memo(({ initialMessages, storeMessageHistory }: ChatProp
* manually reset the input and we'd have to manually pass in file attachments. However, those
* aren't relevant here.
*/
append({ role: 'user', content: `[Model: ${model}]\n\n[Provider: ${provider}]\n\n${diff}\n\n${_input}` });
append({ role: 'user', content: `[Model: ${model}]\n\n[Provider: ${provider.name}]\n\n${diff}\n\n${_input}` });

/**
* After sending a new message we reset all modifications since the model
* should now be aware of all the changes.
*/
workbenchStore.resetAllFileModifications();
} else {
append({ role: 'user', content: `[Model: ${model}]\n\n[Provider: ${provider}]\n\n${_input}` });
append({ role: 'user', content: `[Model: ${model}]\n\n[Provider: ${provider.name}]\n\n${_input}` });
}

setInput('');
Expand Down
35 changes: 21 additions & 14 deletions app/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,37 @@ export const MODIFICATIONS_TAG_NAME = 'bolt_file_modifications';
export const MODEL_REGEX = /^\[Model: (.*?)\]\n\n/;
export const PROVIDER_REGEX = /\[Provider: (.*?)\]\n\n/;
export const DEFAULT_MODEL = 'claude-3-5-sonnet-latest';
export const DEFAULT_PROVIDER = 'Anthropic';


export type ProviderInfo = {
staticModels: ModelInfo[],
name: string,
getDynamicModels?: () => Promise<ModelInfo[]>,
getApiKeyLink?: string,
labelForGetApiKey?: string,
icon?:string,
};

const PROVIDER_LIST: ProviderInfo[] = [
{
name: 'Anthropic',
staticModels: [
{ name: 'claude-3-5-sonnet-latest', label: 'Claude 3.5 Sonnet (new)', provider: 'Anthropic' },
{ name: 'claude-3-5-sonnet-20240620', label: 'Claude 3.5 Sonnet (old)', provider: 'Anthropic' },
{ name: 'claude-3-5-haiku-latest', label: 'Claude 3.5 Haiku (new)', provider: 'Anthropic' },
{ name: 'claude-3-opus-latest', label: 'Claude 3 Opus', provider: 'Anthropic' },
{ name: 'claude-3-sonnet-20240229', label: 'Claude 3 Sonnet', provider: 'Anthropic' },
{ name: 'claude-3-haiku-20240307', label: 'Claude 3 Haiku', provider: 'Anthropic' }
],
getApiKeyLink: "https://console.anthropic.com/settings/keys",
},
{
name: 'Ollama',
staticModels: [],
getDynamicModels: getOllamaModels
getDynamicModels: getOllamaModels,
getApiKeyLink: "https://ollama.com/download",
labelForGetApiKey: "Download Ollama",
icon: "i-ph:cloud-arrow-down",
}, {
name: 'OpenAILike',
staticModels: [],
Expand Down Expand Up @@ -62,17 +78,6 @@ const PROVIDER_LIST: ProviderInfo[] = [
{ name: 'llama-3.2-1b-preview', label: 'Llama 3.2 1b (Groq)', provider: 'Groq' }
],
getApiKeyLink: 'https://console.groq.com/keys'
}, {
name: 'Anthropic',
staticModels: [
{ name: 'claude-3-5-sonnet-latest', label: 'Claude 3.5 Sonnet (new)', provider: 'Anthropic' },
{ name: 'claude-3-5-sonnet-20240620', label: 'Claude 3.5 Sonnet (old)', provider: 'Anthropic' },
{ name: 'claude-3-5-haiku-latest', label: 'Claude 3.5 Haiku (new)', provider: 'Anthropic' },
{ name: 'claude-3-opus-latest', label: 'Claude 3 Opus', provider: 'Anthropic' },
{ name: 'claude-3-sonnet-20240229', label: 'Claude 3 Sonnet', provider: 'Anthropic' },
{ name: 'claude-3-haiku-20240307', label: 'Claude 3 Haiku', provider: 'Anthropic' }
],
getApiKeyLink: "https://console.anthropic.com/settings/keys",
}, {
name: 'OpenAI',
staticModels: [
Expand Down Expand Up @@ -114,10 +119,12 @@ const PROVIDER_LIST: ProviderInfo[] = [
staticModels: [],
getDynamicModels: getLMStudioModels,
getApiKeyLink: 'https://lmstudio.ai/',
labelForGetApiKey: 'Get LMStudio'
labelForGetApiKey: 'Get LMStudio',
icon: "i-ph:cloud-arrow-down",
}
];

export const DEFAULT_PROVIDER = PROVIDER_LIST[0];

const staticModels: ModelInfo[] = PROVIDER_LIST.map(p => p.staticModels).flat();

Expand Down

0 comments on commit 756d3f2

Please sign in to comment.