# How `hiring-agent.py` Orchestrates the Workflow Between `github.py` and `evaluator.py`

> Discover how hiring-agent.py orchestrates GitHub info retrieval and resume evaluation, merging outputs for a unified candidate assessment.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: internals
- Published: 2026-07-15

---

**[`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) serves as the central entry point that sequences GitHub profile retrieval and résumé evaluation by calling `github.fetch_and_display_github_info()` followed by `ResumeEvaluator.evaluate_resume()`, then merges both outputs into a unified candidate assessment.**

The `interviewstreet/hiring-agent` repository implements an automated candidate screening pipeline that combines public portfolio analysis with structured résumé scoring. At the architectural center, [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) coordinates the end-to-end workflow by managing data flow between the GitHub data extraction module ([`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)) and the evaluation engine ([`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)). This orchestration ensures that candidate inputs are transformed into structured JSON outputs suitable for downstream processing or human review.

## The Core Orchestration Pattern

The orchestration follows a strict sequential pipeline where each module handles a distinct domain of candidate data. [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) acts as the glue code that invokes specialized functions, handles intermediate data structures, and assembles the final payload.

### Entry Point and Data Flow

The script begins by parsing command-line arguments to receive either a GitHub URL or a résumé file path. It then executes a three-phase workflow:

1. **GitHub Phase** – Calls `github.fetch_and_display_github_info(github_url)` to retrieve profile metadata and curated project lists
2. **Evaluation Phase** – Instantiates `ResumeEvaluator` from [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) and invokes `evaluate_resume(resume_text)` to generate structured scores
3. **Aggregation Phase** – Merges the GitHub dictionary and evaluation object into a single coherent result

This linear dependency ensures that GitHub data gathering completes before résumé evaluation begins, allowing the evaluator to optionally cross-reference repository information if needed.

## Step 1: GitHub Data Collection via [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)

The first major orchestration step delegates all GitHub-related operations to [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py). This module handles API authentication, username extraction, and LLM-powered repository curation.

### Profile Extraction and Repository Ranking

When [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) calls `github.fetch_and_display_github_info()`, the function executes several internal steps defined in [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py):

- Extracts the username via `github.extract_github_username(github_url)`
- Fetches raw API data using `github._fetch_github_api(username)`
- Initializes the LLM provider through `llm_utils.initialize_llm_provider()`
- Ranks repositories using an LLM prompt and selects the top 7 unique projects

The function returns a dictionary containing:

```python
{
    "profile": <profile-json>,
    "projects": <projects-json>,
    "total_projects": N
}

```

This curated dataset filters out noisy or low-impact repositories before the data reaches the main orchestrator.

## Step 2: Résumé Evaluation via [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)

Once GitHub data is secured, [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) transitions to résumé analysis by initializing the evaluation subsystem. The [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) module encapsulates all LLM prompting and structured output parsing required for consistent scoring.

### Structured Scoring with Pydantic Models

The orchestrator creates a `ResumeEvaluator` instance and passes the candidate's résumé text to `evaluate_resume()`:

```python
from evaluator import ResumeEvaluator

evaluator = ResumeEvaluator()
evaluation = evaluator.evaluate_resume(resume_text)

```

Under the hood, [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py):

- Loads the evaluation criteria template from `resume_evaluation_criteria.jinja`
- Sends the résumé content plus criteria to the LLM using the same provider abstraction as [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)
- Parses the JSON response into an `EvaluationData` Pydantic model

This structured approach ensures type-safe access to evaluation scores, summary text, and skill assessments.

## Step 3: Result Aggregation and Output

The final orchestration responsibility involves merging the two independent data streams. [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) combines the GitHub output dictionary with the evaluation object's serialized data:

```python
import json

github_url = "https://github.com/example_user"
resume_text = Path("resume.txt").read_text(encoding="utf-8")

# 1️⃣ Pull GitHub profile & top projects

github_data = github.fetch_and_display_github_info(github_url)

# 2️⃣ Evaluate the résumé

evaluator = ResumeEvaluator()
evaluation = evaluator.evaluate_resume(resume_text)

# 3️⃣ Combine the two halves

final_result = {
    "github": github_data,
    "resume_evaluation": evaluation.dict(),
}
print(json.dumps(final_result, indent=2, ensure_ascii=False))

```

As implemented in lines 84-89 of [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py), the script outputs a clearly marked "JSON DATA OUTPUT" block to stdout, making it easy for CI/CD pipelines or parent processes to capture the complete candidate assessment. The combined payload includes both the curated GitHub portfolio and the structured résumé evaluation, providing a holistic view of candidate qualifications.

## Summary

- **[`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py)** acts as the central workflow engine that sequences data collection and evaluation steps without implementing domain-specific logic itself.
- **[`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py)** handles the complete GitHub integration, from username extraction to LLM-based repository ranking, returning a filtered list of top projects.
- **[`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py)** provides the `ResumeEvaluator` class that applies consistent scoring criteria to résumé text via templated LLM prompts.
- The orchestrator merges outputs from both modules into a single JSON structure suitable for downstream processing or storage.
- Both modules share utility functions from [`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py) and template management from [`prompts/template_manager.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompts/template_manager.py) for consistent LLM interactions.

## Frequently Asked Questions

### What is the primary responsibility of [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) in the repository?

[`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) serves as the main entry point and workflow orchestrator that coordinates calls to [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) and [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py). It manages the sequential execution of GitHub data retrieval and résumé evaluation, then merges the results into a unified output format.

### How does [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) determine which repositories to include in the evaluation?

The module fetches all public repositories via the GitHub API, then uses an LLM initialized through `llm_utils.initialize_llm_provider()` to rank projects by impact and relevance. It selects the top 7 unique repositories and returns them in the `projects` field of the response dictionary.

### What data structure does the `evaluate_resume()` method return?

The method returns an `EvaluationData` object, which is a Pydantic model defined in [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py). This object provides structured access to evaluation scores, summary assessments, and skill categories, and can be serialized to JSON using the `.dict()` method.

### Can [`github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/github.py) or [`evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/evaluator.py) be used independently without [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py)?

Yes, both modules expose public APIs that can be imported directly. `github.fetch_and_display_github_info()` accepts a GitHub URL and returns profile data, while `ResumeEvaluator` can be instantiated and called with résumé text independently. However, using them separately requires manual handling of the result aggregation that [`hiring-agent.py`](https://github.com/interviewstreet/hiring-agent/blob/main/hiring-agent.py) normally performs.