Compare commits

..

9 Commits

Author SHA1 Message Date
Chester Curme
7d14250bfd enable code interpreter test for v1 2025-07-10 16:02:32 -04:00
Chester Curme
c3add6d3b3 nit 2025-07-10 16:02:26 -04:00
Chester Curme
20c7baca6d add cassette for parsed 2025-07-10 16:02:14 -04:00
Chester Curme
c98ad2edaf fix streaming annotations 2025-07-10 16:02:08 -04:00
Chester Curme
2457f34a89 fix image generation 2025-07-10 16:02:03 -04:00
Chester Curme
1c4a610bf4 remove total 2025-07-10 16:01:55 -04:00
Chester Curme
5c8a6dac35 revert 2025-07-10 16:01:48 -04:00
Chester Curme
c70fb33f67 NotRequired -> Required 2025-07-10 16:01:41 -04:00
Chester Curme
1f30cc0c33 carry over changes 2025-07-10 16:01:18 -04:00
1148 changed files with 26472 additions and 65580 deletions

View File

@@ -5,31 +5,26 @@ This project includes a [dev container](https://containers.dev/), which lets you
You can use the dev container configuration in this folder to build and run the app without needing to install any of its tools locally! You can use it in [GitHub Codespaces](https://github.com/features/codespaces) or the [VS Code Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
## GitHub Codespaces
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/langchain-ai/langchain)
You may use the button above, or follow these steps to open this repo in a Codespace:
1. Click the **Code** drop-down menu at the top of <https://github.com/langchain-ai/langchain>.
1. Click the **Code** drop-down menu at the top of https://github.com/langchain-ai/langchain.
1. Click on the **Codespaces** tab.
1. Click **Create codespace on master**.
For more info, check out the [GitHub documentation](https://docs.github.com/en/free-pro-team@latest/github/developing-online-with-codespaces/creating-a-codespace#creating-a-codespace).
## VS Code Dev Containers
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/langchain-ai/langchain)
> [!NOTE]
> If you click the link above you will open the main repo (`langchain-ai/langchain`) and *not* your local cloned repo. This is fine if you only want to run and test the library, but if you want to contribute you can use the link below and replace with your username and cloned repo name:
```txt
https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/&lt;YOUR_USERNAME&gt;/&lt;YOUR_CLONED_REPO_NAME&gt;
Note: If you click the link above you will open the main repo (langchain-ai/langchain) and not your local cloned repo. This is fine if you only want to run and test the library, but if you want to contribute you can use the link below and replace with your username and cloned repo name:
```
https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/<yourusername>/<yourclonedreponame>
```
Then you will have a local cloned repo where you can contribute and then create pull requests.
If you already have VS Code and Docker installed, you can use the button above to get started. This will use VSCode to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
If you already have VS Code and Docker installed, you can use the button above to get started. This will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
Alternatively you can also follow these steps to open this repo in a container using the VS Code Dev Containers extension:
@@ -45,5 +40,5 @@ You can learn more in the [Dev Containers documentation](https://code.visualstud
## Tips and tricks
- If you are working with the same repository folder in a container and Windows, you'll want consistent line endings (otherwise you may see hundreds of changes in the SCM view). The `.gitattributes` file in the root of this repo will disable line ending conversion and should prevent this. See [tips and tricks](https://code.visualstudio.com/docs/devcontainers/tips-and-tricks#_resolving-git-line-ending-issues-in-containers-resulting-in-many-modified-files) for more info.
- If you'd like to review the contents of the image used in this dev container, you can check it out in the [devcontainers/images](https://github.com/devcontainers/images/tree/main/src/python) repo.
* If you are working with the same repository folder in a container and Windows, you'll want consistent line endings (otherwise you may see hundreds of changes in the SCM view). The `.gitattributes` file in the root of this repo will disable line ending conversion and should prevent this. See [tips and tricks](https://code.visualstudio.com/docs/devcontainers/tips-and-tricks#_resolving-git-line-ending-issues-in-containers-resulting-in-many-modified-files) for more info.
* If you'd like to review the contents of the image used in this dev container, you can check it out in the [devcontainers/images](https://github.com/devcontainers/images/tree/main/src/python) repo.

View File

@@ -1,58 +1,36 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
{
// Name for the dev container
"name": "langchain",
// Point to a Docker Compose file
"dockerComposeFile": "./docker-compose.yaml",
// Required when using Docker Compose. The name of the service to connect to once running
"service": "langchain",
// The optional 'workspaceFolder' property is the path VS Code should open by default when
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
"workspaceFolder": "/workspaces/langchain",
"mounts": [
"source=langchain-workspaces,target=/workspaces/langchain,type=volume"
],
// Prevent the container from shutting down
"overrideCommand": true,
// Features to add to the dev container. More info: https://containers.dev/features
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"containerEnv": {
"UV_LINK_MODE": "copy"
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Run commands after the container is created
"postCreateCommand": "uv sync && echo 'LangChain (Python) dev environment ready!'",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.debugpy",
"ms-python.mypy-type-checker",
"ms-python.isort",
"unifiedjs.vscode-mdx",
"davidanson.vscode-markdownlint",
"ms-toolsai.jupyter",
"GitHub.copilot",
"GitHub.copilot-chat"
],
"settings": {
"python.defaultInterpreterPath": ".venv/bin/python",
"python.formatting.provider": "none",
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
}
}
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
// Name for the dev container
"name": "langchain",
// Point to a Docker Compose file
"dockerComposeFile": "./docker-compose.yaml",
// Required when using Docker Compose. The name of the service to connect to once running
"service": "langchain",
// The optional 'workspaceFolder' property is the path VS Code should open by default when
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
"workspaceFolder": "/workspaces/langchain",
// Prevent the container from shutting down
"overrideCommand": true
// Features to add to the dev container. More info: https://containers.dev/features
// "features": {
// "ghcr.io/devcontainers-contrib/features/poetry:2": {}
// }
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line to run commands after the container is created.
// "postCreateCommand": "cat /etc/os-release",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

View File

@@ -4,9 +4,26 @@ services:
build:
dockerfile: libs/langchain/dev.Dockerfile
context: ..
volumes:
# Update this to wherever you want VS Code to mount the folder of your project
- ..:/workspaces/langchain:cached
networks:
- langchain-network
# environment:
# MONGO_ROOT_USERNAME: root
# MONGO_ROOT_PASSWORD: example123
# depends_on:
# - mongo
# mongo:
# image: mongo
# restart: unless-stopped
# environment:
# MONGO_INITDB_ROOT_USERNAME: root
# MONGO_INITDB_ROOT_PASSWORD: example123
# ports:
# - "27017:27017"
# networks:
# - langchain-network
networks:
langchain-network:

View File

@@ -1,52 +0,0 @@
# top-most EditorConfig file
root = true
# All files
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
# Python files
[*.py]
indent_style = space
indent_size = 4
max_line_length = 88
# JSON files
[*.json]
indent_style = space
indent_size = 2
# YAML files
[*.{yml,yaml}]
indent_style = space
indent_size = 2
# Markdown files
[*.md]
indent_style = space
indent_size = 2
trim_trailing_whitespace = false
# Configuration files
[*.{toml,ini,cfg}]
indent_style = space
indent_size = 4
# Shell scripts
[*.sh]
indent_style = space
indent_size = 2
# Makefile
[Makefile]
indent_style = tab
indent_size = 4
# Jupyter notebooks
[*.ipynb]
# Jupyter may include trailing whitespace in cell
# outputs that's semantically meaningful
trim_trailing_whitespace = false

View File

@@ -3,8 +3,4 @@
Hi there! Thank you for even being interested in contributing to LangChain.
As an open-source project in a rapidly developing field, we are extremely open to contributions, whether they involve new features, improved infrastructure, better documentation, or bug fixes.
To learn how to contribute to LangChain, please follow the [contribution guide here](https://python.langchain.com/docs/contributing/).
## New features
For new features, please start a new [discussion](https://forum.langchain.com/), where the maintainers will help with scoping out the necessary changes.
To learn how to contribute to LangChain, please follow the [contribution guide here](https://python.langchain.com/docs/contributing/).

38
.github/DISCUSSION_TEMPLATE/ideas.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
labels: [idea]
body:
- type: checkboxes
id: checks
attributes:
label: Checked
description: Please confirm and check all the following options.
options:
- label: I searched existing ideas and did not find a similar one
required: true
- label: I added a very descriptive title
required: true
- label: I've clearly described the feature request and motivation for it
required: true
- type: textarea
id: feature-request
validations:
required: true
attributes:
label: Feature request
description: |
A clear and concise description of the feature proposal. Please provide links to any relevant GitHub repos, papers, or other resources if relevant.
- type: textarea
id: motivation
validations:
required: true
attributes:
label: Motivation
description: |
Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link here too.
- type: textarea
id: proposal
validations:
required: false
attributes:
label: Proposal (If applicable)
description: |
If you would like to propose a solution, please describe it here.

122
.github/DISCUSSION_TEMPLATE/q-a.yml vendored Normal file
View File

@@ -0,0 +1,122 @@
labels: [Question]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in LangChain 🦜️🔗!
Please follow these instructions, fill every question, and do every step. 🙏
We're asking for this because answering questions and solving problems in GitHub takes a lot of time --
this is time that we cannot spend on adding new features, fixing bugs, writing documentation or reviewing pull requests.
By asking questions in a structured way (following this) it will be much easier for us to help you.
There's a high chance that by following this process, you'll find the solution on your own, eliminating the need to submit a question and wait for an answer. 😎
As there are many questions submitted every day, we will **DISCARD** and close the incomplete ones.
That will allow us (and others) to focus on helping people like you that follow the whole process. 🤓
Relevant links to check before opening a question to see if your question has already been answered, fixed or
if there's another way to solve your problem:
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
[API Reference](https://python.langchain.com/api_reference/),
[GitHub search](https://github.com/langchain-ai/langchain),
[LangChain Github Discussions](https://github.com/langchain-ai/langchain/discussions),
[LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
[LangChain ChatBot](https://chat.langchain.com/)
- type: checkboxes
id: checks
attributes:
label: Checked other resources
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this question.
required: true
- label: I searched the LangChain documentation with the integrated search.
required: true
- label: I used the GitHub search to find a similar question and didn't find it.
required: true
- type: checkboxes
id: help
attributes:
label: Commit to Help
description: |
After submitting this, I commit to one of:
* Read open questions until I find 2 where I can help someone and add a comment to help there.
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
* Once my question is answered, I will mark the answer as "accepted".
options:
- label: I commit to help with one of those options 👆
required: true
- type: textarea
id: example
attributes:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
If a maintainer can copy it, run it, and see it right away, there's a much higher chance that you'll be able to get help.
**Important!**
* Use code tags (e.g., ```python ... ```) to correctly [format your code](https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting).
* INCLUDE the language label (e.g. `python`) after the first three backticks to enable syntax highlighting. (e.g., ```python rather than ```).
* Reduce your code to the minimum required to reproduce the issue if possible. This makes it much easier for others to help you.
* Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
placeholder: |
from langchain_core.runnables import RunnableLambda
def bad_code(inputs) -> int:
raise NotImplementedError('For demo purpose')
chain = RunnableLambda(bad_code)
chain.invoke('Hello!')
render: python
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: |
What is the problem, question, or error?
Write a short description explaining what you are doing, what you expect to happen, and what is currently happening.
placeholder: |
* I'm trying to use the `langchain` library to do X.
* I expect to see Y.
* Instead, it does Z.
validations:
required: true
- type: textarea
id: system-info
attributes:
label: System Info
description: |
Please share your system info with us.
"pip freeze | grep langchain"
platform (windows / linux / mac)
python version
OR if you're on a recent version of langchain-core you can paste the output of:
python -m langchain_core.sys_info
placeholder: |
"pip freeze | grep langchain"
platform
python version
Alternatively, if you're on a recent version of langchain-core you can paste the output of:
python -m langchain_core.sys_info
These will only surface LangChain packages, don't forget to include any other relevant
packages you're using (if you're not sure what's relevant, you can paste the entire output of `pip freeze`).
validations:
required: true

View File

@@ -1,33 +1,33 @@
name: "\U0001F41B Bug Report"
description: Report a bug in LangChain. To report a security issue, please instead use the security option below. For questions, please use the LangChain forum.
labels: ["bug"]
description: Report a bug in LangChain. To report a security issue, please instead use the security option below. For questions, please use the GitHub Discussions.
labels: ["02 Bug Report"]
body:
- type: markdown
attributes:
value: |
value: >
Thank you for taking the time to file a bug report.
Use this to report BUGS in LangChain. For usage questions, feature requests and general design questions, please use the [LangChain Forum](https://forum.langchain.com/).
Use this to report bugs in LangChain.
If you're not certain that your issue is due to a bug in LangChain, please use [GitHub Discussions](https://github.com/langchain-ai/langchain/discussions)
to ask for help with your issue.
Relevant links to check before filing a bug report to see if your issue has already been reported, fixed or
if there's another way to solve your problem:
* [LangChain Forum](https://forum.langchain.com/),
* [LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
* [LangChain how-to guides](https://python.langchain.com/docs/how_to/),
* [API Reference](https://python.langchain.com/api_reference/),
* [LangChain ChatBot](https://chat.langchain.com/)
* [GitHub search](https://github.com/langchain-ai/langchain),
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
[API Reference](https://python.langchain.com/api_reference/),
[GitHub search](https://github.com/langchain-ai/langchain),
[LangChain Github Discussions](https://github.com/langchain-ai/langchain/discussions),
[LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
[LangChain ChatBot](https://chat.langchain.com/)
- type: checkboxes
id: checks
attributes:
label: Checked other resources
description: Please confirm and check all the following options.
options:
- label: This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
required: true
- label: I added a clear and descriptive title that summarizes this issue.
- label: I added a very descriptive title to this issue.
required: true
- label: I used the GitHub search to find a similar question and didn't find it.
required: true
@@ -35,8 +35,6 @@ body:
required: true
- label: The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).
required: true
- label: I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
required: true
- label: I posted a self-contained, minimal, reproducible example. A maintainer can copy it and run it AS IS.
required: true
- type: textarea
@@ -47,19 +45,19 @@ body:
label: Example Code
description: |
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
If a maintainer can copy it, run it, and see it right away, there's a much higher chance that you'll be able to get help.
**Important!**
* Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
* Reduce your code to the minimum required to reproduce the issue if possible. This makes it much easier for others to help you.
* Use code tags (e.g., ```python ... ```) to correctly [format your code](https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting).
* INCLUDE the language label (e.g. `python`) after the first three backticks to enable syntax highlighting. (e.g., ```python rather than ```).
* Reduce your code to the minimum required to reproduce the issue if possible. This makes it much easier for others to help you.
* Avoid screenshots when possible, as they are hard to read and (more importantly) don't allow others to copy-and-paste your code.
placeholder: |
The following code:
```python
from langchain_core.runnables import RunnableLambda
@@ -101,18 +99,16 @@ body:
Please share your system info with us. Do NOT skip this step and please don't trim
the output. Most users don't include enough information here and it makes it harder
for us to help you.
Run the following command in your terminal and paste the output here:
`python -m langchain_core.sys_info`
python -m langchain_core.sys_info
or if you have an existing python interpreter running:
```python
from langchain_core import sys_info
sys_info.print_sys_info()
```
alternatively, put the entire output of `pip freeze` here.
placeholder: |
python -m langchain_core.sys_info

View File

@@ -1,6 +1,12 @@
blank_issues_enabled: false
version: 2.1
contact_links:
- name: LangChain Forum
url: https://forum.langchain.com/
about: General community discussions, support, and feature requests
- name: 🤔 Question
about: Ask a question in the LangChain forums
url: https://forum.langchain.com/c/help/langchain/14
- name: Feature Request
url: https://www.github.com/langchain-ai/langchain/discussions/categories/ideas
about: Suggest a feature or an idea
- name: Show and tell
about: Show what you built with LangChain
url: https://www.github.com/langchain-ai/langchain/discussions/categories/show-and-tell

View File

@@ -1,59 +1,58 @@
name: Documentation
description: Report an issue related to the LangChain documentation.
title: "docs: <Please write a comprehensive title after the 'docs: ' prefix>"
labels: [documentation]
title: "DOC: <Please write a comprehensive title after the 'DOC: ' prefix>"
labels: [03 - Documentation]
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to report an issue in the documentation.
Only report issues with documentation here, explain if there are
any missing topics or if you found a mistake in the documentation.
Do **NOT** use this to ask usage questions or reporting issues with your code.
If you have usage questions or need help solving some problem,
please use the [LangChain Forum](https://forum.langchain.com/).
If you're in the wrong place, here are some helpful links to find a better
place to ask your question:
* [LangChain Forum](https://forum.langchain.com/),
* [LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
* [LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
* [LangChain how-to guides](https://python.langchain.com/docs/how_to/),
* [API Reference](https://python.langchain.com/api_reference/),
* [LangChain ChatBot](https://chat.langchain.com/)
* [GitHub search](https://github.com/langchain-ai/langchain),
- type: input
id: url
attributes:
label: URL
description: URL to documentation
validations:
required: false
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this issue.
required: true
- label: I included a link to the documentation page I am referring to (if applicable).
required: true
- type: textarea
attributes:
label: "Issue with current documentation:"
description: >
Please make sure to leave a reference to the document/code you're
referring to. Feel free to include names of classes, functions, methods
or concepts you'd like to see documented more.
- type: textarea
attributes:
label: "Idea or request for content:"
description: >
Please describe as clearly as possible what topics you think are missing
from the current documentation.
- type: markdown
attributes:
value: >
Thank you for taking the time to report an issue in the documentation.
Only report issues with documentation here, explain if there are
any missing topics or if you found a mistake in the documentation.
Do **NOT** use this to ask usage questions or reporting issues with your code.
If you have usage questions or need help solving some problem,
please use [GitHub Discussions](https://github.com/langchain-ai/langchain/discussions).
If you're in the wrong place, here are some helpful links to find a better
place to ask your question:
[LangChain documentation with the integrated search](https://python.langchain.com/docs/get_started/introduction),
[API Reference](https://python.langchain.com/api_reference/),
[GitHub search](https://github.com/langchain-ai/langchain),
[LangChain Github Discussions](https://github.com/langchain-ai/langchain/discussions),
[LangChain Github Issues](https://github.com/langchain-ai/langchain/issues?q=is%3Aissue),
[LangChain ChatBot](https://chat.langchain.com/)
- type: input
id: url
attributes:
label: URL
description: URL to documentation
validations:
required: false
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options.
options:
- label: I added a very descriptive title to this issue.
required: true
- label: I included a link to the documentation page I am referring to (if applicable).
required: true
- type: textarea
attributes:
label: "Issue with current documentation:"
description: >
Please make sure to leave a reference to the document/code you're
referring to. Feel free to include names of classes, functions, methods
or concepts you'd like to see documented more.
- type: textarea
attributes:
label: "Idea or request for content:"
description: >
Please describe as clearly as possible what topics you think are missing
from the current documentation.

View File

@@ -5,9 +5,9 @@ body:
attributes:
value: |
Thanks for your interest in LangChain! 🚀
If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation on the [LangChain Forum](https://forum.langchain.com/) instead.
If you are not a LangChain maintainer or were not asked directly by a maintainer to create an issue, then please start the conversation in a [Question in GitHub Discussions](https://github.com/langchain-ai/langchain/discussions/categories/q-a) instead.
You are a LangChain maintainer if you maintain any of the packages inside of the LangChain repository
or are a regular contributor to LangChain with previous merged pull requests.
- type: checkboxes

View File

@@ -1,32 +1,28 @@
Thank you for contributing to LangChain! Follow these steps to mark your pull request as ready for review. **If any of these steps are not completed, your PR will not be considered for review.**
Thank you for contributing to LangChain!
- [ ] **PR title**: "package: description"
- Where "package" is whichever of langchain, core, etc. is being modified. Use "docs: ..." for purely docs changes, "infra: ..." for CI changes.
- Example: "core: add foobar LLM"
- [ ] **PR title**: Follows the format: {TYPE}({SCOPE}): {DESCRIPTION}
- Examples:
- feat(core): add multi-tenant support
- fix(cli): resolve flag parsing error
- docs(openai): update API usage examples
- Allowed `{TYPE}` values:
- feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, release
- Allowed `{SCOPE}` values (optional):
- core, cli, langchain, standard-tests, docs, anthropic, chroma, deepseek, exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openai, perplexity, prompty, qdrant, xai
- Note: the `{DESCRIPTION}` must not start with an uppercase letter.
- Once you've written the title, please delete this checklist item; do not include it in the PR.
- [ ] **PR message**: ***Delete this entire checklist*** and replace with
- **Description:** a description of the change. Include a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) if applicable to a relevant issue.
- **Issue:** the issue # it fixes, if applicable (e.g. Fixes #123)
- **Dependencies:** any dependencies required for this change
- **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out!
- **Description:** a description of the change
- **Issue:** the issue # it fixes, if applicable
- **Dependencies:** any dependencies required for this change
- **Twitter handle:** if your PR gets announced, and you'd like a mention, we'll gladly shout you out!
- [ ] **Add tests and docs**: If you're adding a new integration, you must include:
1. A test for the integration, preferably unit tests that do not rely on network access,
2. An example notebook showing its use. It lives in `docs/docs/integrations` directory.
- [ ] **Lint and test**: Run `make format`, `make lint` and `make test` from the root of the package(s) you've modified. **We will not consider a PR unless these three are passing in CI.** See [contribution guidelines](https://python.langchain.com/docs/contributing/) for more.
- [ ] **Add tests and docs**: If you're adding a new integration, please include
1. a test for the integration, preferably unit tests that do not rely on network access,
2. an example notebook showing its use. It lives in `docs/docs/integrations` directory.
- [ ] **Lint and test**: Run `make format`, `make lint` and `make test` from the root of the package(s) you've modified. See contribution guidelines for more: https://python.langchain.com/docs/contributing/
Additional guidelines:
- Make sure optional dependencies are imported within a function.
- Please do not add dependencies to `pyproject.toml` files (even optional ones) unless they are **required** for unit tests.
- Please do not add dependencies to pyproject.toml files (even optional ones) unless they are required for unit tests.
- Most PRs should not touch more than one package.
- Changes should be backwards compatible.
If no one reviews your PR within a few days, please @-mention one of baskaryan, eyurtsev, ccurme, vbarda, hwchase17.

View File

@@ -1,325 +0,0 @@
# Global Development Guidelines for LangChain Projects
## Core Development Principles
### 1. Maintain Stable Public Interfaces ⚠️ CRITICAL
**Always attempt to preserve function signatures, argument positions, and names for exported/public methods.**
**Bad - Breaking Change:**
```python
def get_user(id, verbose=False): # Changed from `user_id`
pass
```
**Good - Stable Interface:**
```python
def get_user(user_id: str, verbose: bool = False) -> User:
"""Retrieve user by ID with optional verbose output."""
pass
```
**Before making ANY changes to public APIs:**
- Check if the function/class is exported in `__init__.py`
- Look for existing usage patterns in tests and examples
- Use keyword-only arguments for new parameters: `*, new_param: str = "default"`
- Mark experimental features clearly with docstring warnings (using reStructuredText, like `.. warning::`)
🧠 *Ask yourself:* "Would this change break someone's code if they used it last week?"
### 2. Code Quality Standards
**All Python code MUST include type hints and return types.**
**Bad:**
```python
def p(u, d):
return [x for x in u if x not in d]
```
**Good:**
```python
def filter_unknown_users(users: list[str], known_users: set[str]) -> list[str]:
"""Filter out users that are not in the known users set.
Args:
users: List of user identifiers to filter.
known_users: Set of known/valid user identifiers.
Returns:
List of users that are not in the known_users set.
"""
return [user for user in users if user not in known_users]
```
**Style Requirements:**
- Use descriptive, **self-explanatory variable names**. Avoid overly short or cryptic identifiers.
- Attempt to break up complex functions (>20 lines) into smaller, focused functions where it makes sense
- Avoid unnecessary abstraction or premature optimization
- Follow existing patterns in the codebase you're modifying
### 3. Testing Requirements
**Every new feature or bugfix MUST be covered by unit tests.**
**Test Organization:**
- Unit tests: `tests/unit_tests/` (no network calls allowed)
- Integration tests: `tests/integration_tests/` (network calls permitted)
- Use `pytest` as the testing framework
**Test Quality Checklist:**
- [ ] Tests fail when your new logic is broken
- [ ] Happy path is covered
- [ ] Edge cases and error conditions are tested
- [ ] Use fixtures/mocks for external dependencies
- [ ] Tests are deterministic (no flaky tests)
Checklist questions:
- [ ] Does the test suite fail if your new logic is broken?
- [ ] Are all expected behaviors exercised (happy path, invalid input, etc)?
- [ ] Do tests use fixtures or mocks where needed?
```python
def test_filter_unknown_users():
"""Test filtering unknown users from a list."""
users = ["alice", "bob", "charlie"]
known_users = {"alice", "bob"}
result = filter_unknown_users(users, known_users)
assert result == ["charlie"]
assert len(result) == 1
```
### 4. Security and Risk Assessment
**Security Checklist:**
- No `eval()`, `exec()`, or `pickle` on user-controlled input
- Proper exception handling (no bare `except:`) and use a `msg` variable for error messages
- Remove unreachable/commented code before committing
- Race conditions or resource leaks (file handles, sockets, threads).
- Ensure proper resource cleanup (file handles, connections)
**Bad:**
```python
def load_config(path):
with open(path) as f:
return eval(f.read()) # ⚠️ Never eval config
```
**Good:**
```python
import json
def load_config(path: str) -> dict:
with open(path) as f:
return json.load(f)
```
### 5. Documentation Standards
**Use Google-style docstrings with Args section for all public functions.**
**Insufficient Documentation:**
```python
def send_email(to, msg):
"""Send an email to a recipient."""
```
**Complete Documentation:**
```python
def send_email(to: str, msg: str, *, priority: str = "normal") -> bool:
"""
Send an email to a recipient with specified priority.
Args:
to: The email address of the recipient.
msg: The message body to send.
priority: Email priority level (``'low'``, ``'normal'``, ``'high'``).
Returns:
True if email was sent successfully, False otherwise.
Raises:
InvalidEmailError: If the email address format is invalid.
SMTPConnectionError: If unable to connect to email server.
"""
```
**Documentation Guidelines:**
- Types go in function signatures, NOT in docstrings
- Focus on "why" rather than "what" in descriptions
- Document all parameters, return values, and exceptions
- Keep descriptions concise but clear
- Use reStructuredText for docstrings to enable rich formatting
📌 *Tip:* Keep descriptions concise but clear. Only document return values if non-obvious.
### 6. Architectural Improvements
**When you encounter code that could be improved, suggest better designs:**
**Poor Design:**
```python
def process_data(data, db_conn, email_client, logger):
# Function doing too many things
validated = validate_data(data)
result = db_conn.save(validated)
email_client.send_notification(result)
logger.log(f"Processed {len(data)} items")
return result
```
**Better Design:**
```python
@dataclass
class ProcessingResult:
"""Result of data processing operation."""
items_processed: int
success: bool
errors: List[str] = field(default_factory=list)
class DataProcessor:
"""Handles data validation, storage, and notification."""
def __init__(self, db_conn: Database, email_client: EmailClient):
self.db = db_conn
self.email = email_client
def process(self, data: List[dict]) -> ProcessingResult:
"""Process and store data with notifications."""
validated = self._validate_data(data)
result = self.db.save(validated)
self._notify_completion(result)
return result
```
**Design Improvement Areas:**
If there's a **cleaner**, **more scalable**, or **simpler** design, highlight it and suggest improvements that would:
- Reduce code duplication through shared utilities
- Make unit testing easier
- Improve separation of concerns (single responsibility)
- Make unit testing easier through dependency injection
- Add clarity without adding complexity
- Prefer dataclasses for structured data
## Development Tools & Commands
### Package Management
```bash
# Add package
uv add package-name
# Sync project dependencies
uv sync
uv lock
```
### Testing
```bash
# Run unit tests (no network)
make test
# Don't run integration tests, as API keys must be set
# Run specific test file
uv run --group test pytest tests/unit_tests/test_specific.py
```
### Code Quality
```bash
# Lint code
make lint
# Format code
make format
# Type checking
uv run --group lint mypy .
```
### Dependency Management Patterns
**Local Development Dependencies:**
```toml
[tool.uv.sources]
langchain-core = { path = "../core", editable = true }
langchain-tests = { path = "../standard-tests", editable = true }
```
**For tools, use the `@tool` decorator from `langchain_core.tools`:**
```python
from langchain_core.tools import tool
@tool
def search_database(query: str) -> str:
"""Search the database for relevant information.
Args:
query: The search query string.
"""
# Implementation here
return results
```
## Commit Standards
**Use Conventional Commits format for PR titles:**
- `feat(core): add multi-tenant support`
- `fix(cli): resolve flag parsing error`
- `docs: update API usage examples`
- `docs(openai): update API usage examples`
## Framework-Specific Guidelines
- Follow the existing patterns in `langchain-core` for base abstractions
- Use `langchain_core.callbacks` for execution tracking
- Implement proper streaming support where applicable
- Avoid deprecated components like legacy `LLMChain`
### Partner Integrations
- Follow the established patterns in existing partner libraries
- Implement standard interfaces (`BaseChatModel`, `BaseEmbeddings`, etc.)
- Include comprehensive integration tests
- Document API key requirements and authentication
---
## Quick Reference Checklist
Before submitting code changes:
- [ ] **Breaking Changes**: Verified no public API changes
- [ ] **Type Hints**: All functions have complete type annotations
- [ ] **Tests**: New functionality is fully tested
- [ ] **Security**: No dangerous patterns (eval, silent failures, etc.)
- [ ] **Documentation**: Google-style docstrings for public functions
- [ ] **Code Quality**: `make lint` and `make format` pass
- [ ] **Architecture**: Suggested improvements where applicable
- [ ] **Commit Message**: Follows Conventional Commits format

View File

@@ -16,7 +16,6 @@ LANGCHAIN_DIRS = [
"libs/core",
"libs/text-splitters",
"libs/langchain",
"libs/langchain_v1",
]
# when set to True, we are ignoring core dependents

View File

@@ -73,7 +73,6 @@ def main():
for p in package_yaml["packages"]
if (p["repo"].startswith("langchain-ai/") or p.get("include_in_api_ref"))
and p["repo"] != "langchain-ai/langchain"
and p["name"] != "langchain-ai21" # Skip AI21 due to dependency conflicts
])
# Move libraries to their new locations
@@ -83,7 +82,6 @@ def main():
if not p.get("disabled", False)
and (p["repo"].startswith("langchain-ai/") or p.get("include_in_api_ref"))
and p["repo"] != "langchain-ai/langchain"
and p["name"] != "langchain-ai21" # Skip AI21 due to dependency conflicts
])
# Delete ones without a pyproject.toml

6
.github/workflows/.codespell-exclude vendored Normal file
View File

@@ -0,0 +1,6 @@
"NotIn": "not in",
- `/checkin`: Check-in
docs/docs/integrations/providers/trulens.mdx
self.assertIn(
from trulens_eval import Tru
tru = Tru()

View File

@@ -1,4 +1,4 @@
name: '🔗 Compile Integration Tests'
name: compile-integration-test
on:
workflow_call:
@@ -25,24 +25,24 @@ jobs:
working-directory: ${{ inputs.working-directory }}
runs-on: ubuntu-latest
timeout-minutes: 20
name: 'Python ${{ inputs.python-version }}'
name: "uv run pytest -m compile tests/integration_tests #${{ inputs.python-version }}"
steps:
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Integration Dependencies'
- name: Install integration dependencies
shell: bash
run: uv sync --group test --group test_integration
- name: '🔗 Check Integration Tests Compile'
- name: Check integration tests compile
shell: bash
run: uv run pytest -m compile tests/integration_tests
- name: '🧹 Verify Clean Working Directory'
- name: Ensure the tests did not create any additional files
shell: bash
run: |
set -eu

View File

@@ -1,5 +1,4 @@
name: '🚀 Integration Tests'
run-name: 'Test ${{ inputs.working-directory }} on Python ${{ inputs.python-version }}'
name: Integration Tests
on:
workflow_dispatch:
@@ -12,7 +11,6 @@ on:
required: true
type: string
description: "Python version to use"
default: "3.11"
permissions:
contents: read
@@ -26,20 +24,20 @@ jobs:
run:
working-directory: ${{ inputs.working-directory }}
runs-on: ubuntu-latest
name: 'Python ${{ inputs.python-version }}'
name: Python ${{ inputs.python-version }}
steps:
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Integration Dependencies'
- name: Install dependencies
shell: bash
run: uv sync --group test --group test_integration
- name: '🚀 Run Integration Tests'
- name: Run integration tests
shell: bash
env:
AI21_API_KEY: ${{ secrets.AI21_API_KEY }}

View File

@@ -1,6 +1,4 @@
name: '🧹 Code Linting'
# Runs code quality checks using ruff, mypy, and other linting tools
# Checks both package code and test code for consistency
name: lint
on:
workflow_call:
@@ -26,21 +24,19 @@ env:
UV_FROZEN: "true"
jobs:
# Linting job - runs quality checks on package and test code
build:
name: 'Python ${{ inputs.python-version }}'
name: "make lint #${{ inputs.python-version }}"
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: '📋 Checkout Code'
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Lint & Typing Dependencies'
- name: Install dependencies
# Also installs dev/lint/test/typing dependencies, to ensure we have
# type hints for as many of our libraries as possible.
# This helps catch errors that require dependencies to be spotted, for example:
@@ -53,12 +49,12 @@ jobs:
run: |
uv sync --group lint --group typing
- name: '🔍 Analyze Package Code with Linters'
- name: Analysing the code with our lint
working-directory: ${{ inputs.working-directory }}
run: |
make lint_package
- name: '📦 Install Unit Test Dependencies'
- name: Install unit test dependencies
# Also installs dev/lint/test/typing dependencies, to ensure we have
# type hints for as many of our libraries as possible.
# This helps catch errors that require dependencies to be spotted, for example:
@@ -71,13 +67,13 @@ jobs:
working-directory: ${{ inputs.working-directory }}
run: |
uv sync --inexact --group test
- name: '📦 Install Unit + Integration Test Dependencies'
- name: Install unit+integration test dependencies
if: ${{ startsWith(inputs.working-directory, 'libs/partners/') }}
working-directory: ${{ inputs.working-directory }}
run: |
uv sync --inexact --group test --group test_integration
- name: '🔍 Analyze Test Code with Linters'
- name: Analysing the code with our lint
working-directory: ${{ inputs.working-directory }}
run: |
make lint_tests

View File

@@ -1,5 +1,5 @@
name: '🚀 Package Release'
run-name: 'Release ${{ inputs.working-directory }} ${{ inputs.release-version }}'
name: Release
run-name: Release ${{ inputs.working-directory }} by @${{ github.actor }}
on:
workflow_call:
inputs:
@@ -14,16 +14,11 @@ on:
type: string
description: "From which folder this pipeline executes"
default: 'libs/langchain'
release-version:
required: true
type: string
default: '0.1.0'
description: "New version of package being released"
dangerous-nonmaster-release:
required: false
type: boolean
default: false
description: "Release from a non-master branch (danger!) - Only use for hotfixes"
description: "Release from a non-master branch (danger!)"
env:
PYTHON_VERSION: "3.11"
@@ -31,8 +26,6 @@ env:
UV_NO_SYNC: "true"
jobs:
# Build the distribution package and extract version info
# Runs in isolated environment with minimal permissions for security
build:
if: github.ref == 'refs/heads/master' || inputs.dangerous-nonmaster-release
environment: Scheduled testing
@@ -116,7 +109,7 @@ jobs:
# Look for the latest release of the same base version
REGEX="^$PKG_NAME==$BASE_VERSION\$"
PREV_TAG=$(git tag --sort=-creatordate | (grep -P "$REGEX" || true) | head -1)
# If no exact base version match, look for the latest release of any kind
if [ -z "$PREV_TAG" ]; then
REGEX="^$PKG_NAME==\\d+\\.\\d+\\.\\d+\$"
@@ -127,7 +120,7 @@ jobs:
PREV_TAG="$PKG_NAME==${VERSION%.*}.$(( ${VERSION##*.} - 1 ))"; [[ "${VERSION##*.}" -eq 0 ]] && PREV_TAG=""
# backup case if releasing e.g. 0.3.0, looks up last release
# note if last release (chronologically) was e.g. 0.1.47 it will get
# note if last release (chronologically) was e.g. 0.1.47 it will get
# that instead of the last 0.2 release
if [ -z "$PREV_TAG" ]; then
REGEX="^$PKG_NAME==\\d+\\.\\d+\\.\\d+\$"
@@ -388,12 +381,11 @@ jobs:
- name: Test against ${{ matrix.partner }}
if: startsWith(inputs.working-directory, 'libs/core')
run: |
# Identify latest tag, excluding pre-releases
# Identify latest tag
LATEST_PACKAGE_TAG="$(
git ls-remote --tags origin "langchain-${{ matrix.partner }}*" \
| awk '{print $2}' \
| sed 's|refs/tags/||' \
| grep -Ev '==[^=]*(\.?dev[0-9]*|\.?rc[0-9]*)$' \
| sort -Vr \
| head -n 1
)"
@@ -490,7 +482,7 @@ jobs:
with:
name: dist
path: ${{ inputs.working-directory }}/dist/
- name: Create Tag
uses: ncipollo/release-action@v1
with:

View File

@@ -1,6 +1,4 @@
name: '🧪 Unit Testing'
# Runs unit tests with both current and minimum supported dependency versions
# to ensure compatibility across the supported range
name: test
on:
workflow_call:
@@ -22,33 +20,31 @@ env:
UV_NO_SYNC: "true"
jobs:
# Main test job - runs unit tests with current deps, then retests with minimum versions
build:
defaults:
run:
working-directory: ${{ inputs.working-directory }}
runs-on: ubuntu-latest
timeout-minutes: 20
name: 'Python ${{ inputs.python-version }}'
name: "make test #${{ inputs.python-version }}"
steps:
- name: '📋 Checkout Code'
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
id: setup-python
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Test Dependencies'
- name: Install dependencies
shell: bash
run: uv sync --group test --dev
- name: '🧪 Run Core Unit Tests'
- name: Run core tests
shell: bash
run: |
make test
- name: '🔍 Calculate Minimum Dependency Versions'
- name: Get minimum versions
working-directory: ${{ inputs.working-directory }}
id: min-version
shell: bash
@@ -59,7 +55,7 @@ jobs:
echo "min-versions=$min_versions" >> "$GITHUB_OUTPUT"
echo "min-versions=$min_versions"
- name: '🧪 Run Tests with Minimum Dependencies'
- name: Run unit tests with minimum dependency versions
if: ${{ steps.min-version.outputs.min-versions != '' }}
env:
MIN_VERSIONS: ${{ steps.min-version.outputs.min-versions }}
@@ -68,7 +64,7 @@ jobs:
make tests
working-directory: ${{ inputs.working-directory }}
- name: '🧹 Verify Clean Working Directory'
- name: Ensure the tests did not create any additional files
shell: bash
run: |
set -eu

View File

@@ -1,4 +1,4 @@
name: '📑 Documentation Import Testing'
name: test_doc_imports
on:
workflow_call:
@@ -18,30 +18,29 @@ jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
name: '🔍 Check Doc Imports (Python ${{ inputs.python-version }})'
name: "check doc imports #${{ inputs.python-version }}"
steps:
- name: '📋 Checkout Code'
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Test Dependencies'
- name: Install dependencies
shell: bash
run: uv sync --group test
- name: '📦 Install LangChain in Editable Mode'
- name: Install langchain editable
run: |
VIRTUAL_ENV=.venv uv pip install langchain-experimental langchain-community -e libs/core libs/langchain
- name: '🔍 Validate Documentation Import Statements'
- name: Check doc imports
shell: bash
run: |
uv run python docs/scripts/check_imports.py
- name: '🧹 Verify Clean Working Directory'
- name: Ensure the test did not create any additional files
shell: bash
run: |
set -eu

View File

@@ -1,4 +1,4 @@
name: '🐍 Pydantic Version Testing'
name: test pydantic intermediate versions
on:
workflow_call:
@@ -31,30 +31,29 @@ jobs:
working-directory: ${{ inputs.working-directory }}
runs-on: ubuntu-latest
timeout-minutes: 20
name: 'Pydantic ~=${{ inputs.pydantic-version }}'
name: "make test # pydantic: ~=${{ inputs.pydantic-version }}, python: ${{ inputs.python-version }}, "
steps:
- name: '📋 Checkout Code'
uses: actions/checkout@v4
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ inputs.python-version }} + UV'
- name: Set up Python ${{ inputs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ inputs.python-version }}
- name: '📦 Install Test Dependencies'
- name: Install dependencies
shell: bash
run: uv sync --group test
- name: '🔄 Install Specific Pydantic Version'
- name: Overwrite pydantic version
shell: bash
run: VIRTUAL_ENV=.venv uv pip install pydantic~=${{ inputs.pydantic-version }}
- name: '🧪 Run Core Tests'
- name: Run core tests
shell: bash
run: |
make test
- name: '🧹 Verify Clean Working Directory'
- name: Ensure the tests did not create any additional files
shell: bash
run: |
set -eu

View File

@@ -1,4 +1,4 @@
name: '🧪 Test Release Package'
name: test-release
on:
workflow_call:
@@ -29,7 +29,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: '🐍 Set up Python + UV'
- name: Set up Python + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ env.PYTHON_VERSION }}
@@ -45,17 +45,17 @@ jobs:
# > It is strongly advised to separate jobs for building [...]
# > from the publish job.
# https://github.com/pypa/gh-action-pypi-publish#non-goals
- name: '📦 Build Project for Distribution'
- name: Build project for distribution
run: uv build
working-directory: ${{ inputs.working-directory }}
- name: '⬆️ Upload Build Artifacts'
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: test-dist
path: ${{ inputs.working-directory }}/dist/
- name: '🔍 Extract Version Information'
- name: Check Version
id: check-version
shell: python
working-directory: ${{ inputs.working-directory }}

View File

@@ -1,21 +1,17 @@
name: '📚 API Docs'
run-name: 'Build & Deploy API Reference'
# Runs daily or can be triggered manually for immediate updates
name: API Docs Build
on:
workflow_dispatch:
schedule:
- cron: '0 13 * * *' # Daily at 1PM UTC
- cron: '0 13 * * *'
env:
PYTHON_VERSION: "3.11"
jobs:
# Only runs on main repository to prevent unnecessary builds on forks
build:
if: github.repository == 'langchain-ai/langchain' || github.event_name != 'schedule'
runs-on: ubuntu-latest
permissions:
contents: read
permissions: write-all
steps:
- uses: actions/checkout@v4
with:
@@ -26,7 +22,7 @@ jobs:
path: langchain-api-docs-html
token: ${{ secrets.TOKEN_GITHUB_API_DOCS_HTML }}
- name: '📋 Extract Repository List with yq'
- name: Get repos with yq
id: get-unsorted-repos
uses: mikefarah/yq@master
with:
@@ -45,65 +41,56 @@ jobs:
| .repo
' langchain/libs/packages.yml
- name: '📋 Parse YAML & Checkout Repositories'
- name: Parse YAML and checkout repos
env:
REPOS_UNSORTED: ${{ steps.get-unsorted-repos.outputs.result }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Get unique repositories
REPOS=$(echo "$REPOS_UNSORTED" | sort -u)
# Checkout each unique repository
# Checkout each unique repository that is in langchain-ai org
for repo in $REPOS; do
# Validate repository format (allow any org with proper format)
if [[ ! "$repo" =~ ^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$ ]]; then
echo "Error: Invalid repository format: $repo"
exit 1
fi
REPO_NAME=$(echo $repo | cut -d'/' -f2)
# Additional validation for repo name
if [[ ! "$REPO_NAME" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
echo "Error: Invalid repository name: $REPO_NAME"
exit 1
fi
echo "Checking out $repo to $REPO_NAME"
git clone --depth 1 https://github.com/$repo.git $REPO_NAME
done
- name: '🐍 Setup Python ${{ env.PYTHON_VERSION }}'
- name: Setup Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
id: setup-python
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: '📦 Install Initial Python Dependencies'
- name: Install initial py deps
working-directory: langchain
run: |
python -m pip install -U uv
python -m uv pip install --upgrade --no-cache-dir pip setuptools pyyaml
- name: '📦 Organize Library Directories'
- name: Move libs
run: python langchain/.github/scripts/prep_api_docs_build.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: '🧹 Remove Old HTML Files'
- name: Rm old html
run:
rm -rf langchain-api-docs-html/api_reference_build/html
- name: '📦 Install Documentation Dependencies'
- name: Install dependencies
working-directory: langchain
run: |
python -m uv pip install $(ls ./libs/partners | xargs -I {} echo "./libs/partners/{}") --overrides ./docs/vercel_overrides.txt
python -m uv pip install libs/core libs/langchain libs/text-splitters libs/community libs/experimental libs/standard-tests
python -m uv pip install -r docs/api_reference/requirements.txt
- name: '🔧 Configure Git Settings'
- name: Set Git config
working-directory: langchain
run: |
git config --local user.email "actions@github.com"
git config --local user.name "Github Actions"
- name: '📚 Build API Documentation'
- name: Build docs
working-directory: langchain
run: |
python docs/api_reference/create_api_rst.py

View File

@@ -1,4 +1,4 @@
name: '🔗 Check Broken Links'
name: Check Broken Links
on:
workflow_dispatch:
@@ -14,15 +14,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: '🟢 Setup Node.js 18.x'
- name: Use Node.js 18.x
uses: actions/setup-node@v4
with:
node-version: 18.x
cache: "yarn"
cache-dependency-path: ./docs/yarn.lock
- name: '📦 Install Node Dependencies'
- name: Install dependencies
run: yarn install --immutable --mode=skip-build
working-directory: ./docs
- name: '🔍 Scan Documentation for Broken Links'
- name: Check broken links
run: yarn check-broken-links
working-directory: ./docs

View File

@@ -1,6 +1,4 @@
name: '🔍 Check `core` Version Equality'
# Ensures version numbers in pyproject.toml and version.py stay in sync
# Prevents releases with mismatched version numbers
name: Check `core` Version Equality
on:
pull_request:
@@ -18,7 +16,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: '✅ Verify pyproject.toml & version.py Match'
- name: Check version equality
run: |
PYPROJECT_VERSION=$(grep -Po '(?<=^version = ")[^"]*' libs/core/pyproject.toml)
VERSION_PY_VERSION=$(grep -Po '(?<=^VERSION = ")[^"]*' libs/core/langchain_core/version.py)

View File

@@ -1,4 +1,4 @@
name: '🔧 CI'
name: CI
on:
push:
@@ -6,7 +6,6 @@ on:
pull_request:
merge_group:
# Optimizes CI performance by canceling redundant workflow runs
# 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.
#
@@ -25,23 +24,16 @@ env:
UV_NO_SYNC: "true"
jobs:
# This job analyzes which files changed and creates a dynamic test matrix
# to only run tests/lints for the affected packages, improving CI efficiency
build:
name: 'Detect Changes & Set Matrix'
runs-on: ubuntu-latest
steps:
- name: '📋 Checkout Code'
uses: actions/checkout@v4
- name: '🐍 Setup Python 3.11'
uses: actions/setup-python@v5
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: '📂 Get Changed Files'
id: files
- id: files
uses: Ana06/get-changed-files@v2.3.0
- name: '🔍 Analyze Changed Files & Generate Build Matrix'
id: set-matrix
- id: set-matrix
run: |
python -m pip install packaging requests
python .github/scripts/check_diff.py ${{ steps.files.outputs.all }} >> $GITHUB_OUTPUT
@@ -53,8 +45,8 @@ jobs:
dependencies: ${{ steps.set-matrix.outputs.dependencies }}
test-doc-imports: ${{ steps.set-matrix.outputs.test-doc-imports }}
test-pydantic: ${{ steps.set-matrix.outputs.test-pydantic }}
# Run linting only on packages that have changed files
lint:
name: cd ${{ matrix.job-configs.working-directory }}
needs: [ build ]
if: ${{ needs.build.outputs.lint != '[]' }}
strategy:
@@ -67,8 +59,8 @@ jobs:
python-version: ${{ matrix.job-configs.python-version }}
secrets: inherit
# Run unit tests only on packages that have changed files
test:
name: cd ${{ matrix.job-configs.working-directory }}
needs: [ build ]
if: ${{ needs.build.outputs.test != '[]' }}
strategy:
@@ -81,8 +73,8 @@ jobs:
python-version: ${{ matrix.job-configs.python-version }}
secrets: inherit
# Test compatibility with different Pydantic versions for affected packages
test-pydantic:
name: cd ${{ matrix.job-configs.working-directory }}
needs: [ build ]
if: ${{ needs.build.outputs.test-pydantic != '[]' }}
strategy:
@@ -103,12 +95,12 @@ jobs:
job-configs: ${{ fromJson(needs.build.outputs.test-doc-imports) }}
fail-fast: false
uses: ./.github/workflows/_test_doc_imports.yml
secrets: inherit
with:
python-version: ${{ matrix.job-configs.python-version }}
secrets: inherit
# Verify integration tests compile without actually running them (faster feedback)
compile-integration-tests:
name: cd ${{ matrix.job-configs.working-directory }}
needs: [ build ]
if: ${{ needs.build.outputs.compile-integration-tests != '[]' }}
strategy:
@@ -121,9 +113,8 @@ jobs:
python-version: ${{ matrix.job-configs.python-version }}
secrets: inherit
# Run extended test suites that require additional dependencies
extended-tests:
name: 'Extended Tests'
name: "cd ${{ matrix.job-configs.working-directory }} / make extended_tests #${{ matrix.job-configs.python-version }}"
needs: [ build ]
if: ${{ needs.build.outputs.extended-tests != '[]' }}
strategy:
@@ -139,12 +130,12 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: '🐍 Set up Python ${{ matrix.job-configs.python-version }} + UV'
- name: Set up Python ${{ matrix.job-configs.python-version }} + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ matrix.job-configs.python-version }}
- name: '📦 Install Dependencies & Run Extended Tests'
- name: Install dependencies and run extended tests
shell: bash
run: |
echo "Running extended tests, installing dependencies with uv..."
@@ -153,7 +144,7 @@ jobs:
VIRTUAL_ENV=.venv uv pip install -r extended_testing_deps.txt
VIRTUAL_ENV=.venv make extended_tests
- name: '🧹 Verify Clean Working Directory'
- name: Ensure the tests did not create any additional files
shell: bash
run: |
set -eu
@@ -165,9 +156,8 @@ jobs:
# and `set -e` above will cause the step to fail.
echo "$STATUS" | grep 'nothing to commit, working tree clean'
# Final status check - ensures all required jobs passed before allowing merge
ci_success:
name: '✅ CI Success'
name: "CI Success"
needs: [build, lint, test, compile-integration-tests, extended-tests, test-doc-imports, test-pydantic]
if: |
always()
@@ -177,7 +167,7 @@ jobs:
RESULTS_JSON: ${{ toJSON(needs.*.result) }}
EXIT_CODE: ${{!contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && '0' || '1'}}
steps:
- name: '🎉 All Checks Passed'
- name: "CI Success"
run: |
echo $JOBS_JSON
echo $RESULTS_JSON

View File

@@ -1,4 +1,4 @@
name: '📑 Integration Docs Lint'
name: Integration Docs Lint
on:
push:
@@ -33,6 +33,6 @@ jobs:
*.ipynb
*.md
*.mdx
- name: '🔍 Check New Documentation Templates'
- name: Check new docs
run: |
python docs/scripts/check_templates.py ${{ steps.files.outputs.added }}

35
.github/workflows/codespell.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: CI / cd . / make spell_check
on:
push:
branches: [master, v0.1, v0.2]
pull_request:
permissions:
contents: read
jobs:
codespell:
name: (Check for spelling errors)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Dependencies
run: |
pip install toml
- name: Extract Ignore Words List
run: |
# Use a Python script to extract the ignore words list from pyproject.toml
python .github/workflows/extract_ignored_words_list.py
id: extract_ignore_words
# - name: Codespell
# uses: codespell-project/actions-codespell@v2
# with:
# skip: guide_imports.json,*.ambr,./cookbook/data/imdb_top_1000.csv,*.lock
# ignore_words_list: ${{ steps.extract_ignore_words.outputs.ignore_words_list }}
# exclude_file: ./.github/workflows/codespell-exclude

View File

@@ -1,4 +1,4 @@
name: '⚡ CodSpeed'
name: CodSpeed
on:
push:
@@ -18,9 +18,8 @@ env:
jobs:
codspeed:
name: 'Benchmark'
name: Run benchmarks
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'codspeed-ignore') }}
strategy:
matrix:
include:
@@ -39,7 +38,7 @@ jobs:
- uses: actions/checkout@v4
# We have to use 3.12 as 3.13 is not yet supported
- name: '📦 Install UV Package Manager'
- name: Install uv
uses: astral-sh/setup-uv@v6
with:
python-version: "3.12"
@@ -48,11 +47,11 @@ jobs:
with:
python-version: "3.12"
- name: '📦 Install Test Dependencies'
- name: Install dependencies
run: uv sync --group test
working-directory: ${{ matrix.working-directory }}
- name: '⚡ Run Benchmarks: ${{ matrix.working-directory }}'
- name: Run benchmarks ${{ matrix.working-directory }}
uses: CodSpeedHQ/action@v3
with:
token: ${{ secrets.CODSPEED_TOKEN }}

View File

@@ -1,6 +1,5 @@
name: '👥 LangChain People'
run-name: 'Update People Data'
# This workflow updates the LangChain People data by fetching the latest information from the LangChain Git
name: LangChain People
on:
schedule:
- cron: "0 14 1 * *"
@@ -15,13 +14,13 @@ jobs:
permissions:
contents: write
steps:
- name: '📋 Dump GitHub Context'
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v4
# Ref: https://github.com/actions/runner/issues/2033
- name: '🔧 Fix Git Safe Directory in Container'
- name: Fix git safe.directory in container
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
- uses: ./.github/actions/people
with:

View File

@@ -4,7 +4,6 @@
# Purpose:
# Enforces Conventional Commits format for pull request titles to maintain a
# clear, consistent, and machine-readable change history across our repository.
# This helps with automated changelog generation and semantic versioning.
#
# Enforced Commit Message Format (Conventional Commits 1.0.0):
# <type>[optional scope]: <description>
@@ -46,7 +45,7 @@
# • Conventional Commits spec: https://www.conventionalcommits.org/en/v1.0.0/
# -----------------------------------------------------------------------------
name: '🏷️ PR Title Lint'
name: PR Title Lint
permissions:
pull-requests: read
@@ -56,12 +55,11 @@ on:
types: [opened, edited, synchronize]
jobs:
# Validates that PR title follows Conventional Commits specification
lint-pr-title:
name: 'Validate PR Title Format'
name: Validate PR Title
runs-on: ubuntu-latest
steps:
- name: '✅ Validate Conventional Commits Format'
- name: Validate PR Title
uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -83,9 +81,7 @@ jobs:
core
cli
langchain
langchain_v1
standard-tests
text-splitters
docs
anthropic
chroma
@@ -102,10 +98,14 @@ jobs:
prompty
qdrant
xai
infra
requireScope: false
disallowScopes: |
release
[A-Z]+
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
ignoreLabels: |
ignore-lint-pr-title

View File

@@ -1,5 +1,5 @@
name: '📓 Validate Documentation Notebooks'
run-name: 'Test notebooks in ${{ inputs.working-directory }}'
name: Run Notebooks
on:
workflow_dispatch:
inputs:
@@ -24,43 +24,43 @@ jobs:
build:
runs-on: ubuntu-latest
if: github.repository == 'langchain-ai/langchain' || github.event_name != 'schedule'
name: '📑 Test Documentation Notebooks'
name: "Test docs"
steps:
- uses: actions/checkout@v4
- name: '🐍 Set up Python + UV'
- name: Set up Python + uv
uses: "./.github/actions/uv_setup"
with:
python-version: ${{ github.event.inputs.python_version || '3.11' }}
- name: '🔐 Authenticate to Google Cloud'
- name: 'Authenticate to Google Cloud'
id: 'auth'
uses: google-github-actions/auth@v2
with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
- name: '🔐 Configure AWS Credentials'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: '📦 Install Dependencies'
- name: Install dependencies
run: |
uv sync --group dev --group test
- name: '📦 Pre-download Test Files'
- name: Pre-download files
run: |
uv run python docs/scripts/cache_data.py
curl -s https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql | sqlite3 docs/docs/how_to/Chinook.db
cp docs/docs/how_to/Chinook.db docs/docs/tutorials/Chinook.db
- name: '🔧 Prepare Notebooks for CI'
- name: Prepare notebooks
run: |
uv run python docs/scripts/prepare_notebooks_for_ci.py --comment-install-cells --working-directory ${{ github.event.inputs.working-directory || 'all' }}
- name: '🚀 Execute Notebooks'
- name: Run notebooks
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
FIREWORKS_API_KEY: ${{ secrets.FIREWORKS_API_KEY }}

View File

@@ -1,8 +1,7 @@
name: '⏰ Scheduled Integration Tests'
run-name: "Run Integration Tests - ${{ inputs.working-directory-force || 'all libs' }} (Python ${{ inputs.python-version-force || '3.9, 3.11' }})"
name: Scheduled Tests
on:
workflow_dispatch: # Allows maintainers to trigger the workflow manually in GitHub UI
workflow_dispatch: # Allows to trigger the workflow manually in GitHub UI
inputs:
working-directory-force:
type: string
@@ -11,7 +10,7 @@ on:
type: string
description: "Python version to use - defaults to 3.9 and 3.11 in matrix - example value: 3.9"
schedule:
- cron: '0 13 * * *' # Runs daily at 1PM UTC (9AM EDT/6AM PDT)
- cron: '0 13 * * *'
permissions:
contents: read
@@ -23,16 +22,14 @@ env:
POETRY_LIBS: ("libs/partners/google-vertexai" "libs/partners/google-genai" "libs/partners/aws")
jobs:
# Generate dynamic test matrix based on input parameters or defaults
# Only runs on the main repo (for scheduled runs) or when manually triggered
compute-matrix:
if: github.repository_owner == 'langchain-ai' || github.event_name != 'schedule'
runs-on: ubuntu-latest
name: '📋 Compute Test Matrix'
name: Compute matrix
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: '🔢 Generate Python & Library Matrix'
- name: Set matrix
id: set-matrix
env:
DEFAULT_LIBS: ${{ env.DEFAULT_LIBS }}
@@ -53,11 +50,9 @@ jobs:
matrix="{\"python-version\": $python_version, \"working-directory\": $working_directory}"
echo $matrix
echo "matrix=$matrix" >> $GITHUB_OUTPUT
# Run integration tests against partner libraries with live API credentials
# Tests are run with both Poetry and UV depending on the library's setup
build:
if: github.repository_owner == 'langchain-ai' || github.event_name != 'schedule'
name: '🐍 Python ${{ matrix.python-version }}: ${{ matrix.working-directory }}'
name: Python ${{ matrix.python-version }} - ${{ matrix.working-directory }}
runs-on: ubuntu-latest
needs: [compute-matrix]
timeout-minutes: 20
@@ -80,7 +75,7 @@ jobs:
repository: langchain-ai/langchain-aws
path: langchain-aws
- name: '📦 Organize External Libraries'
- name: Move libs
run: |
rm -rf \
langchain/libs/partners/google-genai \
@@ -89,7 +84,7 @@ jobs:
mv langchain-google/libs/vertexai langchain/libs/partners/google-vertexai
mv langchain-aws/libs/aws langchain/libs/partners/aws
- name: '🐍 Set up Python ${{ matrix.python-version }} + Poetry'
- name: Set up Python ${{ matrix.python-version }} with poetry
if: contains(env.POETRY_LIBS, matrix.working-directory)
uses: "./langchain/.github/actions/poetry_setup"
with:
@@ -98,40 +93,40 @@ jobs:
working-directory: langchain/${{ matrix.working-directory }}
cache-key: scheduled
- name: '🐍 Set up Python ${{ matrix.python-version }} + UV'
- name: Set up Python ${{ matrix.python-version }} + uv
if: "!contains(env.POETRY_LIBS, matrix.working-directory)"
uses: "./langchain/.github/actions/uv_setup"
with:
python-version: ${{ matrix.python-version }}
- name: '🔐 Authenticate to Google Cloud'
- name: 'Authenticate to Google Cloud'
id: 'auth'
uses: google-github-actions/auth@v2
with:
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}'
- name: '🔐 Configure AWS Credentials'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: '📦 Install Dependencies (Poetry)'
- name: Install dependencies (poetry)
if: contains(env.POETRY_LIBS, matrix.working-directory)
run: |
echo "Running scheduled tests, installing dependencies with poetry..."
cd langchain/${{ matrix.working-directory }}
poetry install --with=test_integration,test
- name: '📦 Install Dependencies (UV)'
- name: Install dependencies (uv)
if: "!contains(env.POETRY_LIBS, matrix.working-directory)"
run: |
echo "Running scheduled tests, installing dependencies with uv..."
cd langchain/${{ matrix.working-directory }}
uv sync --group test --group test_integration
- name: '🚀 Run Integration Tests'
- name: Run integration tests
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
@@ -160,15 +155,14 @@ jobs:
cd langchain/${{ matrix.working-directory }}
make integration_tests
- name: '🧹 Clean up External Libraries'
# Clean up external libraries to avoid affecting git status check
run: |
- name: Remove external libraries
run: |
rm -rf \
langchain/libs/partners/google-genai \
langchain/libs/partners/google-vertexai \
langchain/libs/partners/aws
- name: '🧹 Verify Clean Working Directory'
- name: Ensure tests did not create additional files
working-directory: langchain
run: |
set -eu

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.vs/
.vscode/
.idea/
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@@ -1,14 +0,0 @@
{
"MD013": false,
"MD024": {
"siblings_only": true
},
"MD025": false,
"MD033": false,
"MD034": false,
"MD036": false,
"MD041": false,
"MD046": {
"style": "fenced"
}
}

View File

@@ -1,111 +1,111 @@
repos:
- repo: local
hooks:
- id: core
name: format core
language: system
entry: make -C libs/core format
files: ^libs/core/
pass_filenames: false
- id: langchain
name: format langchain
language: system
entry: make -C libs/langchain format
files: ^libs/langchain/
pass_filenames: false
- id: standard-tests
name: format standard-tests
language: system
entry: make -C libs/standard-tests format
files: ^libs/standard-tests/
pass_filenames: false
- id: text-splitters
name: format text-splitters
language: system
entry: make -C libs/text-splitters format
files: ^libs/text-splitters/
pass_filenames: false
- id: anthropic
name: format partners/anthropic
language: system
entry: make -C libs/partners/anthropic format
files: ^libs/partners/anthropic/
pass_filenames: false
- id: chroma
name: format partners/chroma
language: system
entry: make -C libs/partners/chroma format
files: ^libs/partners/chroma/
pass_filenames: false
- id: couchbase
name: format partners/couchbase
language: system
entry: make -C libs/partners/couchbase format
files: ^libs/partners/couchbase/
pass_filenames: false
- id: exa
name: format partners/exa
language: system
entry: make -C libs/partners/exa format
files: ^libs/partners/exa/
pass_filenames: false
- id: fireworks
name: format partners/fireworks
language: system
entry: make -C libs/partners/fireworks format
files: ^libs/partners/fireworks/
pass_filenames: false
- id: groq
name: format partners/groq
language: system
entry: make -C libs/partners/groq format
files: ^libs/partners/groq/
pass_filenames: false
- id: huggingface
name: format partners/huggingface
language: system
entry: make -C libs/partners/huggingface format
files: ^libs/partners/huggingface/
pass_filenames: false
- id: mistralai
name: format partners/mistralai
language: system
entry: make -C libs/partners/mistralai format
files: ^libs/partners/mistralai/
pass_filenames: false
- id: nomic
name: format partners/nomic
language: system
entry: make -C libs/partners/nomic format
files: ^libs/partners/nomic/
pass_filenames: false
- id: ollama
name: format partners/ollama
language: system
entry: make -C libs/partners/ollama format
files: ^libs/partners/ollama/
pass_filenames: false
- id: openai
name: format partners/openai
language: system
entry: make -C libs/partners/openai format
files: ^libs/partners/openai/
pass_filenames: false
- id: prompty
name: format partners/prompty
language: system
entry: make -C libs/partners/prompty format
files: ^libs/partners/prompty/
pass_filenames: false
- id: qdrant
name: format partners/qdrant
language: system
entry: make -C libs/partners/qdrant format
files: ^libs/partners/qdrant/
pass_filenames: false
- id: root
name: format docs, cookbook
language: system
entry: make format
files: ^(docs|cookbook)/
pass_filenames: false
- repo: local
hooks:
- id: core
name: format core
language: system
entry: make -C libs/core format
files: ^libs/core/
pass_filenames: false
- id: langchain
name: format langchain
language: system
entry: make -C libs/langchain format
files: ^libs/langchain/
pass_filenames: false
- id: standard-tests
name: format standard-tests
language: system
entry: make -C libs/standard-tests format
files: ^libs/standard-tests/
pass_filenames: false
- id: text-splitters
name: format text-splitters
language: system
entry: make -C libs/text-splitters format
files: ^libs/text-splitters/
pass_filenames: false
- id: anthropic
name: format partners/anthropic
language: system
entry: make -C libs/partners/anthropic format
files: ^libs/partners/anthropic/
pass_filenames: false
- id: chroma
name: format partners/chroma
language: system
entry: make -C libs/partners/chroma format
files: ^libs/partners/chroma/
pass_filenames: false
- id: couchbase
name: format partners/couchbase
language: system
entry: make -C libs/partners/couchbase format
files: ^libs/partners/couchbase/
pass_filenames: false
- id: exa
name: format partners/exa
language: system
entry: make -C libs/partners/exa format
files: ^libs/partners/exa/
pass_filenames: false
- id: fireworks
name: format partners/fireworks
language: system
entry: make -C libs/partners/fireworks format
files: ^libs/partners/fireworks/
pass_filenames: false
- id: groq
name: format partners/groq
language: system
entry: make -C libs/partners/groq format
files: ^libs/partners/groq/
pass_filenames: false
- id: huggingface
name: format partners/huggingface
language: system
entry: make -C libs/partners/huggingface format
files: ^libs/partners/huggingface/
pass_filenames: false
- id: mistralai
name: format partners/mistralai
language: system
entry: make -C libs/partners/mistralai format
files: ^libs/partners/mistralai/
pass_filenames: false
- id: nomic
name: format partners/nomic
language: system
entry: make -C libs/partners/nomic format
files: ^libs/partners/nomic/
pass_filenames: false
- id: ollama
name: format partners/ollama
language: system
entry: make -C libs/partners/ollama format
files: ^libs/partners/ollama/
pass_filenames: false
- id: openai
name: format partners/openai
language: system
entry: make -C libs/partners/openai format
files: ^libs/partners/openai/
pass_filenames: false
- id: prompty
name: format partners/prompty
language: system
entry: make -C libs/partners/prompty format
files: ^libs/partners/prompty/
pass_filenames: false
- id: qdrant
name: format partners/qdrant
language: system
entry: make -C libs/partners/qdrant format
files: ^libs/partners/qdrant/
pass_filenames: false
- id: root
name: format docs, cookbook
language: system
entry: make format
files: ^(docs|cookbook)/
pass_filenames: false

View File

@@ -13,7 +13,7 @@ build:
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/api_reference/conf.py
configuration: docs/api_reference/conf.py
# If using Sphinx, optionally build your docs in additional formats such as PDF
formats:
@@ -21,5 +21,5 @@ formats:
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/api_reference/requirements.txt
install:
- requirements: docs/api_reference/requirements.txt

View File

@@ -1,21 +0,0 @@
{
"recommendations": [
"ms-python.python",
"charliermarsh.ruff",
"ms-python.mypy-type-checker",
"ms-toolsai.jupyter",
"ms-toolsai.jupyter-keymap",
"ms-toolsai.jupyter-renderers",
"ms-toolsai.vscode-jupyter-cell-tags",
"ms-toolsai.vscode-jupyter-slideshow",
"yzhang.markdown-all-in-one",
"davidanson.vscode-markdownlint",
"bierner.markdown-mermaid",
"bierner.markdown-preview-github-styles",
"eamodio.gitlens",
"github.vscode-pull-request-github",
"github.vscode-github-actions",
"redhat.vscode-yaml",
"editorconfig.editorconfig",
],
}

82
.vscode/settings.json vendored
View File

@@ -1,82 +0,0 @@
{
"python.analysis.include": [
"libs/**",
"docs/**",
"cookbook/**"
],
"python.analysis.exclude": [
"**/node_modules",
"**/__pycache__",
"**/.pytest_cache",
"**/.*",
"_dist/**",
"docs/_build/**",
"docs/api_reference/_build/**"
],
"python.analysis.autoImportCompletions": true,
"python.analysis.typeCheckingMode": "basic",
"python.testing.cwd": "${workspaceFolder}",
"python.linting.enabled": true,
"python.linting.ruffEnabled": true,
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports.ruff": "explicit",
"source.fixAll": "explicit"
},
"editor.defaultFormatter": "charliermarsh.ruff"
},
"editor.rulers": [
88
],
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.trimAutoWhitespace": true,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.exclude": {
"**/__pycache__": true,
"**/.pytest_cache": true,
"**/*.pyc": true,
"**/.mypy_cache": true,
"**/.ruff_cache": true,
"_dist/**": true,
"docs/_build/**": true,
"docs/api_reference/_build/**": true,
"**/node_modules": true,
"**/.git": false
},
"search.exclude": {
"**/__pycache__": true,
"**/*.pyc": true,
"_dist/**": true,
"docs/_build/**": true,
"docs/api_reference/_build/**": true,
"**/node_modules": true,
"**/.git": true,
"uv.lock": true,
"yarn.lock": true
},
"git.autofetch": true,
"git.enableSmartCommit": true,
"jupyter.askForKernelRestart": false,
"jupyter.interactiveWindow.textEditor.executeSelection": true,
"[markdown]": {
"editor.wordWrap": "on",
"editor.quickSuggestions": {
"comments": "off",
"strings": "off",
"other": "off"
}
},
"[yaml]": {
"editor.tabSize": 2,
"editor.insertSpaces": true
},
"[json]": {
"editor.tabSize": 2,
"editor.insertSpaces": true
},
"python.terminal.activateEnvironment": false,
"python.defaultInterpreterPath": "./.venv/bin/python"
}

325
CLAUDE.md
View File

@@ -1,325 +0,0 @@
# Global Development Guidelines for LangChain Projects
## Core Development Principles
### 1. Maintain Stable Public Interfaces ⚠️ CRITICAL
**Always attempt to preserve function signatures, argument positions, and names for exported/public methods.**
**Bad - Breaking Change:**
```python
def get_user(id, verbose=False): # Changed from `user_id`
pass
```
**Good - Stable Interface:**
```python
def get_user(user_id: str, verbose: bool = False) -> User:
"""Retrieve user by ID with optional verbose output."""
pass
```
**Before making ANY changes to public APIs:**
- Check if the function/class is exported in `__init__.py`
- Look for existing usage patterns in tests and examples
- Use keyword-only arguments for new parameters: `*, new_param: str = "default"`
- Mark experimental features clearly with docstring warnings (using reStructuredText, like `.. warning::`)
🧠 *Ask yourself:* "Would this change break someone's code if they used it last week?"
### 2. Code Quality Standards
**All Python code MUST include type hints and return types.**
**Bad:**
```python
def p(u, d):
return [x for x in u if x not in d]
```
**Good:**
```python
def filter_unknown_users(users: list[str], known_users: set[str]) -> list[str]:
"""Filter out users that are not in the known users set.
Args:
users: List of user identifiers to filter.
known_users: Set of known/valid user identifiers.
Returns:
List of users that are not in the known_users set.
"""
return [user for user in users if user not in known_users]
```
**Style Requirements:**
- Use descriptive, **self-explanatory variable names**. Avoid overly short or cryptic identifiers.
- Attempt to break up complex functions (>20 lines) into smaller, focused functions where it makes sense
- Avoid unnecessary abstraction or premature optimization
- Follow existing patterns in the codebase you're modifying
### 3. Testing Requirements
**Every new feature or bugfix MUST be covered by unit tests.**
**Test Organization:**
- Unit tests: `tests/unit_tests/` (no network calls allowed)
- Integration tests: `tests/integration_tests/` (network calls permitted)
- Use `pytest` as the testing framework
**Test Quality Checklist:**
- [ ] Tests fail when your new logic is broken
- [ ] Happy path is covered
- [ ] Edge cases and error conditions are tested
- [ ] Use fixtures/mocks for external dependencies
- [ ] Tests are deterministic (no flaky tests)
Checklist questions:
- [ ] Does the test suite fail if your new logic is broken?
- [ ] Are all expected behaviors exercised (happy path, invalid input, etc)?
- [ ] Do tests use fixtures or mocks where needed?
```python
def test_filter_unknown_users():
"""Test filtering unknown users from a list."""
users = ["alice", "bob", "charlie"]
known_users = {"alice", "bob"}
result = filter_unknown_users(users, known_users)
assert result == ["charlie"]
assert len(result) == 1
```
### 4. Security and Risk Assessment
**Security Checklist:**
- No `eval()`, `exec()`, or `pickle` on user-controlled input
- Proper exception handling (no bare `except:`) and use a `msg` variable for error messages
- Remove unreachable/commented code before committing
- Race conditions or resource leaks (file handles, sockets, threads).
- Ensure proper resource cleanup (file handles, connections)
**Bad:**
```python
def load_config(path):
with open(path) as f:
return eval(f.read()) # ⚠️ Never eval config
```
**Good:**
```python
import json
def load_config(path: str) -> dict:
with open(path) as f:
return json.load(f)
```
### 5. Documentation Standards
**Use Google-style docstrings with Args section for all public functions.**
**Insufficient Documentation:**
```python
def send_email(to, msg):
"""Send an email to a recipient."""
```
**Complete Documentation:**
```python
def send_email(to: str, msg: str, *, priority: str = "normal") -> bool:
"""
Send an email to a recipient with specified priority.
Args:
to: The email address of the recipient.
msg: The message body to send.
priority: Email priority level (``'low'``, ``'normal'``, ``'high'``).
Returns:
True if email was sent successfully, False otherwise.
Raises:
InvalidEmailError: If the email address format is invalid.
SMTPConnectionError: If unable to connect to email server.
"""
```
**Documentation Guidelines:**
- Types go in function signatures, NOT in docstrings
- Focus on "why" rather than "what" in descriptions
- Document all parameters, return values, and exceptions
- Keep descriptions concise but clear
- Use reStructuredText for docstrings to enable rich formatting
📌 *Tip:* Keep descriptions concise but clear. Only document return values if non-obvious.
### 6. Architectural Improvements
**When you encounter code that could be improved, suggest better designs:**
**Poor Design:**
```python
def process_data(data, db_conn, email_client, logger):
# Function doing too many things
validated = validate_data(data)
result = db_conn.save(validated)
email_client.send_notification(result)
logger.log(f"Processed {len(data)} items")
return result
```
**Better Design:**
```python
@dataclass
class ProcessingResult:
"""Result of data processing operation."""
items_processed: int
success: bool
errors: List[str] = field(default_factory=list)
class DataProcessor:
"""Handles data validation, storage, and notification."""
def __init__(self, db_conn: Database, email_client: EmailClient):
self.db = db_conn
self.email = email_client
def process(self, data: List[dict]) -> ProcessingResult:
"""Process and store data with notifications."""
validated = self._validate_data(data)
result = self.db.save(validated)
self._notify_completion(result)
return result
```
**Design Improvement Areas:**
If there's a **cleaner**, **more scalable**, or **simpler** design, highlight it and suggest improvements that would:
- Reduce code duplication through shared utilities
- Make unit testing easier
- Improve separation of concerns (single responsibility)
- Make unit testing easier through dependency injection
- Add clarity without adding complexity
- Prefer dataclasses for structured data
## Development Tools & Commands
### Package Management
```bash
# Add package
uv add package-name
# Sync project dependencies
uv sync
uv lock
```
### Testing
```bash
# Run unit tests (no network)
make test
# Don't run integration tests, as API keys must be set
# Run specific test file
uv run --group test pytest tests/unit_tests/test_specific.py
```
### Code Quality
```bash
# Lint code
make lint
# Format code
make format
# Type checking
uv run --group lint mypy .
```
### Dependency Management Patterns
**Local Development Dependencies:**
```toml
[tool.uv.sources]
langchain-core = { path = "../core", editable = true }
langchain-tests = { path = "../standard-tests", editable = true }
```
**For tools, use the `@tool` decorator from `langchain_core.tools`:**
```python
from langchain_core.tools import tool
@tool
def search_database(query: str) -> str:
"""Search the database for relevant information.
Args:
query: The search query string.
"""
# Implementation here
return results
```
## Commit Standards
**Use Conventional Commits format for PR titles:**
- `feat(core): add multi-tenant support`
- `fix(cli): resolve flag parsing error`
- `docs: update API usage examples`
- `docs(openai): update API usage examples`
## Framework-Specific Guidelines
- Follow the existing patterns in `langchain-core` for base abstractions
- Use `langchain_core.callbacks` for execution tracking
- Implement proper streaming support where applicable
- Avoid deprecated components like legacy `LLMChain`
### Partner Integrations
- Follow the established patterns in existing partner libraries
- Implement standard interfaces (`BaseChatModel`, `BaseEmbeddings`, etc.)
- Include comprehensive integration tests
- Document API key requirements and authentication
---
## Quick Reference Checklist
Before submitting code changes:
- [ ] **Breaking Changes**: Verified no public API changes
- [ ] **Type Hints**: All functions have complete type annotations
- [ ] **Tests**: New functionality is fully tested
- [ ] **Security**: No dangerous patterns (eval, silent failures, etc.)
- [ ] **Documentation**: Google-style docstrings for public functions
- [ ] **Code Quality**: `make lint` and `make format` pass
- [ ] **Architecture**: Suggested improvements where applicable
- [ ] **Commit Message**: Follows Conventional Commits format

View File

@@ -7,5 +7,5 @@ Please see the following guides for migrating LangChain code:
* Migrating from [LangChain 0.0.x Chains](https://python.langchain.com/docs/versions/migrating_chains/)
* Upgrade to [LangGraph Memory](https://python.langchain.com/docs/versions/migrating_memory/)
The [LangChain CLI](https://python.langchain.com/docs/versions/v0_3/#migrate-using-langchain-cli) can help you automatically upgrade your code to use non-deprecated imports.
The [LangChain CLI](https://python.langchain.com/docs/versions/v0_3/#migrate-using-langchain-cli) can help you automatically upgrade your code to use non-deprecated imports.
This will be especially helpful if you're still on either version 0.0.x or 0.1.x of LangChain.

View File

@@ -8,6 +8,9 @@ help: Makefile
@printf "\n\033[1mUsage: make <TARGETS> ...\033[0m\n\n\033[1mTargets:\033[0m\n\n"
@sed -n 's/^## //p' $< | awk -F':' '{printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | sort | sed -e 's/^/ /'
## all: Default target, shows help.
all: help
## clean: Clean documentation and API documentation artifacts.
clean: docs_clean api_docs_clean
@@ -16,79 +19,49 @@ clean: docs_clean api_docs_clean
######################
## docs_build: Build the documentation.
docs_build: docs_clean
@echo "📚 Building LangChain documentation..."
docs_build:
cd docs && make build
@echo "✅ Documentation build complete!"
## docs_clean: Clean the documentation build artifacts.
docs_clean:
@echo "🧹 Cleaning documentation artifacts..."
cd docs && make clean
@echo "✅ LangChain documentation cleaned"
## docs_linkcheck: Run linkchecker on the documentation.
docs_linkcheck:
@echo "🔗 Checking documentation links..."
@if [ -d _dist/docs ]; then \
uv run --group test linkchecker _dist/docs/ --ignore-url node_modules; \
else \
echo "⚠️ Documentation not built. Run 'make docs_build' first."; \
exit 1; \
fi
@echo "✅ Link check complete"
uv run --no-group test linkchecker _dist/docs/ --ignore-url node_modules
## api_docs_build: Build the API Reference documentation.
api_docs_build: clean
@echo "📖 Building API Reference documentation..."
uv pip install -e libs/cli
uv run --group docs python docs/api_reference/create_api_rst.py
cd docs/api_reference && uv run --group docs make html
uv run --group docs python docs/api_reference/scripts/custom_formatter.py docs/api_reference/_build/html/
@echo "✅ API documentation built"
@echo "🌐 Opening documentation in browser..."
open docs/api_reference/_build/html/reference.html
api_docs_build:
uv run --no-group test python docs/api_reference/create_api_rst.py
cd docs/api_reference && uv run --no-group test make html
uv run --no-group test python docs/api_reference/scripts/custom_formatter.py docs/api_reference/_build/html/
API_PKG ?= text-splitters
api_docs_quick_preview: clean
@echo "⚡ Building quick API preview for $(API_PKG)..."
uv run --group docs python docs/api_reference/create_api_rst.py $(API_PKG)
cd docs/api_reference && uv run --group docs make html
uv run --group docs python docs/api_reference/scripts/custom_formatter.py docs/api_reference/_build/html/
@echo "🌐 Opening preview in browser..."
api_docs_quick_preview:
uv run --no-group test python docs/api_reference/create_api_rst.py $(API_PKG)
cd docs/api_reference && uv run make html
uv run --no-group test python docs/api_reference/scripts/custom_formatter.py docs/api_reference/_build/html/
open docs/api_reference/_build/html/reference.html
## api_docs_clean: Clean the API Reference documentation build artifacts.
api_docs_clean:
@echo "🧹 Cleaning API documentation artifacts..."
find ./docs/api_reference -name '*_api_reference.rst' -delete
git clean -fdX ./docs/api_reference
rm -f docs/api_reference/index.md
@echo "✅ API documentation cleaned"
## api_docs_linkcheck: Run linkchecker on the API Reference documentation.
api_docs_linkcheck:
@echo "🔗 Checking API documentation links..."
@if [ -f docs/api_reference/_build/html/index.html ]; then \
uv run --group test linkchecker docs/api_reference/_build/html/index.html; \
else \
echo "⚠️ API documentation not built. Run 'make api_docs_build' first."; \
exit 1; \
fi
@echo "✅ API link check complete"
uv run --no-group test linkchecker docs/api_reference/_build/html/index.html
## spell_check: Run codespell on the project.
spell_check:
@echo "✏️ Checking spelling across project..."
uv run --group codespell codespell --toml pyproject.toml
@echo "✅ Spell check complete"
uv run --no-group test codespell --toml pyproject.toml
## spell_fix: Run codespell on the project and fix the errors.
spell_fix:
@echo "✏️ Fixing spelling errors across project..."
uv run --group codespell codespell --toml pyproject.toml -w
@echo "✅ Spelling errors fixed"
uv run --no-group test codespell --toml pyproject.toml -w
######################
# LINTING AND FORMATTING
@@ -96,7 +69,6 @@ spell_fix:
## lint: Run linting on the project.
lint lint_package lint_tests:
@echo "🔍 Running code linting and checks..."
uv run --group lint ruff check docs cookbook
uv run --group lint ruff format docs cookbook cookbook --diff
git --no-pager grep 'from langchain import' docs cookbook | grep -vE 'from langchain import (hub)' && echo "Error: no importing langchain from root in docs, except for hub" && exit 1 || exit 0
@@ -104,16 +76,11 @@ lint lint_package lint_tests:
git --no-pager grep 'api.python.langchain.com' -- docs/docs ':!docs/docs/additional_resources/arxiv_references.mdx' ':!docs/docs/integrations/document_loaders/sitemap.ipynb' || exit 0 && \
echo "Error: you should link python.langchain.com/api_reference, not api.python.langchain.com in the docs" && \
exit 1
@echo "✅ Linting complete"
## format: Format the project files.
format format_diff:
@echo "🎨 Formatting project files..."
uv run --group lint ruff format docs cookbook
uv run --group lint ruff check --fix docs cookbook
@echo "✅ Formatting complete"
update-package-downloads:
@echo "📊 Updating package download statistics..."
uv run python docs/scripts/packages_yml_get_downloads.py
@echo "✅ Package downloads updated"

View File

@@ -15,7 +15,7 @@
[![GitHub star chart](https://img.shields.io/github/stars/langchain-ai/langchain?style=flat-square)](https://star-history.com/#langchain-ai/langchain)
[![Open Issues](https://img.shields.io/github/issues-raw/langchain-ai/langchain?style=flat-square)](https://github.com/langchain-ai/langchain/issues)
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode&style=flat-square)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/langchain-ai/langchain)
[<img src="https://github.com/codespaces/badge.svg" alt="Open in Github Codespace" title="Open in Github Codespace" width="150" height="20">](https://codespaces.new/langchain-ai/langchain)
[<img src="https://github.com/codespaces/badge.svg" title="Open in Github Codespace" width="150" height="20">](https://codespaces.new/langchain-ai/langchain)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/langchainai.svg?style=social&label=Follow%20%40LangChainAI)](https://twitter.com/langchainai)
[![CodSpeed Badge](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/langchain-ai/langchain)
@@ -40,10 +40,9 @@ controllable agent workflows.
## Why use LangChain?
LangChain helps developers build applications powered by LLMs through a standard
interface for models, embeddings, vector stores, and more.
interface for models, embeddings, vector stores, and more.
Use LangChain for:
- **Real-time data augmentation**. Easily connect LLMs to diverse data sources and
external / internal systems, drawing from LangChains vast library of integrations with
model providers, tools, vector stores, retrievers, and more.
@@ -53,10 +52,9 @@ frontier evolves, adapt quickly — LangChains abstractions keep you moving w
losing momentum.
## LangChains ecosystem
While the LangChain framework can be used standalone, it also integrates seamlessly
with any LangChain product, giving developers a full suite of tools when building LLM
applications.
applications.
To improve your LLM application development, pair LangChain with:
@@ -75,13 +73,11 @@ teams — and iterate quickly with visual prototyping in
[LangGraph Studio](https://langchain-ai.github.io/langgraph/concepts/langgraph_studio/).
## Additional resources
- [Tutorials](https://python.langchain.com/docs/tutorials/): Simple walkthroughs with
guided examples on getting started with LangChain.
- [How-to Guides](https://python.langchain.com/docs/how_to/): Quick, actionable code
snippets for topics such as tool calling, RAG use cases, and more.
- [Conceptual Guides](https://python.langchain.com/docs/concepts/): Explanations of key
concepts behind the LangChain framework.
- [LangChain Forum](https://forum.langchain.com/): Connect with the community and share all of your technical questions, ideas, and feedback.
- [API Reference](https://python.langchain.com/api_reference/): Detailed reference on
navigating base packages and integrations for LangChain.

View File

@@ -11,7 +11,6 @@ When building such applications developers should remember to follow good securi
* [**Defense in Depth**](https://en.wikipedia.org/wiki/Defense_in_depth_(computing)): No security technique is perfect. Fine-tuning and good chain design can reduce, but not eliminate, the odds that a Large Language Model (LLM) may make a mistake. It's best to combine multiple layered security approaches rather than relying on any single layer of defense to ensure security. For example: use both read-only permissions and sandboxing to ensure that LLMs are only able to access data that is explicitly meant for them to use.
Risks of not doing so include, but are not limited to:
* Data corruption or loss.
* Unauthorized access to confidential information.
* Compromised performance or availability of critical resources.
@@ -28,17 +27,19 @@ design and secure your applications.
## Reporting OSS Vulnerabilities
LangChain is partnered with [huntr by Protect AI](https://huntr.com/) to provide
a bounty program for our open source projects.
LangChain is partnered with [huntr by Protect AI](https://huntr.com/) to provide
a bounty program for our open source projects.
Please report security vulnerabilities associated with the LangChain
open source projects at [huntr](https://huntr.com/bounties/disclose/?target=https%3A%2F%2Fgithub.com%2Flangchain-ai%2Flangchain&validSearch=true).
Please report security vulnerabilities associated with the LangChain
open source projects by visiting the following link:
[https://huntr.com/bounties/disclose/](https://huntr.com/bounties/disclose/?target=https%3A%2F%2Fgithub.com%2Flangchain-ai%2Flangchain&validSearch=true)
Before reporting a vulnerability, please review:
1) In-Scope Targets and Out-of-Scope Targets below.
2) The [langchain-ai/langchain](https://python.langchain.com/docs/contributing/repo_structure) monorepo structure.
3) The [Best Practices](#best-practices) above to
3) The [Best practices](#best-practices) above to
understand what we consider to be a security vulnerability vs. developer
responsibility.
@@ -46,39 +47,39 @@ Before reporting a vulnerability, please review:
The following packages and repositories are eligible for bug bounties:
* langchain-core
* langchain (see exceptions)
* langchain-community (see exceptions)
* langgraph
* langserve
- langchain-core
- langchain (see exceptions)
- langchain-community (see exceptions)
- langgraph
- langserve
### Out of Scope Targets
All out of scope targets defined by huntr as well as:
* **langchain-experimental**: This repository is for experimental code and is not
- **langchain-experimental**: This repository is for experimental code and is not
eligible for bug bounties (see [package warning](https://pypi.org/project/langchain-experimental/)), bug reports to it will be marked as interesting or waste of
time and published with no bounty attached.
* **tools**: Tools in either langchain or langchain-community are not eligible for bug
- **tools**: Tools in either langchain or langchain-community are not eligible for bug
bounties. This includes the following directories
* libs/langchain/langchain/tools
* libs/community/langchain_community/tools
* Please review the [Best Practices](#best-practices)
- libs/langchain/langchain/tools
- libs/community/langchain_community/tools
- Please review the [best practices](#best-practices)
for more details, but generally tools interact with the real world. Developers are
expected to understand the security implications of their code and are responsible
for the security of their tools.
* Code documented with security notices. This will be decided on a case by
- Code documented with security notices. This will be decided done on a case by
case basis, but likely will not be eligible for a bounty as the code is already
documented with guidelines for developers that should be followed for making their
application secure.
* Any LangSmith related repositories or APIs (see [Reporting LangSmith Vulnerabilities](#reporting-langsmith-vulnerabilities)).
- Any LangSmith related repositories or APIs (see [Reporting LangSmith Vulnerabilities](#reporting-langsmith-vulnerabilities)).
## Reporting LangSmith Vulnerabilities
Please report security vulnerabilities associated with LangSmith by email to `security@langchain.dev`.
* LangSmith site: [https://smith.langchain.com](https://smith.langchain.com)
* SDK client: [https://github.com/langchain-ai/langsmith-sdk](https://github.com/langchain-ai/langsmith-sdk)
- LangSmith site: https://smith.langchain.com
- SDK client: https://github.com/langchain-ai/langsmith-sdk
### Other Security Concerns

View File

@@ -144,7 +144,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"id": "kWDWfSDBMPl8",
"metadata": {},
"outputs": [
@@ -185,7 +185,7 @@
" )\n",
" # Text summary chain\n",
" model = VertexAI(\n",
" temperature=0, model_name=\"gemini-2.5-flash\", max_tokens=1024\n",
" temperature=0, model_name=\"gemini-2.0-flash-lite-001\", max_tokens=1024\n",
" ).with_fallbacks([empty_response])\n",
" summarize_chain = {\"element\": lambda x: x} | prompt | model | StrOutputParser()\n",
"\n",
@@ -235,7 +235,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"id": "PeK9bzXv3olF",
"metadata": {},
"outputs": [],
@@ -254,7 +254,7 @@
"\n",
"def image_summarize(img_base64, prompt):\n",
" \"\"\"Make image summary\"\"\"\n",
" model = ChatVertexAI(model=\"gemini-2.5-flash\", max_tokens=1024)\n",
" model = ChatVertexAI(model=\"gemini-2.0-flash\", max_tokens=1024)\n",
"\n",
" msg = model.invoke(\n",
" [\n",
@@ -431,7 +431,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 9,
"id": "GlwCErBaCKQW",
"metadata": {},
"outputs": [],
@@ -553,7 +553,7 @@
" \"\"\"\n",
"\n",
" # Multi-modal LLM\n",
" model = ChatVertexAI(temperature=0, model_name=\"gemini-2.5-flash\", max_tokens=1024)\n",
" model = ChatVertexAI(temperature=0, model_name=\"gemini-2.0-flash\", max_tokens=1024)\n",
"\n",
" # RAG pipeline\n",
" chain = (\n",

View File

@@ -229,9 +229,9 @@
" \"smoke\",\n",
" \"temp\",\n",
"]\n",
"assert all([column in df.columns for column in expected_columns]), (\n",
" \"DataFrame does not have the expected columns\"\n",
")"
"assert all(\n",
" [column in df.columns for column in expected_columns]\n",
"), \"DataFrame does not have the expected columns\""
]
},
{

View File

@@ -487,7 +487,7 @@
" print(\"*\" * 40)\n",
" print(\n",
" colored(\n",
" f\"After {i + 1} observations, Tommie's summary is:\\n{tommie.get_summary(force_refresh=True)}\",\n",
" f\"After {i+1} observations, Tommie's summary is:\\n{tommie.get_summary(force_refresh=True)}\",\n",
" \"blue\",\n",
" )\n",
" )\n",

View File

@@ -20,7 +20,11 @@
"cell_type": "markdown",
"id": "5939a54c-3198-4ba4-8346-1cc088c473c0",
"metadata": {},
"source": "##### You can embed text in the same VectorDB space as images, and retrieve text and images as well based on input text or image.\n##### Following link demonstrates that.\n<a> https://python.langchain.com/v0.2/docs/integrations/text_embedding/open_clip/ </a>"
"source": [
"##### You can embed text in the same VectorDB space as images, and retreive text and images as well based on input text or image.\n",
"##### Following link demonstrates that.\n",
"<a> https://python.langchain.com/v0.2/docs/integrations/text_embedding/open_clip/ </a>"
]
},
{
"cell_type": "markdown",
@@ -385,7 +389,7 @@
" ax = axs[idx]\n",
" ax.imshow(img)\n",
" # Assuming similarity is not available in the new data, removed sim_score\n",
" ax.title.set_text(f\"\\nProduct ID: {data['id']}\\n Score: {score}\")\n",
" ax.title.set_text(f\"\\nProduct ID: {data[\"id\"]}\\n Score: {score}\")\n",
" ax.axis(\"off\") # Turn off axis\n",
"\n",
" # Hide any remaining empty subplots\n",
@@ -596,4 +600,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}

View File

@@ -148,11 +148,11 @@
"\n",
" instructions = \"None\"\n",
" for i in range(max_meta_iters):\n",
" print(f\"[Episode {i + 1}/{max_meta_iters}]\")\n",
" print(f\"[Episode {i+1}/{max_meta_iters}]\")\n",
" chain = initialize_chain(instructions, memory=None)\n",
" output = chain.predict(human_input=task)\n",
" for j in range(max_iters):\n",
" print(f\"(Step {j + 1}/{max_iters})\")\n",
" print(f\"(Step {j+1}/{max_iters})\")\n",
" print(f\"Assistant: {output}\")\n",
" print(\"Human: \")\n",
" human_input = input()\n",

View File

@@ -183,7 +183,7 @@
"outputs": [],
"source": [
"game_description = f\"\"\"Here is the topic for a Dungeons & Dragons game: {quest}.\n",
" The characters are: {(*character_names,)}.\n",
" The characters are: {*character_names,}.\n",
" The story is narrated by the storyteller, {storyteller_name}.\"\"\"\n",
"\n",
"player_descriptor_system_message = SystemMessage(\n",
@@ -334,7 +334,7 @@
" You are the storyteller, {storyteller_name}.\n",
" Please make the quest more specific. Be creative and imaginative.\n",
" Please reply with the specified quest in {word_limit} words or less. \n",
" Speak directly to the characters: {(*character_names,)}.\n",
" Speak directly to the characters: {*character_names,}.\n",
" Do not add anything else.\"\"\"\n",
" ),\n",
"]\n",

View File

@@ -200,7 +200,7 @@
"outputs": [],
"source": [
"game_description = f\"\"\"Here is the topic for the presidential debate: {topic}.\n",
"The presidential candidates are: {\", \".join(character_names)}.\"\"\"\n",
"The presidential candidates are: {', '.join(character_names)}.\"\"\"\n",
"\n",
"player_descriptor_system_message = SystemMessage(\n",
" content=\"You can add detail to the description of each presidential candidate.\"\n",
@@ -595,7 +595,7 @@
" Frame the debate topic as a problem to be solved.\n",
" Be creative and imaginative.\n",
" Please reply with the specified topic in {word_limit} words or less. \n",
" Speak directly to the presidential candidates: {(*character_names,)}.\n",
" Speak directly to the presidential candidates: {*character_names,}.\n",
" Do not add anything else.\"\"\"\n",
" ),\n",
"]\n",

View File

@@ -395,7 +395,8 @@
"prompt_messages = [\n",
" SystemMessage(\n",
" content=(\n",
" \"You are a world class algorithm to answer questions in a specific format.\"\n",
" \"You are a world class algorithm to answer \"\n",
" \"questions in a specific format.\"\n",
" )\n",
" ),\n",
" HumanMessage(content=\"Answer question using the following context\"),\n",

View File

@@ -552,7 +552,9 @@
"cell_type": "markdown",
"id": "77deb6a0-0950-450a-916a-f2a029676c20",
"metadata": {},
"source": "**Appending all retrieved documents in a single document**"
"source": [
"**Appending all retreived documents in a single document**"
]
},
{
"cell_type": "code",
@@ -756,4 +758,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}

View File

@@ -34,7 +34,7 @@
"tools = [multiply, exponentiate, add]\n",
"\n",
"gpt35 = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0).bind_tools(tools)\n",
"claude3 = ChatAnthropic(model=\"claude-3-7-sonnet-20250219\").bind_tools(tools)\n",
"claude3 = ChatAnthropic(model=\"claude-3-sonnet-20240229\").bind_tools(tools)\n",
"llm_with_tools = gpt35.configurable_alternatives(\n",
" ConfigurableField(id=\"llm\"), default_key=\"gpt35\", claude3=claude3\n",
")"
@@ -113,15 +113,14 @@
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content=\"what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241\", additional_kwargs={}, response_metadata={}),\n",
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_xuNXwm2P6U2Pp2pAbC1sdIBz', 'function': {'arguments': '{\"x\": 3, \"y\": 5}', 'name': 'add'}, 'type': 'function'}, {'id': 'call_0pImUJUDlYa5zfBcxxuvWyYS', 'function': {'arguments': '{\"x\": 8, \"y\": 2.743}', 'name': 'exponentiate'}, 'type': 'function'}, {'id': 'call_yaownQ9TZK0dkqD1KSFyax4H', 'function': {'arguments': '{\"x\": 17.24, \"y\": -918.1241}', 'name': 'add'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 75, 'prompt_tokens': 131, 'total_tokens': 206, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'id': 'chatcmpl-ByJm2qxSWU3oTTSZQv64J4XQKZhA6', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--35fad027-47f7-44d3-aa8b-99f4fc24098c-0', tool_calls=[{'name': 'add', 'args': {'x': 3, 'y': 5}, 'id': 'call_xuNXwm2P6U2Pp2pAbC1sdIBz', 'type': 'tool_call'}, {'name': 'exponentiate', 'args': {'x': 8, 'y': 2.743}, 'id': 'call_0pImUJUDlYa5zfBcxxuvWyYS', 'type': 'tool_call'}, {'name': 'add', 'args': {'x': 17.24, 'y': -918.1241}, 'id': 'call_yaownQ9TZK0dkqD1KSFyax4H', 'type': 'tool_call'}], usage_metadata={'input_tokens': 131, 'output_tokens': 75, 'total_tokens': 206, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}),\n",
" ToolMessage(content='8.0', tool_call_id='call_xuNXwm2P6U2Pp2pAbC1sdIBz'),\n",
" ToolMessage(content='300.03770462067547', tool_call_id='call_0pImUJUDlYa5zfBcxxuvWyYS'),\n",
" ToolMessage(content='-900.8841', tool_call_id='call_yaownQ9TZK0dkqD1KSFyax4H'),\n",
" AIMessage(content='The results are:\\n1. 3 plus 5 is 8.\\n2. 5 raised to the power of 2.743 is approximately 300.04.\\n3. 17.24 minus 918.1241 is approximately -900.88.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 55, 'prompt_tokens': 236, 'total_tokens': 291, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'id': 'chatcmpl-ByJm345MYnpowGS90iAZAlSs7haed', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--5fa66d47-d80e-45d0-9c32-31348c735d72-0', usage_metadata={'input_tokens': 236, 'output_tokens': 55, 'total_tokens': 291, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}"
"{'messages': [HumanMessage(content=\"what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241\"),\n",
" AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_6yMU2WsS4Bqgi1WxFHxtfJRc', 'function': {'arguments': '{\"x\": 8, \"y\": 2.743}', 'name': 'exponentiate'}, 'type': 'function'}, {'id': 'call_GAL3dQiKFF9XEV0RrRLPTvVp', 'function': {'arguments': '{\"x\": 17.24, \"y\": -918.1241}', 'name': 'add'}, 'type': 'function'}]}, response_metadata={'token_usage': {'completion_tokens': 58, 'prompt_tokens': 168, 'total_tokens': 226}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-528302fc-7acf-4c11-82c4-119ccf40c573-0', tool_calls=[{'name': 'exponentiate', 'args': {'x': 8, 'y': 2.743}, 'id': 'call_6yMU2WsS4Bqgi1WxFHxtfJRc'}, {'name': 'add', 'args': {'x': 17.24, 'y': -918.1241}, 'id': 'call_GAL3dQiKFF9XEV0RrRLPTvVp'}]),\n",
" ToolMessage(content='300.03770462067547', tool_call_id='call_6yMU2WsS4Bqgi1WxFHxtfJRc'),\n",
" ToolMessage(content='-900.8841', tool_call_id='call_GAL3dQiKFF9XEV0RrRLPTvVp'),\n",
" AIMessage(content='The result of \\\\(3 + 5^{2.743}\\\\) is approximately 300.04, and the result of \\\\(17.24 - 918.1241\\\\) is approximately -900.88.', response_metadata={'token_usage': {'completion_tokens': 44, 'prompt_tokens': 251, 'total_tokens': 295}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None}, id='run-d1161669-ed09-4b18-94bd-6d8530df5aa8-0')]}"
]
},
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -147,17 +146,17 @@
{
"data": {
"text/plain": [
"{'messages': [HumanMessage(content=\"what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241\", additional_kwargs={}, response_metadata={}),\n",
" AIMessage(content=[{'text': \"I'll solve these calculations for you.\\n\\nFor the first part, I need to calculate 3 plus 5 raised to the power of 2.743.\\n\\nLet me break this down:\\n1) First, I'll calculate 5 raised to the power of 2.743\\n2) Then add 3 to the result\", 'type': 'text'}, {'id': 'toolu_01L1mXysBQtpPLQ2AZTaCGmE', 'input': {'x': 5, 'y': 2.743}, 'name': 'exponentiate', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_01HCbDmuzdg9ATMyKbnecbEE', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 563, 'output_tokens': 146, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'}, id='run--9f6469fb-bcbb-4c1c-9eec-79f6979c38e6-0', tool_calls=[{'name': 'exponentiate', 'args': {'x': 5, 'y': 2.743}, 'id': 'toolu_01L1mXysBQtpPLQ2AZTaCGmE', 'type': 'tool_call'}], usage_metadata={'input_tokens': 563, 'output_tokens': 146, 'total_tokens': 709, 'input_token_details': {'cache_read': 0, 'cache_creation': 0}}),\n",
" ToolMessage(content='82.65606421491815', tool_call_id='toolu_01L1mXysBQtpPLQ2AZTaCGmE'),\n",
" AIMessage(content=[{'text': \"Now I'll add 3 to this result:\", 'type': 'text'}, {'id': 'toolu_01NARC83e9obV35mZ6jYzBiN', 'input': {'x': 3, 'y': 82.65606421491815}, 'name': 'add', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_01ELwyCtVLeGC685PUFqmdz2', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 727, 'output_tokens': 87, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'}, id='run--d5af3d7c-e8b7-4cc2-997a-ad2dafd08751-0', tool_calls=[{'name': 'add', 'args': {'x': 3, 'y': 82.65606421491815}, 'id': 'toolu_01NARC83e9obV35mZ6jYzBiN', 'type': 'tool_call'}], usage_metadata={'input_tokens': 727, 'output_tokens': 87, 'total_tokens': 814, 'input_token_details': {'cache_read': 0, 'cache_creation': 0}}),\n",
" ToolMessage(content='85.65606421491815', tool_call_id='toolu_01NARC83e9obV35mZ6jYzBiN'),\n",
" AIMessage(content=[{'text': \"For the second part, you asked for 17.24 - 918.1241. I don't have a subtraction function available, but I can rewrite this as adding a negative number: 17.24 + (-918.1241)\", 'type': 'text'}, {'id': 'toolu_01Q6fLcZkBWZpMPCZ55WXR3N', 'input': {'x': 17.24, 'y': -918.1241}, 'name': 'add', 'type': 'tool_use'}], additional_kwargs={}, response_metadata={'id': 'msg_01WkmDwUxWjjaKGnTtdLGJnN', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 832, 'output_tokens': 130, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'}, id='run--39a6fbda-4c81-47a6-b361-524bd4ee5823-0', tool_calls=[{'name': 'add', 'args': {'x': 17.24, 'y': -918.1241}, 'id': 'toolu_01Q6fLcZkBWZpMPCZ55WXR3N', 'type': 'tool_call'}], usage_metadata={'input_tokens': 832, 'output_tokens': 130, 'total_tokens': 962, 'input_token_details': {'cache_read': 0, 'cache_creation': 0}}),\n",
" ToolMessage(content='-900.8841', tool_call_id='toolu_01Q6fLcZkBWZpMPCZ55WXR3N'),\n",
" AIMessage(content='So, the answers are:\\n1) 3 plus 5 raised to the 2.743 = 85.65606421491815\\n2) 17.24 - 918.1241 = -900.8841', additional_kwargs={}, response_metadata={'id': 'msg_015Yoc62CvdJbANGFouiQ6AQ', 'model': 'claude-3-7-sonnet-20250219', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 978, 'output_tokens': 58, 'server_tool_use': None, 'service_tier': 'standard'}, 'model_name': 'claude-3-7-sonnet-20250219'}, id='run--174c0882-6180-47ea-8f63-d7b747302327-0', usage_metadata={'input_tokens': 978, 'output_tokens': 58, 'total_tokens': 1036, 'input_token_details': {'cache_read': 0, 'cache_creation': 0}})]}"
"{'messages': [HumanMessage(content=\"what's 3 plus 5 raised to the 2.743. also what's 17.24 - 918.1241\"),\n",
" AIMessage(content=[{'text': \"Okay, let's break this down into two parts:\", 'type': 'text'}, {'id': 'toolu_01DEhqcXkXTtzJAiZ7uMBeDC', 'input': {'x': 3, 'y': 5}, 'name': 'add', 'type': 'tool_use'}], response_metadata={'id': 'msg_01AkLGH8sxMHaH15yewmjwkF', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 450, 'output_tokens': 81}}, id='run-f35bfae8-8ded-4f8a-831b-0940d6ad16b6-0', tool_calls=[{'name': 'add', 'args': {'x': 3, 'y': 5}, 'id': 'toolu_01DEhqcXkXTtzJAiZ7uMBeDC'}]),\n",
" ToolMessage(content='8.0', tool_call_id='toolu_01DEhqcXkXTtzJAiZ7uMBeDC'),\n",
" AIMessage(content=[{'id': 'toolu_013DyMLrvnrto33peAKMGMr1', 'input': {'x': 8.0, 'y': 2.743}, 'name': 'exponentiate', 'type': 'tool_use'}], response_metadata={'id': 'msg_015Fmp8aztwYcce2JDAFfce3', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 545, 'output_tokens': 75}}, id='run-48aaeeeb-a1e5-48fd-a57a-6c3da2907b47-0', tool_calls=[{'name': 'exponentiate', 'args': {'x': 8.0, 'y': 2.743}, 'id': 'toolu_013DyMLrvnrto33peAKMGMr1'}]),\n",
" ToolMessage(content='300.03770462067547', tool_call_id='toolu_013DyMLrvnrto33peAKMGMr1'),\n",
" AIMessage(content=[{'text': 'So 3 plus 5 raised to the 2.743 power is 300.04.\\n\\nFor the second part:', 'type': 'text'}, {'id': 'toolu_01UTmMrGTmLpPrPCF1rShN46', 'input': {'x': 17.24, 'y': -918.1241}, 'name': 'add', 'type': 'tool_use'}], response_metadata={'id': 'msg_015TkhfRBENPib2RWAxkieH6', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 638, 'output_tokens': 105}}, id='run-45fb62e3-d102-4159-881d-241c5dbadeed-0', tool_calls=[{'name': 'add', 'args': {'x': 17.24, 'y': -918.1241}, 'id': 'toolu_01UTmMrGTmLpPrPCF1rShN46'}]),\n",
" ToolMessage(content='-900.8841', tool_call_id='toolu_01UTmMrGTmLpPrPCF1rShN46'),\n",
" AIMessage(content='Therefore, 17.24 - 918.1241 = -900.8841', response_metadata={'id': 'msg_01LgKnRuUcSyADCpxv9tPoYD', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 759, 'output_tokens': 24}}, id='run-1008254e-ccd1-497c-8312-9550dd77bd08-0')]}"
]
},
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
@@ -178,7 +177,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "langchain",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
@@ -192,7 +191,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
"version": "3.10.4"
}
},
"nbformat": 4,

View File

@@ -227,7 +227,7 @@
"outputs": [],
"source": [
"conversation_description = f\"\"\"Here is the topic of conversation: {topic}\n",
"The participants are: {\", \".join(names.keys())}\"\"\"\n",
"The participants are: {', '.join(names.keys())}\"\"\"\n",
"\n",
"agent_descriptor_system_message = SystemMessage(\n",
" content=\"You can add detail to the description of the conversation participant.\"\n",
@@ -396,7 +396,7 @@
" You are the moderator.\n",
" Please make the topic more specific.\n",
" Please reply with the specified quest in {word_limit} words or less. \n",
" Speak directly to the participants: {(*names,)}.\n",
" Speak directly to the participants: {*names,}.\n",
" Do not add anything else.\"\"\"\n",
" ),\n",
"]\n",

View File

@@ -1,9 +1,9 @@
# We build the docs in these stages:
# 1. Install vercel and python dependencies
# 2. Copy files from "source dir" to "intermediate dir"
# 2. Generate files like model feat table, etc in "intermediate dir"
# 3. Copy files to their right spots (e.g. langserve readme) in "intermediate dir"
# 4. Build the docs from "intermediate dir" to "output dir"
# we build the docs in these stages:
# 1. install vercel and python dependencies
# 2. copy files from "source dir" to "intermediate dir"
# 2. generate files like model feat table, etc in "intermediate dir"
# 3. copy files to their right spots (e.g. langserve readme) in "intermediate dir"
# 4. build the docs from "intermediate dir" to "output dir"
SOURCE_DIR = docs/
INTERMEDIATE_DIR = build/intermediate/docs
@@ -18,45 +18,32 @@ PORT ?= 3001
clean:
rm -rf build
clean-cache:
rm -rf build .venv/deps_installed
install-vercel-deps:
yum -y -q update
yum -y -q install gcc bzip2-devel libffi-devel zlib-devel wget tar gzip rsync -y
install-py-deps:
@echo "📦 Installing Python dependencies..."
@if [ ! -d .venv ]; then python3 -m venv .venv; fi
@if [ ! -f .venv/deps_installed ]; then \
$(PYTHON) -m pip install -q --upgrade pip --disable-pip-version-check; \
$(PYTHON) -m pip install -q --upgrade uv; \
$(PYTHON) -m uv pip install -q --pre -r vercel_requirements.txt; \
$(PYTHON) -m uv pip install -q --pre $$($(PYTHON) scripts/partner_deps_list.py) --overrides vercel_overrides.txt; \
touch .venv/deps_installed; \
fi
@echo "✅ Dependencies installed"
python3 -m venv .venv
$(PYTHON) -m pip install -q --upgrade pip
$(PYTHON) -m pip install -q --upgrade uv
$(PYTHON) -m uv pip install -q --pre -r vercel_requirements.txt
$(PYTHON) -m uv pip install -q --pre $$($(PYTHON) scripts/partner_deps_list.py) --overrides vercel_overrides.txt
generate-files:
@echo "📄 Generating documentation files..."
mkdir -p $(INTERMEDIATE_DIR)
cp -rp $(SOURCE_DIR)/* $(INTERMEDIATE_DIR)
@if [ ! -f build/langserve_readme_cache.md ] || [ $$(find build/langserve_readme_cache.md -mtime +1 -print) ]; then \
echo "🌐 Downloading LangServe README..."; \
curl -s https://raw.githubusercontent.com/langchain-ai/langserve/main/README.md | sed 's/<=/\&lt;=/g' > build/langserve_readme_cache.md; \
fi
cp build/langserve_readme_cache.md $(INTERMEDIATE_DIR)/langserve.md
$(PYTHON) scripts/tool_feat_table.py $(INTERMEDIATE_DIR)
$(PYTHON) scripts/kv_store_feat_table.py $(INTERMEDIATE_DIR)
$(PYTHON) scripts/partner_pkg_table.py $(INTERMEDIATE_DIR)
curl https://raw.githubusercontent.com/langchain-ai/langserve/main/README.md | sed 's/<=/\&lt;=/g' > $(INTERMEDIATE_DIR)/langserve.md
cp ../SECURITY.md $(INTERMEDIATE_DIR)/security.md
@echo "🔧 Generating feature tables and processing links..."
$(PYTHON) scripts/tool_feat_table.py $(INTERMEDIATE_DIR) & \
$(PYTHON) scripts/kv_store_feat_table.py $(INTERMEDIATE_DIR) & \
$(PYTHON) scripts/partner_pkg_table.py $(INTERMEDIATE_DIR) & \
$(PYTHON) scripts/resolve_local_links.py $(INTERMEDIATE_DIR)/langserve.md https://github.com/langchain-ai/langserve/tree/main/ & \
wait
@echo "✅ Files generated"
$(PYTHON) scripts/resolve_local_links.py $(INTERMEDIATE_DIR)/langserve.md https://github.com/langchain-ai/langserve/tree/main/
copy-infra:
@echo "📂 Copying infrastructure files..."
mkdir -p $(OUTPUT_NEW_DIR)
cp -r src $(OUTPUT_NEW_DIR)
cp vercel.json $(OUTPUT_NEW_DIR)
@@ -68,22 +55,15 @@ copy-infra:
cp -r static $(OUTPUT_NEW_DIR)
cp -r ../libs/cli/langchain_cli/integration_template $(OUTPUT_NEW_DIR)/src/theme
cp yarn.lock $(OUTPUT_NEW_DIR)
@echo "✅ Infrastructure files copied"
render:
@echo "📓 Converting notebooks (this may take a while)..."
$(PYTHON) scripts/notebook_convert.py $(INTERMEDIATE_DIR) $(OUTPUT_NEW_DOCS_DIR)
@echo "✅ Notebooks converted"
md-sync:
@echo "📝 Syncing markdown files..."
rsync -avmq --include="*/" --include="*.mdx" --include="*.md" --include="*.png" --include="*/_category_.yml" --exclude="*" $(INTERMEDIATE_DIR)/ $(OUTPUT_NEW_DOCS_DIR)
@echo "✅ Markdown files synced"
append-related:
@echo "🔗 Appending related links..."
$(PYTHON) scripts/append_related_links.py $(OUTPUT_NEW_DOCS_DIR)
@echo "✅ Related links appended"
generate-references:
$(PYTHON) scripts/generate_api_reference_links.py --docs_dir $(OUTPUT_NEW_DOCS_DIR)
@@ -91,10 +71,6 @@ generate-references:
update-md: generate-files md-sync
build: install-py-deps generate-files copy-infra render md-sync append-related
@echo ""
@echo "🎉 Documentation build complete!"
@echo "📖 To view locally, run: cd docs && make start"
@echo ""
vercel-build: install-vercel-deps build generate-references
rm -rf docs
@@ -108,9 +84,4 @@ vercel-build: install-vercel-deps build generate-references
NODE_OPTIONS="--max-old-space-size=5000" yarn run docusaurus build
start:
@echo "🚀 Starting documentation server on port $(PORT)..."
@echo "📖 Installing Node.js dependencies..."
cd $(OUTPUT_NEW_DIR) && yarn install --silent
@echo "🌐 Starting server at http://localhost:$(PORT)"
@echo "Press Ctrl+C to stop the server"
cd $(OUTPUT_NEW_DIR) && yarn start --port=$(PORT)
cd $(OUTPUT_NEW_DIR) && yarn && yarn start --port=$(PORT)

View File

@@ -108,7 +108,7 @@ class GalleryGridDirective(SphinxDirective):
# Parse the template with Sphinx Design to create an output container
# Prep the options for the template grid
class_ = "gallery-directive" + f" {self.options.get('class-container', '')}"
class_ = "gallery-directive" + f' {self.options.get("class-container", "")}'
options = {"gutter": 2, "class-container": class_}
options_str = "\n".join(f":{k}: {v}" for k, v in options.items())

View File

@@ -262,8 +262,6 @@ myst_enable_extensions = ["colon_fence"]
# generate autosummary even if no references
autosummary_generate = True
# Don't fail on autosummary import warnings
autosummary_ignore_module_all = False
html_copy_source = False
html_show_sourcelink = False

View File

@@ -97,7 +97,7 @@ def _load_module_members(module_path: str, namespace: str) -> ModuleMembers:
if type(type_) is typing_extensions._TypedDictMeta: # type: ignore
kind: ClassKind = "TypedDict"
elif type(type_) is typing._TypedDictMeta: # type: ignore
kind = "TypedDict"
kind: ClassKind = "TypedDict"
elif (
issubclass(type_, Runnable)
and issubclass(type_, BaseModel)
@@ -189,7 +189,7 @@ def _load_package_modules(
if isinstance(package_directory, str)
else package_directory
)
modules_by_namespace: Dict[str, ModuleMembers] = {}
modules_by_namespace = {}
# Get the high level package name
package_name = package_path.name
@@ -202,12 +202,6 @@ def _load_package_modules(
if file_path.name.startswith("_"):
continue
if "integration_template" in file_path.parts:
continue
if "project_template" in file_path.parts:
continue
relative_module_name = file_path.relative_to(package_path)
# Skip if any module part starts with an underscore
@@ -217,11 +211,7 @@ def _load_package_modules(
# Get the full namespace of the module
namespace = str(relative_module_name).replace(".py", "").replace("/", ".")
# Keep only the top level namespace
# (but make special exception for content_blocks and v1.messages)
if namespace == "messages.content_blocks" or namespace == "v1.messages":
top_namespace = namespace # Keep full namespace for content_blocks
else:
top_namespace = namespace.split(".")[0]
top_namespace = namespace.split(".")[0]
try:
# If submodule is present, we need to construct the paths in a slightly
@@ -277,7 +267,7 @@ def _construct_doc(
.. _{package_namespace}:
======================================
{package_namespace.replace("_", "-")}: {package_version}
{package_namespace.replace('_', '-')}: {package_version}
======================================
.. automodule:: {package_namespace}
@@ -287,7 +277,7 @@ def _construct_doc(
.. toctree::
:hidden:
:maxdepth: 2
"""
index_autosummary = """
"""
@@ -335,7 +325,7 @@ def _construct_doc(
index_autosummary += f"""
:ref:`{package_namespace}_{module}`
{"^" * (len(package_namespace) + len(module) + 8)}
{'^' * (len(package_namespace) + len(module) + 8)}
"""
if classes:
@@ -369,12 +359,12 @@ def _construct_doc(
module_doc += f"""\
:template: {template}
{class_["qualified_name"]}
"""
index_autosummary += f"""
{class_["qualified_name"]}
{class_['qualified_name']}
"""
if functions:
@@ -437,7 +427,7 @@ def _construct_doc(
"""
index_autosummary += f"""
{class_["qualified_name"]}
{class_['qualified_name']}
"""
if deprecated_functions:
@@ -505,7 +495,15 @@ def _package_namespace(package_name: str) -> str:
def _package_dir(package_name: str = "langchain") -> Path:
"""Return the path to the directory containing the documentation."""
if (ROOT_DIR / "libs" / package_name).exists():
if package_name in (
"langchain",
"experimental",
"community",
"core",
"cli",
"text-splitters",
"standard-tests",
):
return ROOT_DIR / "libs" / package_name / _package_namespace(package_name)
else:
return (
@@ -554,8 +552,8 @@ def _build_index(dirs: List[str]) -> None:
integrations = sorted(dir_ for dir_ in dirs if dir_ not in main_)
doc = """# LangChain Python API Reference
Welcome to the LangChain Python API reference. This is a reference for all
`langchain-x` packages.
Welcome to the LangChain Python API reference. This is a reference for all
`langchain-x` packages.
For user guides see [https://python.langchain.com](https://python.langchain.com).
@@ -594,12 +592,7 @@ For the legacy API reference hosted on ReadTheDocs see [https://api.python.langc
if integrations:
integration_headers = [
" ".join(
custom_names.get(
x,
x.title().replace("db", "DB")
if dir_ == "langchain_v1"
else x.title().replace("ai", "AI").replace("db", "DB"),
)
custom_names.get(x, x.title().replace("ai", "AI").replace("db", "DB"))
for x in dir_.split("-")
)
for dir_ in integrations
@@ -667,12 +660,18 @@ def main(dirs: Optional[list] = None) -> None:
print("Starting to build API reference files.")
if not dirs:
dirs = [
p.parent.name
for p in (ROOT_DIR / "libs").rglob("pyproject.toml")
# Exclude packages that are not directly under libs/ or libs/partners/
if p.parent.parent.name in ("libs", "partners")
dir_
for dir_ in os.listdir(ROOT_DIR / "libs")
if dir_ not in ("cli", "partners", "packages.yml")
and "pyproject.toml" in os.listdir(ROOT_DIR / "libs" / dir_)
]
for dir_ in sorted(dirs):
dirs += [
dir_
for dir_ in os.listdir(ROOT_DIR / "libs" / "partners")
if os.path.isdir(ROOT_DIR / "libs" / "partners" / dir_)
and "pyproject.toml" in os.listdir(ROOT_DIR / "libs" / "partners" / dir_)
]
for dir_ in dirs:
# Skip any hidden directories
# Some of these could be present by mistake in the code base
# e.g., .pytest_cache from running tests from the wrong location.
@@ -683,7 +682,7 @@ def main(dirs: Optional[list] = None) -> None:
print("Building package:", dir_)
_build_rst_file(package_name=dir_)
_build_index(sorted(dirs))
_build_index(dirs)
print("API reference files built.")

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
eNrVVk9vG0UU58+NI59gtEJCQl577V3bjVEOUajaQqMW1VRFbbUazz7vDtmd2c7MxnEjHyg9Iy2foCVRXEUtRQVxgUocOfAFwoHPwpu1nbZO2pReEJYt2/P+zG/e+73f7J3pFijNpXj7IRcGFGUG/+jv7kwV3CpAm7v7GZhERrvnzvZ3C8UPP0iMyXWv0aA5r+uMm6SeUhGzhHJRZzJrcDGUewMZjX+fJkAjTH/34AsNyl2LQZjyZ+tdxbn5uOHVm/Vm0H28xhjkxj0rmIy4iMtH8W2e10gEw5Qa2J+Zyx9pnqecUYux8ZWW4mBdCgEV5vJgEyB3acq34IECneMx4Jt9bagp9J09zAt//jHNQGsaw/eXPluA+/ut9x9fc+0GqXt2O+cYWt73HmJig3Dd/jiH4/v+sDBfBBGbpNztdFv7lxWNM1o+ENJllCXwm02qtWt9lUzdtTSVI/f8bNvy/keH5ESHdQURpuY01eWeUQVM11LjXtli5WE98VedXhD4zscko6ut9krL87xa4rutlRMMJwPYqPppAex9grUtn16hpkZaLbJBFWl5rTZpdnr+Sq/tkXMb/SfXXPSikYzdPrID3AtReUgCGjHw/DPeANrtM34TvKDrddvRwPMhiFr+7lVOywNsLYmljFP49UQklxSPuSjvPV2yYhukhucq9Wjd1nNhL5/kxQDbUcOjbrvYzdWO98tSig20IN+wMZ43XbT1aT8pasRrkk+pIM2Vrkc8r1e97Un3rlI1LvdnoH7q8wx5uAS0ovXXyCmFtr/eubfjzKfH6TlefaXe7To1hwvknGAQInVj7fR2nEEqB6E2EvkBIQg6SCFyera1tWUbbgOY7IqPiSKsuwYTwjbN8hR0mBWp4TlVZjnJ6R44ejjcBkLKQ5xrNV52kCoOmYKK4mHE9dw4RBaiNafjDDm5HJTj6aWgaYjR+niU9l92ag1UseTYaiJHoTFpWPDFkrGcCw0HFUaFmqOj46qsqRSxnXaMD3AKbLgy84VmMKk5I6k2dW4TaCZzsChDLra4AX2E8bY2UYiylSNBbCdfxIRJBtQgUuw3iiE6iiGP7eaFhheqHeUSBfToJIymEBZ5eEvz24gf+RODQlheBXRhFSbBkkc6TJFtGNzsLIyRHIlQQJab8bPoAK023cK7ynW0EA7G1cFa3kq32W55k8l7L1fx1dNUHD+4qhsqzRrYQTdXWCPTsGqszf9I3r89JtVnguA/V+Z9LBhKRzkttjiTSjyqLgyXzQXulCvkmYL/O53di16l98GKVcGHbF4uc+LFd6pUnyycr5LnF0X13Ys7zox7YUJ1glrY9oKgRYdN34dOs93tQDdo+x3Wabc7DIbQHFKGFGM08vzWMPC73UHHY4HfgQ6L2KADqKQZFXyIvLWDy3G0rztHZEfrjNoaf+GKwa91/LpcLfZxAi1DnZs1J2U4cqhIWBdEhWVCxAVDfcOIzRFVM62fMxB/X3+tvc4XCG5jFvSme86Snna4uVfNedNtzCKi53wpC0IVELxHKcqmvfAMGUpFKrVBsrhU6BHYjhK8xDZ1naBGEJMAellmWEPOAUlB5JAowOYDCjep2LdtiJFklqGKWWStkwtDMsa9Iyk+NGRTyFFln7nWyFeFNkTTMS5Ss+S4QKAAiAbLcbs5PkHwrMgwQ0SswDyXzmJhXEP9hvh8vn+P7CygTMgNsT4Di6tz2HZxrQruVQ8CeWHCLaq4vVEsI5xFtO3/LMSWf1HYECuYISt6ztCdjYMzwdfN1041mTx7FkCfm5N/AJjRbLE=

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
eNrVVk9v3EQU58+NI59gZCEhofWud9e7bhb1EIWqLTRqUUNV1FbW7PjZnsaecWfGSbbRHig9I5lP0JIoqaKWooK4QCWOHPgC4cBn4Y13nbbblFTlAlGi3bx/85v3fu9n39nfAKW5FG8/5MKAoszgP/rbO/sKbpWgzd29HEwqo52zZ9Z2SsUPP0iNKfSo06EFb+ucm7SdUZGwlHLRZjLvcBHL3bGMJr/tp0AjLH/34AsNyl1OQJjqJxtd57nFpOO1u+2uHzxeZgwK454RTEZcJNWj5DYvWiSCOKMG9mbu6gdaFBln1GLs3NRSHKxIIaDGXB2sAxQuzfgGPFCgC7wGfL2nDTWlvrOLdeGP3/dz0Jom8N3Fzxpwf731/pOr7ifU0Egm7hp2ANzzUXVIuv0oGPtR7I0DFvS84FTEguBUwOIx+AMPxr9aUFq7CMEombnLWSY33XOzqtX9j54u+M9sFVLDcwGPVihLofFXT4pyjJdrkZxuuYjx9NDbucJpdYAdIomUSQa7V6iaVHsXFU+42LukaJLT6oGQLrOVHl917ZH1SRw7UN339puvT9fSskW8LvmUCtJdCjzieaP6l5xdXdvF60P19DI1LdLrkVWqSM/rDUh3OPK9kd+1MYfk2PuuKIhwrJxmuto1qoSfF8JW8TY4+Wpn6HkPrRGj3bVJAS9P8/iOrtb8sw37cY3nSI65fdaF6t7+cmbcyxusOmyn/dPOyPf7zsfYxNO9wVLP87xW2nd7S8c4fjn2uKbs9w3WCyASkyL+oFfT+ivklEIYf75zb9uZb48zcrz2UjsInJbDBXJOMAiRuol2RtvOOJPjUBuJ84IQBB1nEDkj26zWog+PBix2uY+FIuSkBhPCFs2LDHSYl5nhBVVmscjJEbh6uNwGQspD3Gs1WQyQKgmZgnoYYcT13BnjXNFb0EmOvVhMKvD2UtAsxGz9cpbuv+rWGqhi6UvWVG6GxmRhyRuTsfsYGg4qjEo1R0cndVszKRK77Zjv45htujJzQ9eftpxNqdZ1YQtoJguwKEMuNrgBfYTxtjZRiLJV4JbYSb6ICYuMqUGkOG8UQwwUMU/s4aWGF7odFRIF9OgmjGYQlkV4S/PbiB85lYBCWF4NtPEKk2LLIx1mSGxM7g4bZyQ3RSggL8zkWbaPXluuia5rHRnC8aS+WM9bCrqDnjedvvdqFT99korjH1p1R2V5ByfoFgp7ZDpWjbX5H8n7N/9epmtxddlcpo/kdlGc97AJKAfVfrnBmVTidQXzIZsLjTlWFP9JT3ejk3X7vy2qp3z/RVF998K2M+NemFKdohYOPN/v0bjb78OwOwiGEPiD/pANB4Mhgxi6MWVIMUYjr9+L/X4QjIce8/tDGLKIjYeASppTwWPkrV1cjqt9zTkiO3pn1Nb4DS0GP1bw41JtXMMNtAx1brScjOHKoSLhlBAVDg0Rlwz1DTPWN6maaf2cgfj92mudda5EcKuzpDc9c1b0pMvNo1rOmx5jmoyR86UsCVVA8GWComzaB54hsVSkVhukrkuF3gQ7UYIPsXXdJqgRxKSAUZYR1lFwQKoQGRMFOHxA4Sb1LmwZYiSZVahzmqptcj4mEzw7kuJDQ9aF3Kz9s9AWuVlqQzSdoJGahcAGgQIgGiwL7eH4rsXzMscKEbEC81w5i4VxDe3r4vP5+SOy3UCZkutiZQYWrXPY1rhcJ4/qF4GiNOEGVdw+USwjnCbbzn+WYtvfNDbEDubIipETu7N1cKb4c+O1S02nz94FMObG9G9f2m1A

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More