scaffold: Next.js 15 + Drizzle + Better Auth + OpenAI + Recharts base

This commit is contained in:
Christopher Mayor
2026-04-24 14:29:47 -07:00
parent 858f7264ce
commit d13780931e
45 changed files with 9036 additions and 121 deletions

65
src/lib/llm/index.ts Normal file
View File

@@ -0,0 +1,65 @@
import type {
ComparisonRequest,
ComparisonResult,
ResearchProgress,
} from "./types";
import { generateComparison } from "./providers/openai";
export type {
ComparisonRequest,
ComparisonResult,
ResearchProgress,
} from "./types";
export async function* runResearch(
request: ComparisonRequest
): AsyncGenerator<ResearchProgress> {
yield { stage: "parsing", message: "Analyzing comparison request..." };
if (!request.items || request.items.length < 2) {
yield {
stage: "error",
error: "At least 2 items are required for comparison",
};
return;
}
for (let i = 0; i < request.items.length; i++) {
yield {
stage: "researching",
item: request.items[i],
progress: Math.round(((i + 0.5) / request.items.length) * 80),
};
}
yield {
stage: "synthesizing",
message: "Synthesizing research into structured comparison...",
};
try {
const result = await generateComparison(request);
yield { stage: "complete", result };
} catch (error) {
yield {
stage: "error",
error:
error instanceof Error ? error.message : "Research failed unexpectedly",
};
}
}
export async function executeResearch(
request: ComparisonRequest
): Promise<ComparisonResult> {
for await (const progress of runResearch(request)) {
if (progress.stage === "complete") {
return progress.result;
}
if (progress.stage === "error") {
throw new Error(progress.error);
}
}
throw new Error("Research completed without producing a result");
}