Spaces:
Configuration error
Configuration error
File size: 5,841 Bytes
91b2483 aa26954 91b2483 edc4b6c aa26954 b888581 aa26954 b888581 aa26954 91b2483 f9a80bc 91b2483 aa26954 91b2483 aa26954 91b2483 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 b9464fb b888581 7482626 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 b888581 aa26954 91b2483 aa26954 b9464fb aa26954 b9464fb aa26954 edc4b6c aa26954 91b2483 aa26954 b9464fb aa26954 b9464fb aa26954 b9464fb aa26954 b9464fb aa26954 b888581 b9464fb b888581 b9464fb b888581 b9464fb b888581 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
'''Agent responsible for writing the resume based on user provided context'''
import ast
import json
import logging
import os
from openai import OpenAI
from configuration import (
INFERENCE_URL,
WRITER_INSTRUCTIONS,
WRITER_MODEL,
REPO_SELECTION_PROMPT,
PROJECTS_SECTION_PROMPT
)
# pylint: disable=broad-exception-caught
def write_resume(linkedin_resume: dict, github_repositories: list, job_call: dict) -> str:
"""
Generates a resume based on the provided content.
Args:
linkedin_resume (dict): Resume content extracted from linkedin profile.
github_repositories (dict): Information about the applicants GitHub repositories.
job_summary (dict): Extracted/summarized job call information.
Returns:
str: The generated resume.
"""
logger = logging.getLogger(f'{__name__}.write_resume')
logger.info("Selecting relevant GitHub repositories based on job call")
project_repos = _choose_repositories(github_repositories, job_call)
logger.info("Writing projects section of the resume")
projects = _write_projects_section(project_repos, job_call)
# Let the model select the most relevant repositories based on the job call
client = OpenAI(
base_url=INFERENCE_URL,
api_key=os.environ.get("API_KEY", "dummy-key-for-testing")
)
prompt = f'JOB CALL\n{job_call}\nLINKEDIN RESUME\n{linkedin_resume}\nPROJECTS\n{projects}'
messages = [
{
'role': 'system',
'content': WRITER_INSTRUCTIONS
},
{
'role': 'user',
'content': prompt
}
]
completion_args = {
'model': WRITER_MODEL,
'messages': messages,
}
try:
response = client.chat.completions.create(**completion_args)
except Exception as e:
response = None
logger.error('Error during job summarization API call: %s', e)
if response is not None:
response = response.choices[0].message.content
# Create data directory if it doesn't exist
data_dir = 'data'
if not os.path.exists(data_dir):
os.makedirs(data_dir)
logger.info("Created data directory: %s", data_dir)
# Save the resume to resume.md in the data directory
resume_file_path = os.path.join(data_dir, 'resume.md')
try:
with open(resume_file_path, 'w', encoding='utf-8') as f:
f.write(response)
logger.info("Resume saved to: %s", resume_file_path)
except Exception as e:
logger.error("Failed to save resume to file: %s", e)
return response
def _choose_repositories(github_repositories: list, job_call: dict) -> list:
"""
Choose relevant GitHub repositories based on the job call requirements.
Args:
github_repositories (dict): Information about the applicants GitHub repositories.
job_call (dict): Extracted/summarized job call information.
Returns:
list: Filtered list of relevant repositories.
"""
logger = logging.getLogger(f'{__name__}._choose_repositories')
# Create a new repo list without the full README text - this way we can save on input tokens
# by only sending the model the repo metadata, title, description, topics, etc.
repo_data = [
{k: v for k, v in d.items() if k != 'readme'}
for d in github_repositories
]
# Let the model select the most relevant repositories based on the job call
client = OpenAI(
base_url=INFERENCE_URL,
api_key=os.environ.get("API_KEY", "dummy-key-for-testing")
)
messages = [
{
'role': 'system',
'content': f'{REPO_SELECTION_PROMPT}'
},
{
'role': 'user',
'content': f'JOB CALL\n{json.dumps(job_call)}\n\nREPOSITORIES\n{json.dumps(repo_data)}'
}
]
completion_args = {
'model': WRITER_MODEL,
'messages': messages,
}
try:
response = client.chat.completions.create(**completion_args)
except Exception as e:
response = None
logger.error('Error during job summarization API call: %s', e)
if response is not None:
response = response.choices[0].message.content
response = ast.literal_eval(response)
# Now use the repository selection response to filter the repositories
selected_repos = [
repo for repo in github_repositories if repo['name'] in response
]
return selected_repos
def _write_projects_section(project_repos: list, job_call: dict) -> str:
"""
Write the projects section of the resume based on selected GitHub repositories.
Args:
project_repos (list): List of relevant GitHub repositories.
job_call (dict): Extracted/summarized job call information.
Returns:
str: Formatted projects section for the resume.
"""
logger = logging.getLogger(f'{__name__}._write_projects_section')
# Let the model select the most relevant repositories based on the job call
client = OpenAI(
base_url=INFERENCE_URL,
api_key=os.environ.get("API_KEY", "dummy-key-for-testing")
)
messages = [
{
'role': 'system',
'content': f'{PROJECTS_SECTION_PROMPT}'
},
{
'role': 'user',
'content': f'JOB CALL\n{json.dumps(job_call)}\n\nREPOSITORIES\n{json.dumps(project_repos)}'
}
]
completion_args = {
'model': WRITER_MODEL,
'messages': messages,
}
try:
response = client.chat.completions.create(**completion_args)
except Exception as e:
response = None
logger.error('Error during job summarization API call: %s', e)
if response is not None:
response = response.choices[0].message.content
return response |