Upload 26 files
Browse files
app/components/chat/ApiKeyWarning.tsx
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import React from 'react';
|
2 |
+
import type { ProviderInfo } from '~/types/model';
|
3 |
+
|
4 |
+
interface ApiKeyWarningProps {
|
5 |
+
provider: ProviderInfo;
|
6 |
+
apiKeys: Record<string, string>;
|
7 |
+
}
|
8 |
+
|
9 |
+
export const ApiKeyWarning: React.FC<ApiKeyWarningProps> = ({ provider, apiKeys }) => {
|
10 |
+
const isApiKeyMissing = !apiKeys[provider.name];
|
11 |
+
|
12 |
+
if (!isApiKeyMissing) return null;
|
13 |
+
|
14 |
+
return (
|
15 |
+
<div className="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-4">
|
16 |
+
<div className="flex">
|
17 |
+
<div className="flex-shrink-0">
|
18 |
+
<div className="i-ph:warning-circle text-yellow-400 text-2xl" />
|
19 |
+
</div>
|
20 |
+
<div className="ml-3">
|
21 |
+
<p className="text-sm text-yellow-700">
|
22 |
+
API key is missing for {provider.name}. Please add an API key in the settings to send messages.
|
23 |
+
</p>
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
);
|
28 |
+
};
|
app/components/chat/BaseChat.tsx
CHANGED
@@ -77,6 +77,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|
77 |
isStreaming = false,
|
78 |
model,
|
79 |
setModel,
|
|
|
80 |
provider,
|
81 |
setProvider,
|
82 |
providerList,
|
@@ -312,12 +313,18 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|
312 |
}
|
313 |
};
|
314 |
|
|
|
|
|
315 |
const baseChat = (
|
316 |
<div
|
317 |
ref={ref}
|
318 |
className={classNames(styles.BaseChat, 'relative flex h-full w-full overflow-hidden')}
|
319 |
data-chat-visible={showChat}
|
320 |
>
|
|
|
|
|
|
|
|
|
321 |
<ClientOnly>{() => <Menu />}</ClientOnly>
|
322 |
<div ref={scrollRef} className="flex flex-col lg:flex-row overflow-y-auto w-full h-full">
|
323 |
<div className={classNames(styles.Chat, 'flex flex-col flex-grow lg:min-w-[var(--chat-min-width)] h-full')}>
|
@@ -528,7 +535,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
|
528 |
<SendButton
|
529 |
show={input.length > 0 || isStreaming || uploadedFiles.length > 0}
|
530 |
isStreaming={isStreaming}
|
531 |
-
disabled={!providerList || providerList.length === 0}
|
532 |
onClick={(event) => {
|
533 |
if (isStreaming) {
|
534 |
handleStop?.();
|
|
|
77 |
isStreaming = false,
|
78 |
model,
|
79 |
setModel,
|
80 |
+
apiKeys,
|
81 |
provider,
|
82 |
setProvider,
|
83 |
providerList,
|
|
|
313 |
}
|
314 |
};
|
315 |
|
316 |
+
const isApiKeyAvailable = apiKeys && apiKeys[provider.name];
|
317 |
+
|
318 |
const baseChat = (
|
319 |
<div
|
320 |
ref={ref}
|
321 |
className={classNames(styles.BaseChat, 'relative flex h-full w-full overflow-hidden')}
|
322 |
data-chat-visible={showChat}
|
323 |
>
|
324 |
+
<ApiKeyWarning
|
325 |
+
provider={provider}
|
326 |
+
apiKeys={apiKeys}
|
327 |
+
/>
|
328 |
<ClientOnly>{() => <Menu />}</ClientOnly>
|
329 |
<div ref={scrollRef} className="flex flex-col lg:flex-row overflow-y-auto w-full h-full">
|
330 |
<div className={classNames(styles.Chat, 'flex flex-col flex-grow lg:min-w-[var(--chat-min-width)] h-full')}>
|
|
|
535 |
<SendButton
|
536 |
show={input.length > 0 || isStreaming || uploadedFiles.length > 0}
|
537 |
isStreaming={isStreaming}
|
538 |
+
disabled={!isApiKeyAvailable || !providerList || providerList.length === 0}
|
539 |
onClick={(event) => {
|
540 |
if (isStreaming) {
|
541 |
handleStop?.();
|
app/components/chat/Chat.client.tsx
CHANGED
@@ -110,8 +110,8 @@ interface ChatProps {
|
|
110 |
|
111 |
export const ChatImpl = memo(
|
112 |
({ description, initialMessages, storeMessageHistory, importChat, exportChat }: ChatProps) => {
|
113 |
-
useShortcuts();
|
114 |
|
|
|
115 |
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
116 |
const [chatStarted, setChatStarted] = useState(initialMessages.length > 0);
|
117 |
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]); // Move here
|
@@ -511,6 +511,7 @@ export const ChatImpl = memo(
|
|
511 |
setModel={handleModelChange}
|
512 |
provider={provider}
|
513 |
setProvider={handleProviderChange}
|
|
|
514 |
providerList={activeProviders}
|
515 |
messageRef={messageRef}
|
516 |
scrollRef={scrollRef}
|
|
|
110 |
|
111 |
export const ChatImpl = memo(
|
112 |
({ description, initialMessages, storeMessageHistory, importChat, exportChat }: ChatProps) => {
|
|
|
113 |
|
114 |
+
useShortcuts();
|
115 |
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
116 |
const [chatStarted, setChatStarted] = useState(initialMessages.length > 0);
|
117 |
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]); // Move here
|
|
|
511 |
setModel={handleModelChange}
|
512 |
provider={provider}
|
513 |
setProvider={handleProviderChange}
|
514 |
+
apiKeys={apiKeys}
|
515 |
providerList={activeProviders}
|
516 |
messageRef={messageRef}
|
517 |
scrollRef={scrollRef}
|