File size: 5,373 Bytes
77932b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328ddd9
77932b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from openai import OpenAI
from dotenv import load_dotenv
import os 

# Try to load .env file if it exists (for local development)
load_dotenv()

# Initialize OpenAI client - will use OPENAI_API_KEY from environment
# For Hugging Face Spaces, set this as a secret in the Space settings
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
    raise ValueError("OPENAI_API_KEY not found. Please set it in your environment variables or Hugging Face Space secrets.")

client = OpenAI(api_key=api_key)

# File paths - adjust based on where the app runs
# For Hugging Face Spaces, files should be in the root or adjust paths accordingly
cv_path = "src/cv/me.txt" if os.path.exists("src/cv/me.txt") else "cv/me.txt"
avatar_path = "src/cv/avatar.jpeg" if os.path.exists("src/cv/avatar.jpeg") else "cv/avatar.jpeg"
projects_base = "src/projects_images" if os.path.exists("src/projects_images") else "projects_images"

projects = [
    {"image": f"{projects_base}/s_up.jpeg", "title": "Ai Recommendation System"},
    {"image": f"{projects_base}/llm.jpeg", "title": "LLM Automation"},
    {"image": f"{projects_base}/bi.png", "title": "BI"},
    {"image": f"{projects_base}/robot.png", "title": "Robot Arm Control With Ros Python and AI "},
]

with open(cv_path, "r") as f: 
    cv_text = f.read()

system_prompt = f"""
Your name is Alexander.You are acting as Alexander Todorov. You will answer questions related to your career, skills, work experience, and education. \
Questions will be asked by visitors, headhunters, or recruiters about potential job opportunities. \
Respond professionally and use professional language. \
Answer only questions that are directly related to your CV. If you do not find the answer in your CV, respond with: \
"I can only answer questions about my CV."

CV: {cv_text}
With this context, please chat with the user, always staying in character as Alexander Todorov.
"""

def chat(message, history):
    messages = [{"role":"system", "content":system_prompt}] + history + [{"role":"user", "content":message}]
    response = client.chat.completions.create(model="gpt-4o-mini", messages=messages)
    return response.choices[0].message.content


with gr.Blocks(scroll=True) as ui:
    # name and job title    
    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown('<div style="font-size:36px; font-weight:bold;">Alexander Todorov</div>')

        with gr.Column(scale=4):    
            gr.Markdown("""
            <a href="https://www.linkedin.com/in/alexander-t-50864a139" target="_blank">
                <img src="https://cdn-icons-png.flaticon.com/512/174/174857.png" 
                    alt="LinkedIn" style="width:32px; height:32px;"/>
            </a>
            """)

    # ********************************************************************************************************* 
    
    with gr.Row():
        with gr.Column(scale=1):  # 1 part
            gr.Image(avatar_path, 
                        type="pil", 
                        show_label=False, 
                        height=150, 
                        interactive=False, 
                        container=False, 
                        buttons=[['download', 'share', 'fullscreen']])

        # Right column 75% width
        with gr.Column(scale=3):  # 3 parts
            gr.Markdown("""
            <div style="width:50%">
            <p style="color:#9b9b9b;  margin-bottom:0;font-size:20px;">
            Software and Data Engineer with over five years of experience delivering intelligent, 
            user-focused AI solutions and driving automation and innovation in complex environments.
            </p>
            </div>
            """)
    

    # ******************************************************************************************************************
    # Chatbot 
    gr.Markdown(f'<p style="font-size:28px;font-weight:bold;"> Chat with Me About My CV</p>',
                    elem_id="job-title-light")
    gr.Markdown('<hr style="border:1px solid grey;">', elem_id="custom_divider")
    chatbot = gr.Chatbot(placeholder="<strong>Interactive CV Guide</strong><br>Ask Me Anything", height=300)
    chat_interface = gr.ChatInterface(fn=chat, chatbot=chatbot)
    gr.Markdown('<hr style="border: 1px solid #d3d3d3; margin-top:12px; margin-bottom:12px;">')
    
    # ****************************************************************************************************************
    # Projects 
    gr.Markdown(f'<p style="font-size:28px;font-weight:bold;"> Examples of My Work</p>',
                    elem_id="job-title-light")
    gr.Markdown('<hr style="border:1px solid grey;">', elem_id="custom_divider")
    
    # Projects row 
    with gr.Row():
        for project in projects:
            with gr.Column():  # equal width for each project
                # Project image
                gr.Image(project["image"], 
                            type="pil", 
                            show_label=False, 
                            interactive=False, 
                            height=200, width=350,
                            buttons=[['download', 'share', 'fullscreen']])
                # Project title / text
                gr.Markdown(f"<div style='text-align:center; font-size:16px; margin-top:4px;'>{project['title']}</div>")


if __name__ == "__main__":
    ui.launch()