fix(rsocials): campaign wizard timeout + faster content generation

- Add 120s AbortController timeout to apiFetch so wizard can't hang
  forever on slow networks (shows "Request timed out" instead of stuck)
- Switch content generation from gemini-2.5-pro to gemini-2.5-flash
  to avoid Cloudflare/Traefik proxy timeouts (pro model took 30-60s+)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-30 22:48:57 -07:00
parent df202df06c
commit d865da32a7
2 changed files with 21 additions and 10 deletions

View File

@ -133,17 +133,28 @@ export class FolkCampaignWizard extends HTMLElement {
return `/${encodeURIComponent(this._space)}/rsocials`; return `/${encodeURIComponent(this._space)}/rsocials`;
} }
private async apiFetch(path: string, opts: RequestInit = {}): Promise<Response> { private async apiFetch(path: string, opts: RequestInit & { timeoutMs?: number } = {}): Promise<Response> {
let token = ''; let token = '';
try { const s = JSON.parse(localStorage.getItem('encryptid_session') || ''); token = s.accessToken || ''; } catch {} try { const s = JSON.parse(localStorage.getItem('encryptid_session') || ''); token = s.accessToken || ''; } catch {}
return fetch(`${this.basePath}${path}`, { const { timeoutMs = 120_000, ...fetchOpts } = opts;
...opts, const controller = new AbortController();
headers: { const timer = setTimeout(() => controller.abort(), timeoutMs);
'Content-Type': 'application/json', try {
...(token ? { Authorization: `Bearer ${token}` } : {}), return await fetch(`${this.basePath}${path}`, {
...(opts.headers || {}), ...fetchOpts,
}, signal: controller.signal,
}); headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
...(fetchOpts.headers || {}),
},
});
} catch (e: any) {
if (e.name === 'AbortError') throw new Error('Request timed out — please try again');
throw e;
} finally {
clearTimeout(timer);
}
} }
private async loadWizard(): Promise<void> { private async loadWizard(): Promise<void> {

View File

@ -1521,7 +1521,7 @@ routes.post("/api/campaign/wizard/:id/content", async (c) => {
const { GoogleGenerativeAI } = await import("@google/generative-ai"); const { GoogleGenerativeAI } = await import("@google/generative-ai");
const genAI = new GoogleGenerativeAI(GEMINI_API_KEY); const genAI = new GoogleGenerativeAI(GEMINI_API_KEY);
const model = genAI.getGenerativeModel({ const model = genAI.getGenerativeModel({
model: "gemini-2.5-pro", model: "gemini-2.5-flash",
generationConfig: { responseMimeType: "application/json" } as any, generationConfig: { responseMimeType: "application/json" } as any,
}); });