Merge pull request #108 from R0m1k3/claude/openrouter-api-404-h97d7e

fix(openrouter): respect the requesting user's saved model config
This commit is contained in:
LogiFlow authored and GitHub committed 2026-07-14 08:12:07 +02:00
commit 517c786be6
7 files changed
+11 -10

No files matched your search

+1 -1
View File
@@ -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
+2 -2
View File
@@ -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<File | null>(null);
const [logoPreview, setLogoPreview] = useState<string | null>(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]);
+2 -2
View File
@@ -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<File | null>(null);
const [logoPreview, setLogoPreview] = useState<string | null>(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]);
+1 -1
View File
@@ -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()
+3 -2
View File
@@ -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<GeneratedText[]> {
// 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.');
+1 -1
View File
@@ -461,7 +461,7 @@ export class DatabaseStorage implements IStorage {
}
async getAnyOpenrouterConfig(): Promise<OpenrouterConfig | undefined> {
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;
}
+1 -1
View File
@@ -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(),