stops import: swap OpenAI for MiniMax as default AI provider
Deploy to route.crispygoat.com / deploy (push) Successful in 5m27s

This commit is contained in:
Tyler
2026-06-10 10:58:37 -06:00
parent c6501b3ecd
commit 4909a78aca
+17 -10
View File
@@ -9,19 +9,25 @@ type RequestBody = {
/** Raw file content (CSV text). AI parsing is attempted if useAI=true. */
text: string;
brandId: string;
/** If true and OPENAI_API_KEY is set, parse unstructured text with AI. */
/** If true and an AI API key is set, parse unstructured text with AI. */
useAI?: boolean;
};
const AI_MODEL = "gpt-4o-mini";
async function parseWithAI(text: string, brandId: string): Promise<{
async function parseWithAI(text: string, _brandId: string): Promise<{
stops: ParsedStop[];
warnings: string[];
}> {
const apiKey = process.env.OPENAI_API_KEY;
// Prefer MiniMax (env-level) — fall back to OpenAI.
const provider: "minimax" | "openai" =
process.env.MINIMAX_API_KEY ? "minimax" : process.env.OPENAI_API_KEY ? "openai" : "openai";
const apiKey = provider === "minimax" ? process.env.MINIMAX_API_KEY! : process.env.OPENAI_API_KEY!;
const baseURL = provider === "minimax"
? (process.env.MINIMAX_BASE_URL || "https://api.minimax.io/v1")
: "https://api.openai.com/v1";
const model = provider === "minimax" ? "MiniMax-M3" : "gpt-4o-mini";
if (!apiKey) {
throw new Error("OPENAI_API_KEY is not configured. Use CSV format for reliable parsing.");
throw new Error("MINIMAX_API_KEY or OPENAI_API_KEY is not configured. Use CSV format for reliable parsing.");
}
const systemPrompt = `You are a schedule extraction assistant. Given raw schedule text, extract all stop entries.
@@ -37,26 +43,27 @@ Return a JSON array where each entry has:
If a row lacks required fields (city, state, location), omit it and add a warning.`;
const res = await fetch("https://api.openai.com/v1/chat/completions", {
const res = await fetch(`${baseURL}/chat/completions`, {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: AI_MODEL,
model,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: `Extract stops from this schedule:\n\n${text.slice(0, 8000)}` },
],
response_format: { type: "json_object" },
// response_format is OpenAI-specific. MiniMax /v1/chat/completions may not honor it.
...(provider === "openai" ? { response_format: { type: "json_object" } } : {}),
temperature: 0.1,
}),
});
if (!res.ok) {
const err = await res.text();
throw new Error(`OpenAI API error: ${res.status}${err}`);
throw new Error(`${provider} API error: ${res.status}${err}`);
}
const data = await res.json();