file saved as name
This commit is contained in:
parent
585e5e19e0
commit
b914026d8b
@ -419,17 +419,18 @@ async function main(): Promise<void> {
|
||||
try {
|
||||
response = await fetchPage(pageNo, authSession, { searchKeyword });
|
||||
} catch (error) {
|
||||
if (error instanceof UkVisaJobsAuthError) {
|
||||
if (!credentials) {
|
||||
if (!credentials) {
|
||||
if (error instanceof UkVisaJobsAuthError) {
|
||||
throw new Error('UKVisaJobs auth expired. Set UKVISAJOBS_EMAIL and UKVISAJOBS_PASSWORD to refresh.');
|
||||
}
|
||||
console.log(' Auth expired. Refreshing tokens...');
|
||||
authSession = await loginWithBrowser(credentials.email, credentials.password);
|
||||
await saveCachedAuthSession(authSession);
|
||||
response = await fetchPage(pageNo, authSession, { searchKeyword });
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const reason = error instanceof UkVisaJobsAuthError ? 'Auth expired.' : 'Fetch failed.';
|
||||
console.log(` ${reason} Refreshing tokens and retrying...`);
|
||||
authSession = await loginWithBrowser(credentials.email, credentials.password);
|
||||
await saveCachedAuthSession(authSession);
|
||||
response = await fetchPage(pageNo, authSession, { searchKeyword });
|
||||
}
|
||||
|
||||
if (response.status !== 1) {
|
||||
|
||||
@ -207,7 +207,7 @@ export const JobCard: React.FC<JobCardProps> = ({
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<a
|
||||
href={pdfHref}
|
||||
download={`resume_${safeFilenamePart(job.employer)}_${safeFilenamePart(job.title)}.pdf`}
|
||||
download={`Shaheer_Sarfaraz_${safeFilenamePart(job.employer)}.pdf`}
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Download
|
||||
|
||||
@ -323,7 +323,7 @@ export const JobTable: React.FC<JobTableProps> = ({
|
||||
<DropdownMenuItem asChild>
|
||||
<a
|
||||
href={pdfHref}
|
||||
download={`resume_${safeFilenamePart(job.employer)}_${safeFilenamePart(job.title)}.pdf`}
|
||||
download={`Shaheer_Sarfaraz_${safeFilenamePart(job.employer)}.pdf`}
|
||||
>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Download PDF
|
||||
|
||||
@ -176,6 +176,8 @@ const formatDateTime = (dateStr: string | null) => {
|
||||
}
|
||||
};
|
||||
|
||||
const safeFilenamePart = (value: string) => value.replace(/[^a-z0-9]/gi, "_");
|
||||
|
||||
const dateValue = (value: string | null) => {
|
||||
if (!value) return null;
|
||||
const parsed = Date.parse(value);
|
||||
@ -962,7 +964,10 @@ export const OrchestratorPage: React.FC = () => {
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
<DropdownMenuItem asChild>
|
||||
<a href={selectedPdfHref} download={`resume_${selectedJob.id}.pdf`}>
|
||||
<a
|
||||
href={selectedPdfHref}
|
||||
download={`Shaheer_Sarfaraz_${safeFilenamePart(selectedJob.employer)}.pdf`}
|
||||
>
|
||||
<FileText className="mr-2 h-4 w-4" />
|
||||
Download PDF
|
||||
</a>
|
||||
|
||||
@ -56,8 +56,8 @@ export async function scoreJobSuitability(
|
||||
if (!content) {
|
||||
throw new Error('No content in response');
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(content);
|
||||
|
||||
const parsed = parseJsonFromContent(content);
|
||||
return {
|
||||
score: Math.min(100, Math.max(0, parsed.score || 0)),
|
||||
reason: parsed.reason || 'No explanation provided',
|
||||
@ -68,6 +68,24 @@ export async function scoreJobSuitability(
|
||||
}
|
||||
}
|
||||
|
||||
function parseJsonFromContent(content: string): { score?: number; reason?: string } {
|
||||
const trimmed = content.trim();
|
||||
const withoutFences = trimmed.replace(/```(?:json)?\s*|```/gi, '').trim();
|
||||
const candidate = withoutFences;
|
||||
|
||||
try {
|
||||
return JSON.parse(candidate);
|
||||
} catch {
|
||||
const firstBrace = candidate.indexOf('{');
|
||||
const lastBrace = candidate.lastIndexOf('}');
|
||||
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
|
||||
const sliced = candidate.slice(firstBrace, lastBrace + 1);
|
||||
return JSON.parse(sliced);
|
||||
}
|
||||
throw new Error('Unable to parse JSON from model response');
|
||||
}
|
||||
}
|
||||
|
||||
function buildScoringPrompt(job: Job, profile: Record<string, unknown>): string {
|
||||
return `
|
||||
You are evaluating a job listing for a candidate. Score how suitable this job is for the candidate on a scale of 0-100.
|
||||
@ -93,7 +111,7 @@ Disciplines: ${job.disciplines || 'Not specified'}
|
||||
Job Description:
|
||||
${job.jobDescription || 'No description available'}
|
||||
|
||||
Respond with JSON: { "score": <0-100>, "reason": "<brief explanation>" }
|
||||
Respond with JSON only (no code fences): { "score": <0-100>, "reason": "<brief explanation>" }
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user