# mani568347/morning-job-agent architecture

> Architecture diagram of the GitHub repository mani568347/morning-job-agent, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mani568347/morning-job-agent
- Repository: https://github.com/mani568347/morning-job-agent

## Overview

Morning Job Agent automates a daily job-search workflow: load saved searches and resume data, enforce the request budget, fetch listings, remove duplicates and stale postings, score and rank matches, draft letters for the best matches, and write a dated report. Its main internal layers are pipeline orchestration, Gemini-backed matching, and file-based configuration and state. The README documents scheduled GitHub Actions runs and commits; the sampled source does not include the workflow file, so those links reflect documented behavior rather than inspected workflow code.

Main entry points: [`src/morning_job_agent/pipeline.py`](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/pipeline.py) (Search pipeline), [`src/morning_job_agent/config.py`](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/config.py) (Config and stores), [`src/morning_job_agent/scoring.py`](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/scoring.py) (Scoring and letters), [`.github/workflows/daily.yml`](https://github.com/mani568347/morning-job-agent/blob/main/.github/workflows/daily.yml) (Actions workflow)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_orchestration["Run orchestration"]
  node_workflow["Actions workflow<br/>[daily.yml]"]
  node_entry["Module entry point<br/>[__main__.py]"]
  node_pipeline["Search pipeline<br/>[pipeline.py]"]
end

subgraph group_matching["Job matching"]
  node_models["Domain models<br/>[models.py]"]
  node_resume_parser["Resume parser<br/>[parse_resume.py]"]
  node_jsearch_client["JSearch client<br/>[jsearch.py]"]
  node_dedupe["Deduplication<br/>[dedupe.py]"]
  node_scoring["Scoring and letters<br/>[scoring.py]"]
  node_report["Report renderer<br/>[report.py]"]
end

subgraph group_state["Files and reports"]
  node_config["Config and stores<br/>[config.py]"]
  node_queries["Saved queries<br/>[queries.yaml]"]
  node_resume_data["Resume profile<br/>[resume.json]"]
  node_seen_data["Seen-job state<br/>[seen.json]"]
  node_usage_data["Request counter<br/>[usage.json]"]
  node_report_files["Daily reports"]
end

subgraph group_integrations["External services"]
  node_jsearch_api["JSearch API"]
  node_gemini["Gemini models"]
end

node_schedule(("Daily scheduler"))

node_schedule -->|"triggers"| node_workflow
node_workflow -->|"runs"| node_entry
node_entry -->|"calls"| node_pipeline
node_pipeline -->|"loads settings"| node_config
node_config -->|"reads"| node_queries
node_config -->|"reads"| node_resume_data
node_config -->|"reads"| node_seen_data
node_config -->|"reads"| node_usage_data
node_pipeline -->|"fetches listings"| node_jsearch_client
node_jsearch_client -->|"requests jobs"| node_jsearch_api
node_jsearch_api -->|"returns listings"| node_jsearch_client
node_pipeline -->|"filters jobs"| node_dedupe
node_pipeline -->|"scores fresh jobs"| node_scoring
node_resume_data -->|"provides profile"| node_scoring
node_scoring -->|"sends prompts"| node_gemini
node_gemini -->|"returns results"| node_scoring
node_scoring -->|"returns shortlist"| node_pipeline
node_scoring -->|"validates outputs"| node_models
node_jsearch_client -->|"builds jobs"| node_models
node_pipeline -->|"renders results"| node_report
node_report -->|"writes report"| node_report_files
node_pipeline -->|"records usage"| node_config
node_config -->|"writes counter"| node_usage_data
node_pipeline -->|"saves dedupe state"| node_config
node_config -->|"writes state"| node_seen_data
node_resume_parser -->|"extracts profile"| node_gemini
node_resume_parser -->|"writes profile"| node_resume_data
node_workflow -->|"commits reports"| node_report_files
node_workflow -->|"commits state"| node_seen_data
node_workflow -->|"commits counter"| node_usage_data

click node_workflow "https://github.com/mani568347/morning-job-agent/blob/main/.github/workflows/daily.yml"
click node_entry "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/__main__.py"
click node_pipeline "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/pipeline.py"
click node_config "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/config.py"
click node_models "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/models.py"
click node_resume_parser "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/parse_resume.py"
click node_jsearch_client "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/jsearch.py"
click node_dedupe "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/dedupe.py"
click node_scoring "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/scoring.py"
click node_report "https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/report.py"
click node_queries "https://github.com/mani568347/morning-job-agent/blob/main/config/queries.yaml"
click node_resume_data "https://github.com/mani568347/morning-job-agent/blob/main/data/resume.json"
click node_seen_data "https://github.com/mani568347/morning-job-agent/blob/main/data/seen.json"
click node_usage_data "https://github.com/mani568347/morning-job-agent/blob/main/data/usage.json"
click node_report_files "https://github.com/mani568347/morning-job-agent/tree/main/reports"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_workflow,node_entry,node_pipeline toneBlue
class node_models,node_resume_parser,node_jsearch_client,node_dedupe,node_scoring,node_report toneAmber
class node_config,node_queries,node_resume_data,node_seen_data,node_usage_data,node_report_files toneMint
class node_jsearch_api,node_gemini,node_schedule toneRose
```

## Components

### Run orchestration

- [Actions workflow](https://github.com/mani568347/morning-job-agent/blob/main/.github/workflows/daily.yml): `.github/workflows/daily.yml`
- [Module entry point](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/__main__.py): `src/morning_job_agent/__main__.py`
- [Search pipeline](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/pipeline.py): `src/morning_job_agent/pipeline.py`

### Job matching

- [Domain models](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/models.py): `src/morning_job_agent/models.py`
- [Resume parser](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/parse_resume.py): `src/morning_job_agent/parse_resume.py`
- [JSearch client](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/jsearch.py): `src/morning_job_agent/jsearch.py`
- [Deduplication](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/dedupe.py): `src/morning_job_agent/dedupe.py`
- [Scoring and letters](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/scoring.py): `src/morning_job_agent/scoring.py`
- [Report renderer](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/report.py): `src/morning_job_agent/report.py`

### Files and reports

- [Config and stores](https://github.com/mani568347/morning-job-agent/blob/main/src/morning_job_agent/config.py): `src/morning_job_agent/config.py`
- [Saved queries](https://github.com/mani568347/morning-job-agent/blob/main/config/queries.yaml): `config/queries.yaml`
- [Resume profile](https://github.com/mani568347/morning-job-agent/blob/main/data/resume.json): `data/resume.json`
- [Seen-job state](https://github.com/mani568347/morning-job-agent/blob/main/data/seen.json): `data/seen.json`
- [Request counter](https://github.com/mani568347/morning-job-agent/blob/main/data/usage.json): `data/usage.json`
- [Daily reports](https://github.com/mani568347/morning-job-agent/tree/main/reports): `reports`

### External services

- **JSearch API**
- **Gemini models**

### Other components

- **Daily scheduler**

## Connections

- Daily scheduler → Actions workflow: triggers
- Actions workflow → Module entry point: runs
- Module entry point → Search pipeline: calls
- Search pipeline → Config and stores: loads settings
- Config and stores → Saved queries: reads
- Config and stores → Resume profile: reads
- Config and stores → Seen-job state: reads
- Config and stores → Request counter: reads
- Search pipeline → JSearch client: fetches listings
- JSearch client → JSearch API: requests jobs
- JSearch API → JSearch client: returns listings
- Search pipeline → Deduplication: filters jobs
- Search pipeline → Scoring and letters: scores fresh jobs
- Resume profile → Scoring and letters: provides profile
- Scoring and letters → Gemini models: sends prompts
- Gemini models → Scoring and letters: returns results
- Scoring and letters → Search pipeline: returns shortlist
- Scoring and letters → Domain models: validates outputs
- JSearch client → Domain models: builds jobs
- Search pipeline → Report renderer: renders results
- Report renderer → Daily reports: writes report
- Search pipeline → Config and stores: records usage
- Config and stores → Request counter: writes counter
- Search pipeline → Config and stores: saves dedupe state
- Config and stores → Seen-job state: writes state
- Resume parser → Gemini models: extracts profile
- Resume parser → Resume profile: writes profile
- Actions workflow → Daily reports: commits reports
- Actions workflow → Seen-job state: commits state
- Actions workflow → Request counter: commits counter
