Update Gemini model to 3.6 and enhance resume pipeline features - #27
Merged
Conversation
- Introduced `PipelineFlow` component to visualize the workflow steps with status indicators. - Added `PipelineSidebar` component to display the current workflow phase and progress. - Created `ResultsDashboard` component to show ATS score, keyword coverage, and pipeline timing. - Implemented `SavedList` component for managing saved resumes and job descriptions with delete functionality. - Enhanced API with new types and methods for handling bullet differences and workflow refinement. - Updated flow management with new flow steps and metadata. - Improved state management for stream steps with duration tracking.
✅ Deploy Preview for tailrresume ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR updates the Tailr backend to use Gemini 3.6 Flash by default and adds a “refine” workflow path that re-runs the resume optimization pipeline with user feedback, while expanding the frontend UI to visualize pipeline progress/timing and apply targeted bullet-level feedback.
Changes:
- Backend: add
user_feedbackto workflow state, compute and return a bullet-level diff (bullet_diff), and expose a new SSE endpoint/workflows/refine. - Frontend: add new flow metadata + UI components (pipeline sidebar/flow, results dashboard) and support re-optimizing with per-bullet comments via the refine SSE stream.
- Docs/config: update Gemini version references and adjust deployment/env guidance.
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates Gemini badge and architecture diagram text to 3.6 Flash. |
| netlify.toml | Removes build-time env configuration (notably NEXT_PUBLIC_API_BASE). |
| apps/frontend/lib/store.ts | Adds optional duration_ms to streamed step state. |
| apps/frontend/lib/flow.ts | Introduces centralized flow step metadata/order/labels. |
| apps/frontend/lib/api.ts | Adds bullet_diff typing, adds refineWorkflow(), and factors SSE reading into readSSE(). |
| apps/frontend/components/SavedList.tsx | New component to list/select/delete saved resumes/JDs. |
| apps/frontend/components/ResultsDashboard.tsx | New results dashboard (ATS score + timing breakdown) wrapper. |
| apps/frontend/components/PipelineSidebar.tsx | New left sidebar workflow stepper with progress indicator. |
| apps/frontend/components/PipelineFlow.tsx | New pipeline node/connector visualization for streamed steps. |
| apps/frontend/components/Navbar.tsx | Minor UI/formatting tweaks (“Saved Data”, formatting, import order). |
| apps/frontend/app/page.tsx | Major UI overhaul + streaming orchestration, captures step durations, renders bullet diff, and adds refine-with-feedback flow. |
| apps/frontend/app/globals.css | Tweaks base font-size and card hover transform behavior. |
| apps/backend/workflows/state.py | Adds user_feedback to workflow state. |
| apps/backend/workflows/nodes.py | Formats feedback into rewrite prompt and locks un-commented content after refine. |
| apps/backend/workflows/diff.py | New bullet-level diff computation between canonical and rewritten resumes. |
| apps/backend/tests/test_workflow_refine.py | Tests feedback formatting, refine streaming output, and feedback-lock behavior. |
| apps/backend/tests/test_workflow_pipeline.py | Tests full pipeline + stream now includes full final payload (incl. bullet_diff). |
| apps/backend/tests/test_workflow_diff.py | Unit tests for compute_bullet_diff() behavior. |
| apps/backend/tests/test_guardrails_validators.py | Adds tests for tolerant date parsing in resume guardrails. |
| apps/backend/tests/conftest.py | Adds test env defaults and sys.path setup for backend tests. |
| apps/backend/requirements.txt | Adds fpdf2 dependency. |
| apps/backend/prompts/planner/system_v1.txt | Updates planner role prompt text. |
| apps/backend/prompts/ats/system_v1.txt | Updates ATS role prompt text. |
| apps/backend/guardrails/validators/resume_validator.py | Adds tolerant date parsing and compares parsed dates for invalid ranges. |
| apps/backend/config/settings.py | Updates default GEMINI_MODEL to gemini-3.6-flash. |
| apps/backend/application/workflow/service.py | Accumulates streamed state and emits richer workflow_complete payload + bullet_diff. |
| apps/backend/api/routes/workflow.py | Adds /workflows/refine SSE endpoint + refactors JD requirements resolution. |
| apps/backend/api/routes/resume.py | Adds /resumes/render-pdf endpoint and refactors PDF rendering to accept JSON payload. |
| apps/backend/api/routes/resume_schemas.py | Adds ResumeRenderRequest. |
| apps/backend/.env.example | Updates GEMINI model default to 3.6. |
| AGENTS.md | Updates model default and production API base guidance text. |
| .env.example | Replaces concrete prod API base with placeholder. |
Suppressed comments (2)
apps/frontend/components/SavedList.tsx:51
- Same stale-state issue as the resumes branch: filtering
savedJdsfrom a possibly stale closure can drop concurrent updates. Use the latest store state when applying the filter.
} else {
await deleteJobDescription(id);
setSavedJds(savedJds.filter((j) => j.id !== id));
}
apps/frontend/components/PipelineSidebar.tsx:100
- The progress bar width uses
currentIdx / FLOW_STEPS.length, which yields 0% for the first step (currentIdx === 0). It should align with the displayed progress count (i.e.,currentIdx + 1).
className="h-full rounded-full transition-all duration-500"
style={{
width: `${(Math.max(0, currentIdx) / FLOW_STEPS.length) * 100}%`,
background: "var(--accent)",
}}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
1
to
4
| [build] | ||
| base = "apps/frontend" | ||
| command = "npm run build" | ||
| publish = ".next" |
Comment on lines
+89
to
+92
| <span className="text-[var(--text-secondary)]">Progress</span> | ||
| <span className="font-mono text-[var(--text-primary)]"> | ||
| {Math.max(0, currentIdx)}/{FLOW_STEPS.length} | ||
| </span> |
Comment on lines
99
to
+103
| start = exp.get("start_date") | ||
| end = exp.get("end_date") | ||
| if start and end and end.lower() not in ["present", "current"]: | ||
| if start > end: | ||
| start_dt = _parse_date(start) | ||
| end_dt = _parse_date(end) |
Comment on lines
+45
to
+48
| if (isResume) { | ||
| await deleteResume(id); | ||
| setSavedResumes(savedResumes.filter((r) => r.id !== id)); | ||
| } else { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.