import os import yaml import gradio as gr from dotenv import load_dotenv from agno.agent import Agent from agno.models.nebius import Nebius from agno.tools.github import GithubTools from agno.tools.exa import ExaTools from agno.tools.thinking import ThinkingTools from agno.tools.reasoning import ReasoningTools # Load environment variables from .env if present load_dotenv() # Load prompts from YAML file with open("hiring_prompts.yaml", "r", encoding="utf-8") as f: prompts = yaml.safe_load(f) # Extract prompt sections description_multi = prompts.get("description_for_multi_candidates", "") instructions_multi = prompts.get("instructions_for_multi_candidates", "") description_single = prompts.get("description_for_single_candidate", "") instructions_single = prompts.get("instructions_for_single_candidate", "") def analyze_multi(github_usernames, job_role, nebius_api_key, model_id, github_api_key, exa_api_key): """ Analyze multiple GitHub users for a given job role. github_usernames: string with newline separated usernames. Returns a markdown report. """ if not github_usernames or not job_role: return "Please provide GitHub usernames and job role." usernames = [u.strip() for u in github_usernames.split("\n") if u.strip()] if not usernames: return "No valid GitHub usernames found." query = f"Evaluate GitHub candidates for role '{job_role}': {', '.join(usernames)}" agent = Agent( description=description_multi, instructions=instructions_multi, model=Nebius(id=model_id, api_key=nebius_api_key), name="CandilyzerMulti", tools=[ ThinkingTools(think=True, instructions="Strict GitHub candidate evaluation"), GithubTools(access_token=github_api_key), ExaTools(api_key=exa_api_key, include_domains=["github.com"], type="keyword"), ReasoningTools(add_instructions=True), ], markdown=True, show_tool_calls=True, ) stream = agent.run(query, stream=True) output = "" for chunk in stream: if hasattr(chunk, "content") and isinstance(chunk.content, str): output += chunk.content return output def analyze_single(github_username, linkedin_url, job_role, nebius_api_key, model_id, github_api_key, exa_api_key): """ Analyze a single GitHub (and optional LinkedIn) candidate for a given job role. """ if not github_username or not job_role: return "Please provide GitHub username and job role." query = f"Analyze candidate for {job_role}. GitHub: {github_username}" if linkedin_url: query += f", LinkedIn: {linkedin_url}" agent = Agent( description=description_single, instructions=instructions_single, model=Nebius(id=model_id, api_key=nebius_api_key), name="CandilyzerSingle", tools=[ ThinkingTools(add_instructions=True), GithubTools(access_token=github_api_key), ExaTools(api_key=exa_api_key, include_domains=["linkedin.com", "github.com"], type="keyword"), ReasoningTools(add_instructions=True), ], markdown=True, show_tool_calls=True, add_datetime_to_instructions=True, ) stream = agent.run(query, stream=True) output = "" for chunk in stream: if hasattr(chunk, "content") and isinstance(chunk.content, str): output += chunk.content return output with gr.Blocks() as demo: gr.Markdown("# Candilyzer\nAI Candidate Analyzer using Agno and Nebius AI") with gr.Tab("Multi-Candidate Analyzer"): github_usernames = gr.Textbox(label="GitHub Usernames (one per line)", lines=4, placeholder="username1\nusername2\n...") job_role = gr.Textbox(label="Job Role", placeholder="Backend Engineer") nebius_api_key = gr.Textbox(label="Nebius API Key", type="password") model_id = gr.Textbox(label="Model ID", placeholder="meta-llama/Llama-3-70B-Instruct") github_api_key = gr.Textbox(label="GitHub API Key", type="password") exa_api_key = gr.Textbox(label="Exa API Key", type="password") multi_button = gr.Button("Analyze Candidates") multi_output = gr.Markdown() multi_button.click(analyze_multi, inputs=[github_usernames, job_role, nebius_api_key, model_id, github_api_key, exa_api_key], outputs=multi_output) with gr.Tab("Single Candidate Analyzer"): github_username = gr.Textbox(label="GitHub Username", placeholder="username") linkedin_url = gr.Textbox(label="LinkedIn Profile (optional)", placeholder="https://linkedin.com/in/...") job_role2 = gr.Textbox(label="Job Role", placeholder="ML Engineer") nebius_api_key2 = gr.Textbox(label="Nebius API Key", type="password") model_id2 = gr.Textbox(label="Model ID", placeholder="meta-llama/Llama-3-70B-Instruct") github_api_key2 = gr.Textbox(label="GitHub API Key", type="password") exa_api_key2 = gr.Textbox(label="Exa API Key", type="password") single_button = gr.Button("Analyze Candidate") single_output = gr.Markdown() single_button.click(analyze_single, inputs=[github_username, linkedin_url, job_role2, nebius_api_key2, model_id2, github_api_key2, exa_api_key2], outputs=single_output) demo.launch()