Smart auto (#476)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { LargeLanguageModel } from "@/lib/schemas";
|
||||
import { isDyadProEnabled, type LargeLanguageModel } from "@/lib/schemas";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Tooltip,
|
||||
@@ -119,6 +119,8 @@ export function ModelPicker() {
|
||||
return null;
|
||||
}
|
||||
const selectedModel = settings?.selectedModel;
|
||||
const isSmartAutoEnabled =
|
||||
settings.enableProSmartFilesContextMode && isDyadProEnabled(settings);
|
||||
const modelDisplayName = getModelDisplayName();
|
||||
|
||||
return (
|
||||
@@ -190,21 +192,37 @@ export function ModelPicker() {
|
||||
>
|
||||
<div className="flex justify-between items-start w-full">
|
||||
<span className="flex flex-col items-start">
|
||||
<span>{model.displayName}</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
auto
|
||||
<span>
|
||||
{isSmartAutoEnabled
|
||||
? "Smart Auto"
|
||||
: model.displayName}
|
||||
</span>
|
||||
</span>
|
||||
{model.tag && (
|
||||
<span className="text-[10px] bg-primary/10 text-primary px-1.5 py-0.5 rounded-full font-medium">
|
||||
{model.tag}
|
||||
</span>
|
||||
)}
|
||||
<div className="flex items-center gap-1.5">
|
||||
{isSmartAutoEnabled && (
|
||||
<span className="text-[10px] bg-gradient-to-r from-indigo-600 via-indigo-500 to-indigo-600 bg-[length:200%_100%] animate-[shimmer_5s_ease-in-out_infinite] text-white px-1.5 py-0.5 rounded-full font-medium">
|
||||
Dyad Pro
|
||||
</span>
|
||||
)}
|
||||
{model.tag && (
|
||||
<span className="text-[10px] bg-primary/10 text-primary px-1.5 py-0.5 rounded-full font-medium">
|
||||
{model.tag}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">
|
||||
{model.description}
|
||||
{isSmartAutoEnabled ? (
|
||||
<p>
|
||||
<strong>Smart Auto</strong> uses a cheaper model for
|
||||
easier tasks
|
||||
<br /> and a flagship model for harder tasks
|
||||
</p>
|
||||
) : (
|
||||
model.description
|
||||
)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
))}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { eq } from "drizzle-orm";
|
||||
|
||||
export const PROVIDERS_THAT_SUPPORT_THINKING: (keyof typeof MODEL_OPTIONS)[] = [
|
||||
"google",
|
||||
"auto",
|
||||
];
|
||||
|
||||
export interface ModelOption {
|
||||
@@ -139,6 +140,11 @@ export const MODEL_OPTIONS: Record<string, ModelOption[]> = {
|
||||
displayName: "Auto",
|
||||
description: "Automatically selects the best model",
|
||||
tag: "Default",
|
||||
// These are below Gemini 2.5 Pro & Flash limits
|
||||
// which are the ones defaulted to for both regular auto
|
||||
// and smart auto.
|
||||
maxOutputTokens: 32_000,
|
||||
contextWindow: 1_000_000,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -186,7 +192,7 @@ export const CLOUD_PROVIDERS: Record<
|
||||
auto: {
|
||||
displayName: "Dyad",
|
||||
websiteUrl: "https://academy.dyad.sh/settings",
|
||||
gatewayPrefix: "",
|
||||
gatewayPrefix: "dyad/",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -54,39 +54,6 @@ export async function getModelClient(
|
||||
const allProviders = await getLanguageModelProviders();
|
||||
|
||||
const dyadApiKey = settings.providerSettings?.auto?.apiKey?.value;
|
||||
// Handle 'auto' provider by trying each model in AUTO_MODELS until one works
|
||||
if (model.provider === "auto") {
|
||||
for (const autoModel of AUTO_MODELS) {
|
||||
const providerInfo = allProviders.find(
|
||||
(p) => p.id === autoModel.provider,
|
||||
);
|
||||
const envVarName = providerInfo?.envVarName;
|
||||
|
||||
const apiKey =
|
||||
dyadApiKey ||
|
||||
settings.providerSettings?.[autoModel.provider]?.apiKey?.value ||
|
||||
(envVarName ? getEnvVar(envVarName) : undefined);
|
||||
|
||||
if (apiKey) {
|
||||
logger.log(
|
||||
`Using provider: ${autoModel.provider} model: ${autoModel.name}`,
|
||||
);
|
||||
// Recursively call with the specific model found
|
||||
return await getModelClient(
|
||||
{
|
||||
provider: autoModel.provider,
|
||||
name: autoModel.name,
|
||||
},
|
||||
settings,
|
||||
files,
|
||||
);
|
||||
}
|
||||
}
|
||||
// If no models have API keys, throw an error
|
||||
throw new Error(
|
||||
"No API keys available for any model supported by the 'auto' provider.",
|
||||
);
|
||||
}
|
||||
|
||||
// --- Handle specific provider ---
|
||||
const providerConfig = allProviders.find((p) => p.id === model.provider);
|
||||
@@ -161,6 +128,38 @@ export async function getModelClient(
|
||||
// Fall through to regular provider logic if gateway prefix is missing
|
||||
}
|
||||
}
|
||||
// Handle 'auto' provider by trying each model in AUTO_MODELS until one works
|
||||
if (model.provider === "auto") {
|
||||
for (const autoModel of AUTO_MODELS) {
|
||||
const providerInfo = allProviders.find(
|
||||
(p) => p.id === autoModel.provider,
|
||||
);
|
||||
const envVarName = providerInfo?.envVarName;
|
||||
|
||||
const apiKey =
|
||||
settings.providerSettings?.[autoModel.provider]?.apiKey?.value ||
|
||||
(envVarName ? getEnvVar(envVarName) : undefined);
|
||||
|
||||
if (apiKey) {
|
||||
logger.log(
|
||||
`Using provider: ${autoModel.provider} model: ${autoModel.name}`,
|
||||
);
|
||||
// Recursively call with the specific model found
|
||||
return await getModelClient(
|
||||
{
|
||||
provider: autoModel.provider,
|
||||
name: autoModel.name,
|
||||
},
|
||||
settings,
|
||||
files,
|
||||
);
|
||||
}
|
||||
}
|
||||
// If no models have API keys, throw an error
|
||||
throw new Error(
|
||||
"No API keys available for any model supported by the 'auto' provider.",
|
||||
);
|
||||
}
|
||||
return getRegularModelClient(model, settings, providerConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,6 +168,13 @@ export const UserSettingsSchema = z.object({
|
||||
*/
|
||||
export type UserSettings = z.infer<typeof UserSettingsSchema>;
|
||||
|
||||
export function isDyadProEnabled(settings: UserSettings): boolean {
|
||||
return (
|
||||
settings.enableDyadPro === true &&
|
||||
!!settings.providerSettings?.auto?.apiKey?.value
|
||||
);
|
||||
}
|
||||
|
||||
// Define interfaces for the props
|
||||
export interface SecurityRisk {
|
||||
type: "warning" | "danger";
|
||||
|
||||
@@ -290,6 +290,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-marquee {
|
||||
animation: marquee 2s linear infinite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user