Tighten curator mission generation

This commit is contained in:
Sai-karthik
2026-06-17 13:05:54 +00:00
parent c46b9b11f6
commit 1d887bc153
2 changed files with 12 additions and 113 deletions
+8 -68
View File
@@ -346,73 +346,7 @@ function formatTask(task: DailyMissionTask) {
return lines.map((line) => `- ${line}`).join("\n");
}
function fallbackDailyMissionResponse(input: { task: DailyMissionTask; messages: DailyMissionMessage[] }) {
const latestUser = [...input.messages].reverse().find((message) => message.role === "user")?.content.trim() ?? "";
const userMessagesAfterStart = input.messages.filter((message) => message.role === "user");
const interviewMission = isInterviewMission(input.task);
if (latestUser.toLowerCase() === "start") {
const serviceReply = serviceStartReply(input.task);
if (serviceReply) {
return {
reply: serviceReply,
completed: false,
updateSummary: undefined,
actionLabel: undefined,
actionRoute: undefined,
};
}
if (isConfidenceCheck(input.task)) {
return {
reply: "Quick confidence check: on a scale of 1 to 10, how confident do you feel about getting interview-ready for your target role this week?",
completed: false,
updateSummary: undefined,
actionLabel: undefined,
actionRoute: undefined,
};
}
if (interviewMission) {
return {
reply: `Let us get your interview room ready. For "${input.task.subtask}", tell me the role you want to practice for and the kind of question you want first.`,
completed: false,
updateSummary: undefined,
actionLabel: undefined,
actionRoute: undefined,
};
}
return {
reply: `Alright, I have this one. For "${input.task.subtask}", tell me your answer in one or two lines. I will use it to update this task here.`,
completed: false,
updateSummary: undefined,
actionLabel: undefined,
actionRoute: undefined,
};
}
const updateSummary = compactAnswer(latestUser);
const completed = userMessagesAfterStart.some((message) => message.content.trim().toLowerCase() === "start") && latestUser.length > 0;
if (interviewMission) {
return {
reply: `Perfect. I will carry this into the interview room setup: ${updateSummary}. Your interview room link is ready.`,
completed,
updateSummary,
actionLabel: completed ? "Generate room" : undefined,
actionRoute: completed ? getInterviewActionRoute(input.task) : undefined,
};
}
return {
reply: `Nice, saved. I updated this task with: ${updateSummary}`,
completed,
updateSummary,
actionLabel: undefined,
actionRoute: undefined,
};
}
export async function runDailyMissionAgent(input: DailyMissionAgentInput) {
const started = input.messages.some(
@@ -453,8 +387,14 @@ ${transcript}`,
return withDailyMissionActionDefaults(input.task, parseDailyMissionResponse(result.text));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.warn("daily mission model failed; using fallback", { message });
return fallbackDailyMissionResponse({ task: input.task, messages: input.messages });
console.warn("daily mission model failed; returning unavailable state", { message });
return {
reply: "Daily mission is temporarily unavailable right now. No progress was saved. Please retry in a moment.",
completed: false,
updateSummary: undefined,
actionLabel: undefined,
actionRoute: undefined,
};
}
}
+4 -45
View File
@@ -219,13 +219,13 @@ async function taskFromStage(input: {
{ label: "Mission", value: input.missionTitle },
{ label: "Current focus", value: copy.title },
{ label: "Service handoff", value: serviceName(serviceId, input.role) },
{ label: "Source", value: input.missionInstanceId ? "Active mission" : "Mission registry" },
{ label: "Source", value: "Active mission" },
],
contextNarrative: copy.contextNarrative,
subtasks: copy.subtasks,
signals: [input.missionTitle, input.stageTitle, serviceName(serviceId, input.role)],
completionEvents: completionEventsForService(serviceId),
source: input.missionInstanceId ? "curator-v1" : "mission-registry",
source: "curator-v1",
};
}
@@ -291,49 +291,8 @@ export async function buildCuratorTasks(userId: string, date = todayIso()): Prom
if (tasks.length >= 3) break;
}
if (tasks.length < 3) {
const registryModules = listMissionDefinitions().flatMap((mission) =>
mission.modules.map((module) => ({ mission, module, serviceId: serviceFromRole(module.role, module.service) })),
).filter((item) => item.serviceId !== "qscore-service");
const seenServices = new Set(tasks.map((task) => task.serviceId).filter(Boolean));
for (const item of registryModules) {
if (tasks.length >= 3) break;
if (!item.serviceId) continue;
if (item.serviceId && seenServices.has(item.serviceId)) continue;
if (tasks.some((task) => task.missionId === item.mission.missionId && task.stageId === item.module.id)) continue;
tasks.push(await taskFromStage({
userId,
date,
index: tasks.length,
missionId: item.mission.missionId,
missionTitle: item.mission.shortTitle || item.mission.title,
stageId: item.module.id,
stageTitle: item.module.title,
stageDescription: item.module.description ?? item.mission.promise,
role: item.module.role,
serviceId: item.serviceId,
}));
if (item.serviceId) seenServices.add(item.serviceId);
}
for (const item of registryModules) {
if (tasks.length >= 3) break;
if (tasks.some((task) => task.missionId === item.mission.missionId && task.stageId === item.module.id)) continue;
tasks.push(await taskFromStage({
userId,
date,
index: tasks.length,
missionId: item.mission.missionId,
missionTitle: item.mission.shortTitle || item.mission.title,
stageId: item.module.id,
stageTitle: item.module.title,
stageDescription: item.module.description ?? item.mission.promise,
role: item.module.role,
serviceId: item.serviceId,
}));
}
}
// Only surface tasks backed by real active missions for this user.
// Do not pad the dashboard with registry-only missions or demo task fallbacks.
const enriched: CuratorTask[] = [];
for (const task of tasks.slice(0, 3)) {