Files
2026-08-16 14:58:47 +08:00

89 lines
2.4 KiB
TypeScript

/**
* PBL v2 — Evaluation helpers.
*
* Evaluation records produced by `record_closing_check` (task-level)
* and by the standalone evaluator runs (milestone / final, PR 6 / 7).
* PR 3 only needs the helper to write a task-level evaluation when
* `advance_micro_task` is called; richer evaluations come in
* later PRs.
*/
import type {
PBLEvaluation,
PBLEvaluationKind,
PBLProjectV2,
PBLScenarioActGoals,
} from '../../types';
import {
appendRuntimeEvent,
milestoneIdForMicrotask,
mintRuntimeEventId,
} from '../kernel/runtime-events';
function newId(prefix: string): string {
return (
prefix + '_' + Math.random().toString(16).slice(2, 8) + Math.random().toString(16).slice(2, 8)
);
}
export function addEvaluation(
project: PBLProjectV2,
args: {
kind: PBLEvaluationKind;
microtaskId?: string;
milestoneId?: string;
feedback: string;
strengths?: string[];
improvements?: string[];
score?: number;
stars?: number;
whatYouBuilt?: string[];
whatYouLearned?: string[];
whatsNext?: string;
actGoals?: PBLScenarioActGoals[];
},
): PBLEvaluation {
const evaluation: PBLEvaluation = {
id: newId('eval'),
kind: args.kind,
microtaskId: args.microtaskId,
milestoneId: args.milestoneId,
feedback: args.feedback,
strengths: args.strengths ?? [],
improvements: args.improvements ?? [],
score: args.score,
stars: args.stars,
whatYouBuilt: args.whatYouBuilt,
whatYouLearned: args.whatYouLearned,
whatsNext: args.whatsNext,
actGoals: args.actGoals,
createdAt: new Date().toISOString(),
};
project.evaluations.push(evaluation);
appendRuntimeEvent(project, {
id: mintRuntimeEventId(),
kind: 'evaluation_created',
actorType: 'system',
evaluationId: evaluation.id,
ts: evaluation.createdAt,
microtaskId: evaluation.microtaskId,
milestoneId: evaluation.milestoneId ?? milestoneIdForMicrotask(project, evaluation.microtaskId),
});
project.updatedAt = evaluation.createdAt;
return evaluation;
}
export function listEvaluationsForMicrotask(
project: PBLProjectV2,
microtaskId: string,
): PBLEvaluation[] {
return project.evaluations.filter((e) => e.microtaskId === microtaskId);
}
export function listEvaluationsForMilestone(
project: PBLProjectV2,
milestoneId: string,
): PBLEvaluation[] {
return project.evaluations.filter((e) => e.milestoneId === milestoneId);
}