-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added a candidates api that matches resumes to jobs (#131)
- Loading branch information
1 parent
5059f04
commit 6a1fe09
Showing
5 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use client'; | ||
|
||
export default function Home({ children }) { | ||
return <>{children}</>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import React from 'react'; | ||
|
||
const JobList = () => { | ||
return <div className="flex flex-col gap-5">List of jobs</div>; | ||
}; | ||
|
||
export default JobList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const { createClient } = require('@supabase/supabase-js'); | ||
|
||
const supabaseUrl = 'https://itxuhvvwryeuzuyihpkp.supabase.co'; | ||
const supabaseKey = process.env.SUPABASE_KEY; | ||
const supabase = createClient(supabaseUrl, supabaseKey); | ||
|
||
if (!process.env.OPENAI_API_KEY) { | ||
throw new Error('Missing env var from OpenAI'); | ||
} | ||
|
||
// This API route is used to match candidates to a job | ||
|
||
export default async function handler(req, res) { | ||
const jobId = 40224903; | ||
|
||
const { data } = await supabase.from('jobs').select().eq('uuid', jobId); | ||
|
||
const jdEmbedding = data[0].embedding_v5; | ||
|
||
const { data: documents } = await supabase.rpc('match_resumes_v5', { | ||
query_embedding: jdEmbedding, | ||
match_threshold: 0.14, // Choose an appropriate threshold for your data | ||
match_count: 40, // Choose the number of matches | ||
}); | ||
|
||
return res.status(200).send(documents); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
require('dotenv').config({ path: __dirname + '/./../../.env' }); | ||
|
||
const { createClient } = require('@supabase/supabase-js'); | ||
const OpenAI = require('openai'); | ||
|
||
const supabaseUrl = 'https://itxuhvvwryeuzuyihpkp.supabase.co'; | ||
const supabaseKey = process.env.SUPABASE_KEY; | ||
const supabase = createClient(supabaseUrl, supabaseKey); | ||
const openai = new OpenAI({ | ||
apiKey: process.env.OPENAI_API_KEY, | ||
}); | ||
|
||
async function sleep(ms) { | ||
return new Promise((resolve) => setTimeout(resolve, ms)); | ||
} | ||
|
||
async function main() { | ||
const { data, error } = await supabase | ||
.from('resumes') | ||
.select('id::text, username, resume, embedding') | ||
.is('embedding', null); | ||
// .limit(300); | ||
console.log({ data, error }); | ||
|
||
for (let i = 0; i < data.length; i++) { | ||
const resume = data[i]; | ||
if (!resume.embedding) { | ||
console.log('Create embedding for'); | ||
console.log('Username:', resume.username); | ||
console.log('ID:', resume.id); | ||
|
||
const completion1 = await openai.embeddings.create({ | ||
model: 'text-embedding-3-large', | ||
input: resume.resume.substr(0, 8192), | ||
}); | ||
console.log('Embedding done'); | ||
|
||
const desiredLength = 3072; | ||
|
||
let embedding = completion1.data[0].embedding; | ||
|
||
if (embedding.length < desiredLength) { | ||
embedding = embedding.concat( | ||
Array(desiredLength - embedding.length).fill(0) | ||
); | ||
} | ||
|
||
console.log('Embedding to be saved:', embedding); | ||
|
||
try { | ||
console.log('Saving embedding for ID:', resume.id); | ||
|
||
const updateResponse = await supabase | ||
.from('resumes') | ||
.update({ embedding }) | ||
.eq('id', resume.id); | ||
|
||
console.log('Update response:', updateResponse); | ||
|
||
if (updateResponse.error) { | ||
console.log('Error updating embedding:', updateResponse.error); | ||
} else { | ||
console.log('Embedding updated successfully:', updateResponse.data); | ||
} | ||
|
||
await sleep(2000); // Sleep for 2 seconds | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
} | ||
} | ||
} | ||
|
||
main(); |