Use Canonical Models to set context window sizes (#6723)
This commit is contained in:
@@ -41,6 +41,7 @@ import {
|
||||
import { getNavigationShortcutText } from '../utils/keyboardShortcuts';
|
||||
import { UserInput, ImageData } from '../types/message';
|
||||
import { compressImageDataUrl } from '../utils/conversionUtils';
|
||||
import { fetchCanonicalModelInfo } from '../utils/canonical';
|
||||
|
||||
interface PastedImage {
|
||||
id: string;
|
||||
@@ -58,11 +59,6 @@ const TOOLS_MAX_SUGGESTED = 60; // max number of tools before we show a warning
|
||||
// Manual compact trigger message - must match backend constant
|
||||
const MANUAL_COMPACT_TRIGGER = '/compact';
|
||||
|
||||
interface ModelLimit {
|
||||
pattern: string;
|
||||
context_limit: number;
|
||||
}
|
||||
|
||||
interface ChatInputProps {
|
||||
sessionId: string | null;
|
||||
handleSubmit: (input: UserInput) => void;
|
||||
@@ -142,7 +138,7 @@ export default function ChatInput({
|
||||
const dropdownRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
|
||||
null
|
||||
) as React.RefObject<HTMLDivElement>;
|
||||
const { getProviders, read } = useConfig();
|
||||
const { getProviders } = useConfig();
|
||||
const { getCurrentModelAndProvider, currentModel, currentProvider } = useModelAndProvider();
|
||||
const [tokenLimit, setTokenLimit] = useState<number>(TOKEN_LIMIT_DEFAULT);
|
||||
const [isTokenLimitLoaded, setIsTokenLimitLoaded] = useState(false);
|
||||
@@ -367,28 +363,6 @@ export default function ChatInput({
|
||||
}
|
||||
}, [textAreaRef]);
|
||||
|
||||
// Load model limits from the API
|
||||
const getModelLimits = async () => {
|
||||
try {
|
||||
const response = await read('model-limits', false);
|
||||
if (response) {
|
||||
// The response is already parsed, no need for JSON.parse
|
||||
return response as ModelLimit[];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching model limits:', err);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const findModelLimit = (modelName: string, modelLimits: ModelLimit[]): number | null => {
|
||||
if (!modelName) return null;
|
||||
const matchingLimit = modelLimits.find((limit) =>
|
||||
modelName.toLowerCase().includes(limit.pattern.toLowerCase())
|
||||
);
|
||||
return matchingLimit ? matchingLimit.context_limit : null;
|
||||
};
|
||||
|
||||
// Load providers and get current model's token limit
|
||||
const loadProviderDetails = async () => {
|
||||
try {
|
||||
@@ -403,7 +377,7 @@ export default function ChatInput({
|
||||
return;
|
||||
}
|
||||
|
||||
// First, check predefined models from environment (highest priority)
|
||||
// Priority 1: Check predefined models from environment
|
||||
const predefinedModels = getPredefinedModelsFromEnv();
|
||||
const predefinedModel = predefinedModels.find((m) => m.name === model);
|
||||
if (predefinedModel?.context_limit) {
|
||||
@@ -412,12 +386,18 @@ export default function ChatInput({
|
||||
return;
|
||||
}
|
||||
|
||||
const providers = await getProviders(true);
|
||||
// Priority 2: Check canonical model info (source of truth)
|
||||
const canonicalInfo = await fetchCanonicalModelInfo(provider, model);
|
||||
if (canonicalInfo?.context_limit) {
|
||||
setTokenLimit(canonicalInfo.context_limit);
|
||||
setIsTokenLimitLoaded(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the provider details for the current provider
|
||||
// Priority 3: Fall back to provider metadata known_models (may be outdated)
|
||||
const providers = await getProviders(true);
|
||||
const currentProvider = providers.find((p) => p.name === provider);
|
||||
if (currentProvider?.metadata?.known_models) {
|
||||
// Find the model's token limit from the backend response
|
||||
const modelConfig = currentProvider.metadata.known_models.find((m) => m.name === model);
|
||||
if (modelConfig?.context_limit) {
|
||||
setTokenLimit(modelConfig.context_limit);
|
||||
@@ -426,16 +406,7 @@ export default function ChatInput({
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Use pattern matching logic if no exact model match was found
|
||||
const modelLimit = await getModelLimits();
|
||||
const fallbackLimit = findModelLimit(model as string, modelLimit);
|
||||
if (fallbackLimit !== null) {
|
||||
setTokenLimit(fallbackLimit);
|
||||
setIsTokenLimitLoaded(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// If no match found, use the default model limit
|
||||
// Priority 4: Use default if nothing else found
|
||||
setTokenLimit(TOKEN_LIMIT_DEFAULT);
|
||||
setIsTokenLimitLoaded(true);
|
||||
} catch (err) {
|
||||
@@ -1190,11 +1161,13 @@ export default function ChatInput({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex flex-col relative h-auto p-4 transition-colors ${disableAnimation ? '' : 'page-transition'
|
||||
} ${isFocused
|
||||
className={`flex flex-col relative h-auto p-4 transition-colors ${
|
||||
disableAnimation ? '' : 'page-transition'
|
||||
} ${
|
||||
isFocused
|
||||
? 'border-border-strong hover:border-border-strong'
|
||||
: 'border-border-default hover:border-border-default'
|
||||
} bg-background-default z-10 rounded-t-2xl`}
|
||||
} bg-background-default z-10 rounded-t-2xl`}
|
||||
data-drop-zone="true"
|
||||
onDrop={handleLocalDrop}
|
||||
onDragOver={handleLocalDragOver}
|
||||
@@ -1263,7 +1236,7 @@ export default function ChatInput({
|
||||
size="sm"
|
||||
shape="round"
|
||||
variant="outline"
|
||||
onClick={() => { }}
|
||||
onClick={() => {}}
|
||||
disabled={true}
|
||||
className="bg-slate-600 text-white cursor-not-allowed opacity-50 border-slate-600 rounded-full px-6 py-2"
|
||||
>
|
||||
@@ -1310,12 +1283,13 @@ export default function ChatInput({
|
||||
}
|
||||
}}
|
||||
disabled={isTranscribing}
|
||||
className={`rounded-full px-6 py-2 ${isRecording
|
||||
? 'bg-red-500 text-white hover:bg-red-600 border-red-500'
|
||||
: isTranscribing
|
||||
? 'bg-slate-600 text-white cursor-not-allowed animate-pulse border-slate-600'
|
||||
: 'bg-slate-600 text-white hover:bg-slate-700 border-slate-600'
|
||||
}`}
|
||||
className={`rounded-full px-6 py-2 ${
|
||||
isRecording
|
||||
? 'bg-red-500 text-white hover:bg-red-600 border-red-500'
|
||||
: isTranscribing
|
||||
? 'bg-slate-600 text-white cursor-not-allowed animate-pulse border-slate-600'
|
||||
: 'bg-slate-600 text-white hover:bg-slate-700 border-slate-600'
|
||||
}`}
|
||||
>
|
||||
<Microphone />
|
||||
</Button>
|
||||
@@ -1353,10 +1327,11 @@ export default function ChatInput({
|
||||
shape="round"
|
||||
variant="outline"
|
||||
disabled={isSubmitButtonDisabled}
|
||||
className={`rounded-full px-10 py-2 flex items-center gap-2 ${isSubmitButtonDisabled
|
||||
? 'bg-slate-600 text-white cursor-not-allowed opacity-50 border-slate-600'
|
||||
: 'bg-slate-600 text-white hover:bg-slate-700 border-slate-600 hover:cursor-pointer'
|
||||
}`}
|
||||
className={`rounded-full px-10 py-2 flex items-center gap-2 ${
|
||||
isSubmitButtonDisabled
|
||||
? 'bg-slate-600 text-white cursor-not-allowed opacity-50 border-slate-600'
|
||||
: 'bg-slate-600 text-white hover:bg-slate-700 border-slate-600 hover:cursor-pointer'
|
||||
}`}
|
||||
>
|
||||
<Send className="w-4 h-4" />
|
||||
<span className="text-sm">Send</span>
|
||||
|
||||
Reference in New Issue
Block a user