Add curator resume handoff from interview evidence

This commit is contained in:
Sai-karthik
2026-06-20 08:50:32 +00:00
parent c66360cb7e
commit 9a6518a5d8
+107
View File
@@ -35,6 +35,94 @@ async function missionGoalHint(userId: string, task: CuratorTask) {
return conciseRoleHint(goal);
}
function asText(value: unknown): string | undefined {
if (typeof value === "string") {
const trimmed = value.trim();
return trimmed ? trimmed : undefined;
}
if (typeof value === "number" || typeof value === "boolean") {
return String(value);
}
return undefined;
}
function reviewField(payload: Record<string, unknown>, keys: string[]) {
for (const key of keys) {
const direct = asText(payload[key]);
if (direct) return direct;
}
const review = payload.review && typeof payload.review === "object" ? payload.review as Record<string, unknown> : undefined;
if (!review) return undefined;
for (const key of keys) {
const nested = asText(review[key]);
if (nested) return nested;
}
return undefined;
}
async function latestInterviewResumeEvidence(userId: string) {
const rows = await db.select({
id: growEvents.id,
type: growEvents.type,
source: growEvents.source,
payload: growEvents.payload,
occurredAt: growEvents.occurredAt,
}).from(growEvents)
.where(and(
eq(growEvents.userId, userId),
inArray(growEvents.type as any, [
"interview.review_completed",
"interview.completed",
"roleplay.review_completed",
"roleplay.completed",
]),
))
.orderBy(desc(growEvents.occurredAt))
.limit(5);
const latest = rows[0];
if (!latest) return null;
const payload = latest.payload ?? {};
const strongestAnswer = reviewField(payload, [
"strongest_answer",
"strongestAnswer",
"best_answer",
"bestAnswer",
"top_answer",
"topAnswer",
]);
const improvementArea = reviewField(payload, [
"improvement_area",
"improvementArea",
"biggest_gap",
"biggestGap",
"coaching_note",
"coachingNote",
]);
const summary = reviewField(payload, [
"summary",
"feedback_summary",
"feedbackSummary",
"overall_feedback",
"overallFeedback",
]);
const carryForward = [
summary ? `Review summary: ${summary}` : undefined,
strongestAnswer ? `Strongest answer to convert into proof: ${strongestAnswer}` : undefined,
improvementArea ? `Weakest area to repair in resume positioning: ${improvementArea}` : undefined,
].filter((item): item is string => Boolean(item));
return {
eventId: latest.id,
source: latest.source,
type: latest.type,
occurredAt: latest.occurredAt,
carryForward,
};
}
export async function prepareHandoffForTask(
userId: string,
task: CuratorTask,
@@ -303,6 +391,25 @@ export function buildCuratorTools(ctx: { userId: string; date: string; conversat
},
}),
prepare_resume_from_interview_evidence: tool({
description: "Prepare a resume handoff that carries forward recent interview or roleplay review evidence into the proof task.",
inputSchema: z.object({ taskId: z.string().optional() }),
execute: async ({ taskId }) => {
const task = await findTask(ctx.userId, taskId ?? ctx.taskId ?? "", ctx.date);
if (!task) return { error: "task_not_found" };
const handoff = await prepareHandoffForTask(ctx.userId, task, "resume-service");
const evidence = await latestInterviewResumeEvidence(ctx.userId);
return {
handoff,
carryForward: evidence?.carryForward ?? [],
sourceEventId: evidence?.eventId,
sourceEventType: evidence?.type,
sourceService: evidence?.source,
sourceOccurredAt: evidence?.occurredAt,
};
},
}),
prepare_roleplay_setup: tool({
description: "Prepare roleplay setup handoff.",
inputSchema: z.object({ taskId: z.string().optional() }),