diff --git a/.codespellignore b/.codespellignore new file mode 100644 index 0000000..e69de29 diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..a4f82e9 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,41 @@ +# This workflow will run integration tests for the current project once per day + +name: Integration Tests + +on: + schedule: + - cron: "37 14 * * *" # Run at 7:37 AM Pacific Time (14:37 UTC) every day + workflow_dispatch: # Allows triggering the workflow manually in GitHub UI + +# If another scheduled run starts while this workflow is still running, +# cancel the earlier run in favor of the next run. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-tests: + name: Integration Tests + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.11", "3.12"] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + uv venv + uv pip install -r pyproject.toml + - name: Run integration tests + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }} + run: | + uv pip install pytest + uv run pytest tests/integration_tests diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..055407c --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,57 @@ +# This workflow will run unit tests for the current project + +name: CI + +on: + push: + branches: ["main"] + pull_request: + workflow_dispatch: # Allows triggering the workflow manually in GitHub UI + +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit-tests: + name: Unit Tests + strategy: + matrix: + os: [ubuntu-latest] + python-version: ["3.11", "3.12"] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + curl -LsSf https://astral.sh/uv/install.sh | sh + uv venv + uv pip install -r pyproject.toml + - name: Lint with ruff + run: | + uv pip install ruff + uv run ruff check . + - name: Lint with mypy + run: | + uv pip install mypy + uv run mypy --strict src/ + - name: Check README spelling + uses: codespell-project/actions-codespell@v2 + with: + ignore_words_file: .codespellignore + path: README.md + - name: Check code spelling + uses: codespell-project/actions-codespell@v2 + with: + ignore_words_file: .codespellignore + path: src/ + - name: Run tests with pytest + run: | + uv pip install pytest + uv run pytest tests/unit_tests diff --git a/README.md b/README.md index f48407e..dc143fd 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,74 @@ # LangGraph ReAct Agent Template -This LangGraph template implements a simple, extensible ReAct agent. +[![CI](https://github.com/langchain-ai/react-agent/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/langchain-ai/react-agent/actions/workflows/unit-tests.yml) +[![Integration Tests](https://github.com/langchain-ai/react-agent/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/langchain-ai/react-agent/actions/workflows/integration-tests.yml) + +This is a starter project to help you get started with developing a ReAct agent using [LangGraph](https://github.com/langchain-ai/langgraph) in [LangGraph Studio](https://github.com/langchain-ai/langgraph-studio). ![Graph view in LangGraph studio UI](./static/studio_ui.png) -## Repo Structure +It contains an example graph exported from `src/react_agent/graph.py` that implements a simple, extensible ReAct agent capable of reasoning and acting based on user inputs. + +## What it does + +The ReAct agent: + +1. Takes a user **query** as input +2. Reasons about the query and decides on an action +3. Executes the chosen action using available tools +4. Observes the result of the action +5. Repeats steps 2-4 until it can provide a final answer + +By default, it's set up with a basic set of tools, but can be easily extended with custom tools to suit various use cases. + +## Getting Started + +Assuming you have already [installed LangGraph Studio](https://github.com/langchain-ai/langgraph-studio?tab=readme-ov-file#download), to set up: -```txt -├── LICENSE -├── README.md -├── langgraph.json -├── poetry.lock -├── pyproject.toml -├── react_agent -│   ├── __init__.py -│   ├── graph.py -│   └── utils -│   ├── __init__.py -│   ├── configuration.py # Define the configurable variables -│   ├── state.py # Define state variables and how they're updated -│   ├── tools.py # Define the tools your agent can access -│   └── utils.py # Other sundry utilities -└── tests # Add whatever tests you'd like here - ├── integration_tests - │   └── __init__.py - └── unit_tests - └── __init__.py +1. Create a `.env` file. + +```bash +cp .env.example .env ``` +2. Define required API keys in your `.env` file. + +The primary [search tool](./src/react_agent/tools.py) [^1] used is [Tavily](https://tavily.com/). Create an API key [here](https://app.tavily.com/sign-in). + + + +Set up your LLM API keys. This repo defaults to using [Claude](https://console.anthropic.com/login). + + + +3. Customize whatever you'd like in the code. +4. Open the folder LangGraph Studio! + +## How to customize + +1. **Add new tools**: Extend the agent's capabilities by adding new tools in [tools.py](./src/react_agent/tools.py). These can be any Python functions that perform specific tasks. +2. **Select a different model**: We default to Anthropic's Claude 3 Sonnet. You can select a compatible chat model using `provider/model-name` via configuration. Example: `openai/gpt-4-turbo-preview`. +3. **Customize the prompt**: We provide a default system prompt in [configuration.py](./src/react_agent/configuration.py). You can easily update this via configuration in the studio. + +You can also quickly extend this template by: + +- Modifying the agent's reasoning process in [graph.py](./src/react_agent/graph.py). +- Adjusting the ReAct loop or adding additional steps to the agent's decision-making process. + +## Development + +While iterating on your graph, you can edit past state and rerun your app from past states to debug specific nodes. Local changes will be automatically applied via hot reload. Try adding an interrupt before the agent calls tools, updating the default system message in `src/react_agent/configuration.py` to take on a persona, or adding additional nodes and edges! + +Follow up requests will be appended to the same thread. You can create an entirely new thread, clearing previous history, using the `+` button in the top right. + +You can find the latest (under construction) docs on [LangGraph](https://github.com/langchain-ai/langgraph) here, including examples and other references. Using those guides can help you pick the right patterns to adapt here for your use case. + +LangGraph Studio also integrates with [LangSmith](https://smith.langchain.com/) for more in-depth tracing and collaboration with teammates. +