diff --git a/client/src/components/ai-chat.tsx b/client/src/components/ai-chat.tsx index d56d334..c1c9d25 100644 --- a/client/src/components/ai-chat.tsx +++ b/client/src/components/ai-chat.tsx @@ -32,7 +32,7 @@ export default function AiChat() { }, ]); const [input, setInput] = useState(""); - const [selectedModel, setSelectedModel] = useState("anthropic/claude-3.5-sonnet"); + const [selectedModel, setSelectedModel] = useState("anthropic/claude-sonnet-4.5"); const { toast } = useToast(); // Fetch available models from OpenRouter diff --git a/client/src/pages/mobile/settings.tsx b/client/src/pages/mobile/settings.tsx index e60fe13..dbaa01e 100644 --- a/client/src/pages/mobile/settings.tsx +++ b/client/src/pages/mobile/settings.tsx @@ -23,7 +23,7 @@ export default function SettingsMobile() { const [endpointUrl, setEndpointUrl] = useState(""); const [publicUrl, setPublicUrl] = useState(""); const [openrouterApiKey, setOpenrouterApiKey] = useState(""); - const [openrouterModel, setOpenrouterModel] = useState("anthropic/claude-3.5-sonnet"); + const [openrouterModel, setOpenrouterModel] = useState("anthropic/claude-sonnet-4.5"); const [openrouterSystemPrompt, setOpenrouterSystemPrompt] = useState("Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."); const [logoFile, setLogoFile] = useState(null); const [logoPreview, setLogoPreview] = useState(null); @@ -64,7 +64,7 @@ export default function SettingsMobile() { useEffect(() => { if (openrouterConfig) { - setOpenrouterModel((openrouterConfig as any).model || "anthropic/claude-3.5-sonnet"); + setOpenrouterModel((openrouterConfig as any).model || "anthropic/claude-sonnet-4.5"); setOpenrouterSystemPrompt((openrouterConfig as any).systemPrompt || "Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."); } }, [openrouterConfig]); diff --git a/client/src/pages/settings.tsx b/client/src/pages/settings.tsx index 82f3f91..c74a96d 100644 --- a/client/src/pages/settings.tsx +++ b/client/src/pages/settings.tsx @@ -23,7 +23,7 @@ export default function Settings() { const [endpointUrl, setEndpointUrl] = useState(""); const [publicUrl, setPublicUrl] = useState(""); const [openrouterApiKey, setOpenrouterApiKey] = useState(""); - const [openrouterModel, setOpenrouterModel] = useState("anthropic/claude-3.5-sonnet"); + const [openrouterModel, setOpenrouterModel] = useState("anthropic/claude-sonnet-4.5"); const [openrouterSystemPrompt, setOpenrouterSystemPrompt] = useState("Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."); const [logoFile, setLogoFile] = useState(null); const [logoPreview, setLogoPreview] = useState(null); @@ -81,7 +81,7 @@ export default function Settings() { useEffect(() => { if (openrouterConfig) { - setOpenrouterModel((openrouterConfig as any).model || "anthropic/claude-3.5-sonnet"); + setOpenrouterModel((openrouterConfig as any).model || "anthropic/claude-sonnet-4.5"); setOpenrouterSystemPrompt((openrouterConfig as any).systemPrompt || "Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."); } }, [openrouterConfig]); diff --git a/migration-docker.sql b/migration-docker.sql index 7842461..8a8d05c 100644 --- a/migration-docker.sql +++ b/migration-docker.sql @@ -88,7 +88,7 @@ CREATE TABLE IF NOT EXISTS openrouter_config ( id VARCHAR PRIMARY KEY DEFAULT gen_random_uuid(), user_id VARCHAR NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE, api_key TEXT NOT NULL, - model TEXT NOT NULL DEFAULT 'anthropic/claude-3.5-sonnet', + model TEXT NOT NULL DEFAULT 'anthropic/claude-sonnet-4.5', system_prompt TEXT NOT NULL DEFAULT 'Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l''engagement.', created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() diff --git a/server/services/openrouter.ts b/server/services/openrouter.ts index 0e607bd..c5b5c8e 100644 --- a/server/services/openrouter.ts +++ b/server/services/openrouter.ts @@ -18,8 +18,9 @@ export class OpenRouterService { private baseUrl = "https://openrouter.ai/api/v1/chat/completions"; async generatePostText(productInfo: ProductInfo, userId: string, modelOverride?: string): Promise { - // Get any available OpenRouter configuration (shared across all users) - const config = await storage.getAnyOpenrouterConfig(); + // Prefer the requesting user's own configuration; fall back to the most + // recently saved shared configuration if this user hasn't set one up. + const config = (await storage.getOpenrouterConfig(userId)) || (await storage.getAnyOpenrouterConfig()); if (!config) { throw new Error('Configuration OpenRouter non trouvée. Veuillez demander à un administrateur de configurer OpenRouter dans les Paramètres.'); diff --git a/server/storage.ts b/server/storage.ts index 9f22de0..b74d331 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -461,7 +461,7 @@ export class DatabaseStorage implements IStorage { } async getAnyOpenrouterConfig(): Promise { - const [config] = await db.select().from(openrouterConfig).limit(1); + const [config] = await db.select().from(openrouterConfig).orderBy(desc(openrouterConfig.updatedAt)).limit(1); return config || undefined; } diff --git a/shared/schema.ts b/shared/schema.ts index d5b0334..5797ead 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -127,7 +127,7 @@ export const openrouterConfig = pgTable("openrouter_config", { id: varchar("id").primaryKey().default(sql`gen_random_uuid()`), userId: varchar("user_id").notNull().unique().references(() => users.id, { onDelete: "cascade" }), apiKey: text("api_key").notNull(), - model: text("model").notNull().default("anthropic/claude-3.5-sonnet"), + model: text("model").notNull().default("anthropic/claude-sonnet-4.5"), systemPrompt: text("system_prompt").notNull().default("Tu es un expert en marketing des réseaux sociaux. Génère 3 variations de textes engageants pour des publications Facebook et Instagram à partir des informations produit fournies. Chaque variation doit être unique, captivante et optimisée pour l'engagement."), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(),