66 lines
1.5 KiB
TypeScript
66 lines
1.5 KiB
TypeScript
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");
|
|
}
|