mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-19 21:11:45 +10:00
fix(ai): provide current date to resume analysis (#3353)
This commit is contained in:
@@ -47,6 +47,7 @@ Do not include markdown, comments, or additional keys.
|
||||
4. Never invent candidate achievements or facts.
|
||||
5. If data is missing, call it out explicitly in rationale/suggestions.
|
||||
6. Keep scorecard dimensions practical and common for resume review.
|
||||
7. Use the current date from the analysis context for chronology checks. Do not flag a date on or before that date as future-dated.
|
||||
|
||||
## Suggestions Requirements
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { UIMessage } from "ai";
|
||||
import type { ResumeData } from "@reactive-resume/schema/resume/data";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { convertToModelMessages, modelMessageSchema } from "ai";
|
||||
|
||||
@@ -10,6 +11,7 @@ vi.mock("@reactive-resume/env/server", () => ({ env: envMock }));
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
function stubOpenAICompatibleResponse(response?: { content?: string; finishReason?: string }) {
|
||||
@@ -67,7 +69,7 @@ function stubRejectedFetch(error: unknown) {
|
||||
return fetchMock;
|
||||
}
|
||||
|
||||
const { testConnection } = await import("./service");
|
||||
const { analyzeResume, testConnection } = await import("./service");
|
||||
|
||||
describe("AI provider connection test", () => {
|
||||
it("names the rejected key instead of reporting a transport failure", async () => {
|
||||
@@ -168,6 +170,26 @@ describe("AI provider connection test", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("AI resume analysis", () => {
|
||||
it("gives the model the actual current date for chronology checks", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-08-18T12:00:00Z"));
|
||||
|
||||
const response = stubOpenAICompatibleResponse({
|
||||
content: JSON.stringify({
|
||||
overallScore: 80,
|
||||
scorecard: [{ dimension: "Clarity", score: 80, rationale: "Clear." }],
|
||||
suggestions: [],
|
||||
strengths: ["Clear experience."],
|
||||
}),
|
||||
});
|
||||
|
||||
await analyzeResume({ ...testInput(), resumeData: {} as ResumeData });
|
||||
|
||||
expect(JSON.stringify(response.getRequestBody())).toContain("Current date: 2026-08-18");
|
||||
});
|
||||
});
|
||||
|
||||
describe("AI chat service", () => {
|
||||
it("tests OpenAI-compatible providers without requiring structured output", async () => {
|
||||
const openAiCompatible = stubOpenAICompatibleResponse();
|
||||
|
||||
@@ -509,8 +509,9 @@ type AnalyzeResumeInput = z.infer<typeof aiCredentialsSchema> & {
|
||||
resumeData: ResumeData;
|
||||
};
|
||||
|
||||
function buildAnalyzeResumeSystemPrompt(resumeData: ResumeData): string {
|
||||
return `${analyzeResumeSystemPromptTemplate}\n\n## Resume Data\n\n${JSON.stringify(resumeData, null, 2)}`;
|
||||
function buildAnalyzeResumeSystemPrompt(resumeData: ResumeData, now = new Date()): string {
|
||||
const currentDate = now.toISOString().slice(0, 10);
|
||||
return `${analyzeResumeSystemPromptTemplate}\n\n## Analysis Context\n\nCurrent date: ${currentDate} (UTC). Treat dates on or before this date as not future-dated. Flag a date as future-dated only when it is after the current date.\n\n## Resume Data\n\n${JSON.stringify(resumeData, null, 2)}`;
|
||||
}
|
||||
|
||||
/** Sends resume data to the AI provider and returns a structured analysis, parsing raw JSON from the response text. */
|
||||
|
||||
Reference in New Issue
Block a user