Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Thumbs.db
*.sw?

# Optional backend venv (if created in root)
#.venv/
#.venv/

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -199,4 +199,4 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

backend/.langgraph_api
backend/.langgraph_api
76 changes: 76 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Pre-commit configuration for Gemini LangGraph Quickstart
# See https://pre-commit.com for more information

repos:
# Model Validation (Critical - prevents 404 model errors)
- repo: local
hooks:
- id: model-validation
name: Model Configuration Validation
entry: ./tests/test-model-validation.sh
language: script
always_run: true
pass_filenames: false
description: "Prevent frontend/backend model mismatches that cause 404 errors"

# Backend Python (Ruff - modern all-in-one tool)
- repo: local
hooks:
- id: ruff-lint
name: Ruff Linting (Python)
entry: bash -c 'cd backend && ruff check --fix .'
language: system
files: ^backend/.*\.py$
description: "Fast Python linter (replaces flake8, isort, etc.)"
- id: ruff-format
name: Ruff Format (Python)
entry: bash -c 'cd backend && ruff format .'
language: system
files: ^backend/.*\.py$
description: "Fast Python formatter (replaces black)"

# Frontend TypeScript/React
- repo: local
hooks:
- id: eslint-frontend
name: ESLint (Frontend)
entry: bash -c 'cd frontend && npm run lint'
language: system
files: ^frontend/.*\.(ts|tsx|js|jsx)$
description: "TypeScript/React linting"
- id: prettier-frontend
name: Prettier (Frontend)
entry: bash -c 'cd frontend && npm run format'
language: system
files: ^frontend/.*\.(ts|tsx|js|jsx|json|css|md)$
description: "Frontend code formatting (auto-fix)"
- id: typescript-check
name: TypeScript Check
entry: bash -c 'cd frontend && npx tsc --noEmit'
language: system
files: ^frontend/.*\.(ts|tsx)$
description: "TypeScript type checking"

# General file hygiene
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-yaml
name: Check YAML
description: "Validate YAML syntax"
- id: check-json
name: Check JSON
description: "Validate JSON syntax"
- id: trailing-whitespace
name: Trim Trailing Whitespace
description: "Remove trailing whitespace"
- id: end-of-file-fixer
name: Fix End of Files
description: "Ensure files end with newline"
- id: check-merge-conflict
name: Check Merge Conflicts
description: "Check for merge conflict markers"

# Global settings
default_install_hook_types: [pre-commit]
default_stages: [pre-commit]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ dev-backend:
# Run frontend and backend concurrently
dev:
@echo "Starting both frontend and backend development servers..."
@make dev-frontend & make dev-backend
@make dev-frontend & make dev-backend
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ This project demonstrates a fullstack application using a React frontend and a L

## Project Structure

The project is divided into two main directories:
The project is divided into main directories:

- `frontend/`: Contains the React application built with Vite.
- `backend/`: Contains the LangGraph/FastAPI application, including the research agent logic.
- `tests/`: Contains project-wide regression tests for model validation and configuration consistency.

## Getting Started: Development and Local Testing

Expand Down Expand Up @@ -84,6 +85,25 @@ cd backend
python examples/cli_research.py "What are the latest trends in renewable energy?"
```

## Testing

Run comprehensive model validation tests to ensure frontend/backend model consistency:

```bash
./tests/test-model-validation.sh
```

These regression tests prevent model configuration mismatches that can cause 404 errors and application crashes. See `tests/README.md` for detailed testing documentation.

### Pre-commit Hooks

Set up automated code quality checks that run before each commit:

```bash
./setup-precommit.sh
```

This configures hooks for model validation, Python linting (Ruff), frontend formatting (Prettier), and TypeScript checking.

## Deployment

Expand Down Expand Up @@ -117,4 +137,4 @@ Open your browser and navigate to `http://localhost:8123/app/` to see the applic

## License

This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.
This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.
2 changes: 1 addition & 1 deletion backend/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# GEMINI_API_KEY=
# GEMINI_API_KEY=
1 change: 0 additions & 1 deletion backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,3 @@ help:
@echo 'tests - run unit tests'
@echo 'test TEST_FILE=<test_file> - run all tests in file'
@echo 'test_watch - run unit tests in watch mode'

4 changes: 3 additions & 1 deletion backend/examples/cli_research.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import argparse

from langchain_core.messages import HumanMessage

from agent.graph import graph


Expand All @@ -21,7 +23,7 @@ def main() -> None:
)
parser.add_argument(
"--reasoning-model",
default="gemini-2.5-pro-preview-05-06",
default="gemini-2.5-pro",
help="Model for the final answer",
)
args = parser.parse_args()
Expand Down
1 change: 1 addition & 0 deletions backend/src/agent/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# mypy: disable - error - code = "no-untyped-def,misc"
import pathlib

from fastapi import FastAPI, Response
from fastapi.staticfiles import StaticFiles

Expand Down
6 changes: 3 additions & 3 deletions backend/src/agent/configuration.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import os
from pydantic import BaseModel, Field
from typing import Any, Optional
from typing import Any

from langchain_core.runnables import RunnableConfig
from pydantic import BaseModel, Field


class Configuration(BaseModel):
Expand Down Expand Up @@ -41,7 +41,7 @@ class Configuration(BaseModel):

@classmethod
def from_runnable_config(
cls, config: Optional[RunnableConfig] = None
cls, config: RunnableConfig | None = None
) -> "Configuration":
"""Create a Configuration instance from a RunnableConfig."""
configurable = (
Expand Down
Loading