From f624ad489afaa47b51337349952738d65fd82f9e Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Fri, 25 Jul 2025 14:49:03 -0400 Subject: [PATCH] feat(docs): improve devx, fix `Makefile` targets (#32237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **TL;DR much of the provided `Makefile` targets were broken, and any time I wanted to preview changes locally I either had to refer to a command Chester gave me or try waiting on a Vercel preview deployment. With this PR, everything should behave like normal.** Significant updates to the `Makefile` and documentation files, focusing on improving usability, adding clear messaging, and fixing/enhancing documentation workflows. ### Updates to `Makefile`: #### Enhanced build and cleaning processes: - Added informative messages (e.g., "๐Ÿ“š Building LangChain documentation...") to makefile targets like `docs_build`, `docs_clean`, and `api_docs_build` for better user feedback during execution. - Introduced a `clean-cache` target to the `docs` `Makefile` to clear cached dependencies and ensure clean builds. #### Improved dependency handling: - Modified `install-py-deps` to create a `.venv/deps_installed` marker, preventing redundant/duplicate dependency installations and improving efficiency. #### Streamlined file generation and infrastructure setup: - Added caching for the LangServe README download and parallelized feature table generation - Added user-friendly completion messages for targets like `copy-infra` and `render`. #### Documentation server updates: - Enhanced the `start` target with messages indicating server start and URL for local documentation viewing. --- ### Documentation Improvements: #### Content clarity and consistency: - Standardized section titles for consistency across documentation files. [[1]](diffhunk://#diff-9b1a85ea8a9dcf79f58246c88692cd7a36316665d7e05a69141cfdc50794c82aL1-R1) [[2]](diffhunk://#diff-944008ad3a79d8a312183618401fcfa71da0e69c75803eff09b779fc8e03183dL1-R1) - Refined phrasing and formatting in sections like "Dependency management" and "Formatting and linting" for better readability. [[1]](diffhunk://#diff-2069d4f956ab606ae6d51b191439283798adaf3a6648542c409d258131617059L6-R6) [[2]](diffhunk://#diff-2069d4f956ab606ae6d51b191439283798adaf3a6648542c409d258131617059L84-R82) #### Enhanced workflows: - Updated instructions for building and viewing documentation locally, including tips for specifying server ports and handling API reference previews. [[1]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L60-R94) [[2]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L82-R126) - Expanded guidance on cleaning documentation artifacts and using linting tools effectively. [[1]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L82-R126) [[2]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L107-R142) #### API reference documentation: - Improved instructions for generating and formatting in-code documentation, highlighting best practices for docstring writing. [[1]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L107-R142) [[2]](diffhunk://#diff-048deddcfd44b242e5b23aed9f2e9ec73afc672244ce14df2a0a316d95840c87L144-R186) --- ### Minor Changes: - Added support for a new package name (`langchain_v1`) in the API documentation generation script. - Fixed minor capitalization and formatting issues in documentation files. [[1]](diffhunk://#diff-2069d4f956ab606ae6d51b191439283798adaf3a6648542c409d258131617059L40-R40) [[2]](diffhunk://#diff-2069d4f956ab606ae6d51b191439283798adaf3a6648542c409d258131617059L166-R160) --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Makefile | 66 ++- docs/Makefile | 71 +++- docs/api_reference/conf.py | 2 + docs/api_reference/create_api_rst.py | 8 +- docs/docs/contributing/how_to/code/index.mdx | 2 +- docs/docs/contributing/how_to/code/setup.mdx | 16 +- .../how_to/documentation/index.mdx | 2 +- .../how_to/documentation/setup.mdx | 81 ++-- .../how_to/documentation/style_guide.mdx | 4 +- docs/docs/contributing/how_to/index.mdx | 2 +- .../how_to/integrations/index.mdx | 8 +- .../how_to/integrations/package.mdx | 4 +- docs/docs/contributing/how_to/testing.mdx | 10 +- docs/docs/contributing/index.mdx | 2 +- .../contributing/reference/repo_structure.mdx | 2 +- docs/docs/contributing/tutorials/docs.mdx | 8 +- docs/docs/integrations/providers/ibm.mdx | 2 +- .../providers/predictionguard.mdx | 2 +- docs/docs/integrations/providers/premai.md | 80 ++-- docs/scripts/kv_store_feat_table.py | 3 - docs/scripts/notebook_convert.py | 19 +- docs/sidebars.js | 4 +- docs/vercel_overrides.txt | 6 + .../integration_template/Makefile | 2 +- libs/core/Makefile | 2 +- .../core/langchain_core/outputs/llm_result.py | 5 +- libs/core/langchain_core/tools/base.py | 7 +- libs/core/langchain_core/tools/convert.py | 3 +- .../core/langchain_core/tracers/log_stream.py | 2 + libs/core/langchain_core/utils/aiter.py | 5 +- libs/langchain/Makefile | 7 +- .../chains/combine_documents/map_rerank.py | 4 +- .../langchain/chains/conversation/base.py | 1 + .../chains/conversational_retrieval/base.py | 115 +++--- libs/langchain_v1/Makefile | 7 +- libs/partners/anthropic/Makefile | 2 +- libs/partners/chroma/Makefile | 2 +- libs/partners/deepseek/Makefile | 2 +- libs/partners/exa/Makefile | 2 +- libs/partners/fireworks/Makefile | 2 +- libs/partners/groq/Makefile | 2 +- libs/partners/huggingface/Makefile | 2 +- libs/partners/mistralai/Makefile | 2 +- libs/partners/nomic/Makefile | 2 +- libs/partners/ollama/Makefile | 2 +- libs/partners/openai/Makefile | 2 +- libs/partners/perplexity/Makefile | 2 +- libs/partners/prompty/Makefile | 2 +- libs/partners/xai/Makefile | 2 +- libs/standard-tests/Makefile | 2 +- libs/text-splitters/Makefile | 2 +- pyproject.toml | 23 +- uv.lock | 388 +++++++++++++++++- 53 files changed, 761 insertions(+), 246 deletions(-) diff --git a/Makefile b/Makefile index 62b97f600a7..4bcad7bd107 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,6 @@ help: Makefile @printf "\n\033[1mUsage: make ...\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 @@ -19,49 +16,78 @@ clean: docs_clean api_docs_clean ###################### ## docs_build: Build the documentation. -docs_build: +docs_build: docs_clean + @echo "๐Ÿ“š Building LangChain documentation..." 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: - uv run --no-group test linkchecker _dist/docs/ --ignore-url node_modules + @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" ## api_docs_build: Build the API Reference documentation. -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_docs_build: clean + @echo "๐Ÿ“– Building API Reference documentation..." + 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_PKG ?= text-splitters -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/ +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..." 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: - uv run --no-group test linkchecker docs/api_reference/_build/html/index.html + @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" ## spell_check: Run codespell on the project. spell_check: - uv run --no-group test codespell --toml pyproject.toml + @echo "โœ๏ธ Checking spelling across project..." + uv run --group codespell codespell --toml pyproject.toml + @echo "โœ… Spell check complete" ## spell_fix: Run codespell on the project and fix the errors. spell_fix: - uv run --no-group test codespell --toml pyproject.toml -w + @echo "โœ๏ธ Fixing spelling errors across project..." + uv run --group codespell codespell --toml pyproject.toml -w + @echo "โœ… Spelling errors fixed" ###################### # LINTING AND FORMATTING @@ -69,6 +95,7 @@ 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 @@ -76,11 +103,16 @@ 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" diff --git a/docs/Makefile b/docs/Makefile index 43fb70bb105..f400c2bf73f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -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,32 +18,45 @@ 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: - 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 + @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" generate-files: + @echo "๐Ÿ“„ Generating documentation files..." mkdir -p $(INTERMEDIATE_DIR) cp -rp $(SOURCE_DIR)/* $(INTERMEDIATE_DIR) - - $(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/<=/\<=/g' > $(INTERMEDIATE_DIR)/langserve.md + @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/<=/\<=/g' > build/langserve_readme_cache.md; \ + fi + cp build/langserve_readme_cache.md $(INTERMEDIATE_DIR)/langserve.md cp ../SECURITY.md $(INTERMEDIATE_DIR)/security.md - $(PYTHON) scripts/resolve_local_links.py $(INTERMEDIATE_DIR)/langserve.md https://github.com/langchain-ai/langserve/tree/main/ + @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" copy-infra: + @echo "๐Ÿ“‚ Copying infrastructure files..." mkdir -p $(OUTPUT_NEW_DIR) cp -r src $(OUTPUT_NEW_DIR) cp vercel.json $(OUTPUT_NEW_DIR) @@ -55,15 +68,22 @@ 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) @@ -71,6 +91,10 @@ 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 @@ -84,4 +108,9 @@ vercel-build: install-vercel-deps build generate-references NODE_OPTIONS="--max-old-space-size=5000" yarn run docusaurus build start: - cd $(OUTPUT_NEW_DIR) && yarn && yarn start --port=$(PORT) + @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) diff --git a/docs/api_reference/conf.py b/docs/api_reference/conf.py index 22d59f0badf..b61cdaa4ec4 100644 --- a/docs/api_reference/conf.py +++ b/docs/api_reference/conf.py @@ -262,6 +262,8 @@ 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 diff --git a/docs/api_reference/create_api_rst.py b/docs/api_reference/create_api_rst.py index 4dd0152bf69..663a79d2153 100644 --- a/docs/api_reference/create_api_rst.py +++ b/docs/api_reference/create_api_rst.py @@ -497,6 +497,7 @@ def _package_dir(package_name: str = "langchain") -> Path: """Return the path to the directory containing the documentation.""" if package_name in ( "langchain", + "langchain_v1", "experimental", "community", "core", @@ -592,7 +593,12 @@ 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("ai", "AI").replace("db", "DB")) + custom_names.get( + x, + x.title().replace("db", "DB") + if dir_ == "langchain_v1" + else x.title().replace("ai", "AI").replace("db", "DB"), + ) for x in dir_.split("-") ) for dir_ in integrations diff --git a/docs/docs/contributing/how_to/code/index.mdx b/docs/docs/contributing/how_to/code/index.mdx index cd3889bed0c..37c61a4208f 100644 --- a/docs/docs/contributing/how_to/code/index.mdx +++ b/docs/docs/contributing/how_to/code/index.mdx @@ -1,4 +1,4 @@ -# Contribute Code +# Contribute code If you would like to add a new feature or update an existing one, please read the resources below before getting started: diff --git a/docs/docs/contributing/how_to/code/setup.mdx b/docs/docs/contributing/how_to/code/setup.mdx index 00aa5b77076..9ba53d52242 100644 --- a/docs/docs/contributing/how_to/code/setup.mdx +++ b/docs/docs/contributing/how_to/code/setup.mdx @@ -3,7 +3,7 @@ This guide walks through how to run the repository locally and check in your first code. For a [development container](https://containers.dev/), see the [.devcontainer folder](https://github.com/langchain-ai/langchain/tree/master/.devcontainer). -## Dependency Management: `uv` and other env/dependency managers +## Dependency management: `uv` and other env/dependency managers This project utilizes [uv](https://docs.astral.sh/uv/) v0.5+ as a dependency manager. @@ -37,7 +37,7 @@ For this quickstart, start with `langchain`: cd libs/langchain ``` -## Local Development Dependencies +## Local development dependencies Install development requirements (for running langchain, running examples, linting, formatting, tests, and coverage): @@ -64,12 +64,6 @@ To run unit tests: make test ``` -To run unit tests in Docker: - -```bash -make docker_tests -``` - There are also [integration tests and code-coverage](../testing.mdx) available. ### Developing langchain_core @@ -81,11 +75,11 @@ cd libs/core make test ``` -## Formatting and Linting +## Formatting and linting Run these locally before submitting a PR; the CI system will check also. -### Code Formatting +### Code formatting Formatting for this project is done via [ruff](https://docs.astral.sh/ruff/rules/). @@ -163,7 +157,7 @@ If codespell is incorrectly flagging a word, you can skip spellcheck for that wo ignore-words-list = 'momento,collison,ned,foor,reworkd,parth,whats,aapply,mysogyny,unsecure' ``` -## Working with Optional Dependencies +## Working with optional dependencies `langchain`, `langchain-community`, and `langchain-experimental` rely on optional dependencies to keep these packages lightweight. diff --git a/docs/docs/contributing/how_to/documentation/index.mdx b/docs/docs/contributing/how_to/documentation/index.mdx index 53e3cb05271..345793c06a1 100644 --- a/docs/docs/contributing/how_to/documentation/index.mdx +++ b/docs/docs/contributing/how_to/documentation/index.mdx @@ -1,4 +1,4 @@ -# Contribute Documentation +# Contribute documentation Documentation is a vital part of LangChain. We welcome both new documentation for new features and community improvements to our current documentation. Please read the resources below before getting started: diff --git a/docs/docs/contributing/how_to/documentation/setup.mdx b/docs/docs/contributing/how_to/documentation/setup.mdx index d7ad896d74a..4a665208c2e 100644 --- a/docs/docs/contributing/how_to/documentation/setup.mdx +++ b/docs/docs/contributing/how_to/documentation/setup.mdx @@ -12,12 +12,11 @@ It covers a wide array of topics, including tutorials, use cases, integrations, and more, offering extensive guidance on building with LangChain. The content for this documentation lives in the `/docs` directory of the monorepo. 2. In-code Documentation: This is documentation of the codebase itself, which is also -used to generate the externally facing [API Reference](https://python.langchain.com/api_reference/langchain/index.html). +used to generate the externally facing [API Reference](https://python.langchain.com/api_reference/). The content for the API reference is autogenerated by scanning the docstrings in the codebase. For this reason we ask that developers document their code well. -The `API Reference` is largely autogenerated by [sphinx](https://www.sphinx-doc.org/en/master/) -from the code and is hosted by [Read the Docs](https://readthedocs.org/). +The API Reference is largely autogenerated by [sphinx](https://www.sphinx-doc.org/en/master/) from the code. We appreciate all contributions to the documentation, whether it be fixing a typo, adding a new tutorial or example and whether it be in the main documentation or the API Reference. @@ -25,7 +24,7 @@ adding a new tutorial or example and whether it be in the main documentation or Similar to linting, we recognize documentation can be annoying. If you do not want to do it, please contact a project maintainer, and they can help you with it. We do not want this to be a blocker for good code getting contributed. -## ๐Ÿ“œ Main Documentation +## ๐Ÿ“œ Main documentation The content for the main documentation is located in the `/docs` directory of the monorepo. @@ -42,7 +41,7 @@ After modifying the documentation: 3. Make a pull request with the changes. 4. You can preview and verify that the changes are what you wanted by clicking the `View deployment` or `Visit Preview` buttons on the pull request `Conversation` page. This will take you to a preview of the documentation changes. -## โš’๏ธ Linting and Building Documentation Locally +## โš’๏ธ Linting and building documentation locally After writing up the documentation, you may want to lint and build the documentation locally to ensure that it looks good and is free of errors. @@ -57,20 +56,44 @@ The code that builds the documentation is located in the `/docs` directory of th In the following commands, the prefix `api_` indicates that those are operations for the API Reference. -Before building the documentation, it is always a good idea to clean the build directory: - -```bash -make docs_clean -make api_docs_clean -``` - -Next, you can build the documentation as outlined below: +You can build the documentation as outlined below: ```bash make docs_build make api_docs_build ``` +### Viewing documentation locally + +After building the main documentation, you can view it locally by starting a development server: + +```bash +# For main documentation (after running `make docs_build`) +cd docs && make start +``` + +This will start a development server where you can view the documentation in your browser. The exact url will be shown to you during the start process. The server will automatically reload when you make changes to the documentation files under the `build/` directory (e.g. for temporary tests - changes you wish to persist should be put under `docs/docs/`). + +:::tip + +You can specify a different port by setting the `PORT` environment variable: + +```bash +cd docs && PORT=3000 make start +``` + +::: + +The API Reference documentation is built as static HTML files and will be automatically opened directly in your browser. + +You can also view the API Reference for a specific package by specifying the package name and installing the package if necessary dependencies: + +```bash +# Opens the API Reference for the `ollama` package in your default browser +uv pip install -e libs/partners/ollama +make api_docs_quick_preview API_PKG=ollama +``` + :::tip The `make api_docs_build` command takes a long time. If you're making cosmetic changes to the API docs and want to see how they look, use: @@ -79,18 +102,28 @@ The `make api_docs_build` command takes a long time. If you're making cosmetic c make api_docs_quick_preview ``` -which will just build a small subset of the API reference. +which will just build a small subset of the API reference (the `text-splitters` package). ::: -Finally, run the link checker to ensure all links are valid: +Finally, run the link checker from the project root to ensure all links are valid: ```bash make docs_linkcheck make api_docs_linkcheck ``` -### Linting and Formatting +To clean up the documentation build artifacts, you can run: + +```bash +make clean + +# Or to clean specific documentation artifacts +make docs_clean +make api_docs_clean +``` + +### Formatting and linting The Main Documentation is linted from the **monorepo root**. To lint the main documentation, run the following from there: @@ -104,9 +137,9 @@ If you have formatting-related errors, you can fix them automatically with: make format ``` -## โŒจ๏ธ In-code Documentation +## โŒจ๏ธ In-code documentation -The in-code documentation is largely autogenerated by [sphinx](https://www.sphinx-doc.org/en/master/) from the code and is hosted by [Read the Docs](https://readthedocs.org/). +The in-code documentation is largely autogenerated by [sphinx](https://www.sphinx-doc.org/en/master/) from the code following [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html). For the API reference to be useful, the codebase must be well-documented. This means that all functions, classes, and methods should have a docstring that explains what they do, what the arguments are, and what the return value is. This is a good practice in general, but it is especially important for LangChain because the API reference is the primary resource for developers to understand how to use the codebase. @@ -141,16 +174,16 @@ def my_function(arg1: int, arg2: str) -> float: return 3.14 ``` -### Linting and Formatting +### Formatting and linting The in-code documentation is linted from the directories belonging to the packages being documented. -For example, if you're working on the `langchain-community` package, you would change -the working directory to the `langchain-community` directory: +For example, if you're working on the `langchain-ollama` package, you would change +the working directory to the the package directory: ```bash -cd [root]/libs/langchain-community +cd [root]/libs/partners/ollama ``` Then you can run the following commands to lint and format the in-code documentation: @@ -160,9 +193,9 @@ make format make lint ``` -## Verify Documentation Changes +## Verify documentation changes After pushing documentation changes to the repository, you can preview and verify that the changes are what you wanted by clicking the `View deployment` or `Visit Preview` buttons on the pull request `Conversation` page. This will take you to a preview of the documentation changes. -This preview is created by [Vercel](https://vercel.com/docs/getting-started-with-vercel). \ No newline at end of file +This preview is created by [Vercel](https://vercel.com/docs/getting-started-with-vercel). diff --git a/docs/docs/contributing/how_to/documentation/style_guide.mdx b/docs/docs/contributing/how_to/documentation/style_guide.mdx index 201285dd149..a5e369666ad 100644 --- a/docs/docs/contributing/how_to/documentation/style_guide.mdx +++ b/docs/docs/contributing/how_to/documentation/style_guide.mdx @@ -2,7 +2,7 @@ sidebar_class_name: "hidden" --- -# Documentation Style Guide +# Documentation style guide As LangChain continues to grow, the amount of documentation required to cover the various concepts and integrations continues to grow too. This page provides guidelines for anyone writing documentation for LangChain and outlines some of our philosophies around @@ -158,3 +158,5 @@ Be concise, including in code samples. - Use bullet points and numbered lists to break down information into easily digestible chunks - Use tables (especially for **Reference** sections) and diagrams often to present information visually - Include the table of contents for longer documentation pages to help readers navigate the content, but hide it for shorter pages + +Next, see the [documentation setup guide](setup.mdx) to get started with writing documentation for LangChain. diff --git a/docs/docs/contributing/how_to/index.mdx b/docs/docs/contributing/how_to/index.mdx index 675586340f4..23b94f56c62 100644 --- a/docs/docs/contributing/how_to/index.mdx +++ b/docs/docs/contributing/how_to/index.mdx @@ -1,4 +1,4 @@ -# How-to Guides +# How-to guides - [**Documentation**](documentation/index.mdx): Help improve our docs, including this one! - [**Code**](code/index.mdx): Help us write code, fix bugs, or improve our infrastructure. diff --git a/docs/docs/contributing/how_to/integrations/index.mdx b/docs/docs/contributing/how_to/integrations/index.mdx index efe95c065f3..4f038cb45d3 100644 --- a/docs/docs/contributing/how_to/integrations/index.mdx +++ b/docs/docs/contributing/how_to/integrations/index.mdx @@ -3,7 +3,7 @@ pagination_prev: null pagination_next: contributing/how_to/integrations/package --- -# Contribute Integrations +# Contribute integrations Integrations are a core component of LangChain. LangChain provides standard interfaces for several different components (language models, vector stores, etc) that are crucial when building LLM applications. @@ -16,7 +16,7 @@ LangChain provides standard interfaces for several different components (languag - **Best Practices:** Through their standard interface, LangChain components encourage and facilitate best practices (streaming, async, etc) -## Components to Integrate +## Components to integrate :::info @@ -71,7 +71,7 @@ In order to contribute an integration, you should follow these steps: 5. [Optional] Open and merge a PR to add documentation for your integration to the official LangChain docs. 6. [Optional] Engage with the LangChain team for joint co-marketing ([see below](#co-marketing)). -## Co-Marketing +## Co-marketing With over 20 million monthly downloads, LangChain has a large audience of developers building LLM applications. Beyond just listing integrations, we aim to highlight @@ -87,5 +87,5 @@ Here are some heuristics for types of content we are excited to promote: - **End-to-end applications:** End-to-end applications are great resources for developers looking to build. We prefer to highlight applications that are more complex/agentic in nature, and that use [LangGraph](https://github.com/langchain-ai/langgraph) as the orchestration framework. We get particularly excited about anything involving long-term memory, human-in-the-loop interaction patterns, or multi-agent architectures. - **Research:** We love highlighting novel research! Whether it is research built on top of LangChain or that integrates with it. -## Further Reading +## Further reading To get started, let's learn [how to implement an integration package](/docs/contributing/how_to/integrations/package/) for LangChain. diff --git a/docs/docs/contributing/how_to/integrations/package.mdx b/docs/docs/contributing/how_to/integrations/package.mdx index 570363ec323..806fb852c49 100644 --- a/docs/docs/contributing/how_to/integrations/package.mdx +++ b/docs/docs/contributing/how_to/integrations/package.mdx @@ -358,7 +358,7 @@ a schema for the LLM to fill out when calling the tool. Similar to the `name` an description (part of `Field(..., description="description")`) are passed to the LLM, and the values in these fields should be concise and LLM-usable. -### Run Methods +### Run methods `_run` is the main method that should be implemented in the subclass. This method takes in the arguments from `args_schema` and runs the tool, returning a string @@ -469,6 +469,6 @@ import RetrieverSource from '/src/theme/integration_template/integration_templat --- -## Next Steps +## Next steps Now that you've implemented your package, you can move on to [testing your integration](../standard_tests) for your integration and successfully run them. diff --git a/docs/docs/contributing/how_to/testing.mdx b/docs/docs/contributing/how_to/testing.mdx index 0afccc2a360..cc5a1155c32 100644 --- a/docs/docs/contributing/how_to/testing.mdx +++ b/docs/docs/contributing/how_to/testing.mdx @@ -10,7 +10,7 @@ Unit tests run on every pull request, so they should be fast and reliable. Integration tests run once a day, and they require more setup, so they should be reserved for confirming interface points with external services. -## Unit Tests +## Unit tests Unit tests cover modular logic that does not require calls to outside APIs. If you add new logic, please add a unit test. @@ -27,19 +27,13 @@ To run unit tests: make test ``` -To run unit tests in Docker: - -```bash -make docker_tests -``` - To run a specific test: ```bash TEST_FILE=tests/unit_tests/test_imports.py make test ``` -## Integration Tests +## Integration tests Integration tests cover logic that requires making calls to outside APIs (often integration with other services). If you add support for a new external API, please add a new integration test. diff --git a/docs/docs/contributing/index.mdx b/docs/docs/contributing/index.mdx index 3223012903f..ea59ab4a39a 100644 --- a/docs/docs/contributing/index.mdx +++ b/docs/docs/contributing/index.mdx @@ -12,7 +12,7 @@ More coming soon! We are working on tutorials to help you make your first contri - [**Make your first docs PR**](tutorials/docs.mdx) -## How-to Guides +## How-to guides - [**Documentation**](how_to/documentation/index.mdx): Help improve our docs, including this one! - [**Code**](how_to/code/index.mdx): Help us write code, fix bugs, or improve our infrastructure. diff --git a/docs/docs/contributing/reference/repo_structure.mdx b/docs/docs/contributing/reference/repo_structure.mdx index 8838fdfb935..13a133c119d 100644 --- a/docs/docs/contributing/reference/repo_structure.mdx +++ b/docs/docs/contributing/reference/repo_structure.mdx @@ -50,7 +50,7 @@ There are other files in the root directory level, but their presence should be ## Documentation The `/docs` directory contains the content for the documentation that is shown -at https://python.langchain.com/ and the associated API Reference https://python.langchain.com/api_reference/langchain/index.html. +at [python.langchain.com](https://python.langchain.com/) and the associated [API Reference](https://python.langchain.com/api_reference/). See the [documentation](../how_to/documentation/index.mdx) guidelines to learn how to contribute to the documentation. diff --git a/docs/docs/contributing/tutorials/docs.mdx b/docs/docs/contributing/tutorials/docs.mdx index 4b31b972e4c..8032586c50f 100644 --- a/docs/docs/contributing/tutorials/docs.mdx +++ b/docs/docs/contributing/tutorials/docs.mdx @@ -8,7 +8,7 @@ This tutorial will guide you through making a simple documentation edit, like co --- -## Editing a Documentation Page on GitHub +## Editing a documentation page on GitHub Sometimes you want to make a small change, like fixing a typo, and the easiest way to do this is to use GitHub's editor directly. @@ -42,10 +42,14 @@ Sometimes you want to make a small change, like fixing a typo, and the easiest w - Give your PR a title like `docs: Fix typo in X section`. - Follow the checklist in the PR description template. -## Getting a Review +## Getting a review Once you've submitted the pull request, it will be reviewed by the maintainers. You may receive feedback or requests for changes. Keep an eye on the PR to address any comments. Docs PRs are typically reviewed within a few days, but it may take longer depending on the complexity of the change and the availability of maintainers. For more information on reviews, see the [Review Process](../reference/review_process.mdx). + +## More information + +See our [how-to guides](../how_to/documentation/index.mdx) for more information on contributing to documentation: diff --git a/docs/docs/integrations/providers/ibm.mdx b/docs/docs/integrations/providers/ibm.mdx index 6c4d69d1c66..f53d023d08e 100644 --- a/docs/docs/integrations/providers/ibm.mdx +++ b/docs/docs/integrations/providers/ibm.mdx @@ -92,7 +92,7 @@ the support of DB2 vector store and vector search. See detailed usage examples in the guide [here](/docs/integrations/vectorstores/db2). -Installation: This is a seperate package for vector store feature only and can be run +Installation: This is a separate package for vector store feature only and can be run without the `langchain-ibm` package. ```bash pip install -U langchain-db2 diff --git a/docs/docs/integrations/providers/predictionguard.mdx b/docs/docs/integrations/providers/predictionguard.mdx index bd7eea8330b..f862d43eca3 100644 --- a/docs/docs/integrations/providers/predictionguard.mdx +++ b/docs/docs/integrations/providers/predictionguard.mdx @@ -20,7 +20,7 @@ pip install langchain-predictionguard |---|---|---|---------------------------------------------------------|-------------------------------------------------------------------------------| |Chat|Build Chat Bots|[Chat](https://docs.predictionguard.com/api-reference/api-reference/chat-completions)| `from langchain_predictionguard import ChatPredictionGuard` | [ChatPredictionGuard.ipynb](/docs/integrations/chat/predictionguard) | |Completions|Generate Text|[Completions](https://docs.predictionguard.com/api-reference/api-reference/completions)| `from langchain_predictionguard import PredictionGuard` | [PredictionGuard.ipynb](/docs/integrations/llms/predictionguard) | -|Text Embedding|Embed String to Vectores|[Embeddings](https://docs.predictionguard.com/api-reference/api-reference/embeddings)| `from langchain_predictionguard import PredictionGuardEmbeddings` | [PredictionGuardEmbeddings.ipynb](/docs/integrations/text_embedding/predictionguard) | +|Text Embedding|Embed String to Vectors|[Embeddings](https://docs.predictionguard.com/api-reference/api-reference/embeddings)| `from langchain_predictionguard import PredictionGuardEmbeddings` | [PredictionGuardEmbeddings.ipynb](/docs/integrations/text_embedding/predictionguard) | ## Getting Started diff --git a/docs/docs/integrations/providers/premai.md b/docs/docs/integrations/providers/premai.md index 25498ebb287..678763a33af 100644 --- a/docs/docs/integrations/providers/premai.md +++ b/docs/docs/integrations/providers/premai.md @@ -1,7 +1,6 @@ # PremAI -[PremAI](https://premai.io/) is an all-in-one platform that simplifies the creation of robust, production-ready applications powered by Generative AI. By streamlining the development process, PremAI allows you to concentrate on enhancing user experience and driving overall growth for your application. You can quickly start using our platform [here](https://docs.premai.io/quick-start). - +[PremAI](https://premai.io/) is an all-in-one platform that simplifies the creation of robust, production-ready applications powered by Generative AI. By streamlining the development process, PremAI allows you to concentrate on enhancing user experience and driving overall growth for your application. You can quickly start using [our platform](https://docs.premai.io/quick-start). ## ChatPremAI @@ -26,10 +25,9 @@ from langchain_community.chat_models import ChatPremAI Once we imported our required modules, let's setup our client. For now let's assume that our `project_id` is `8`. But make sure you use your project-id, otherwise it will throw error. -To use langchain with prem, you do not need to pass any model name or set any parameters with our chat-client. By default it will use the model name and parameters used in the [LaunchPad](https://docs.premai.io/get-started/launchpad). - -> Note: If you change the `model` or any other parameters like `temperature` or `max_tokens` while setting the client, it will override existing default configurations, that was used in LaunchPad. +To use langchain with prem, you do not need to pass any model name or set any parameters with our chat-client. By default it will use the model name and parameters used in the [LaunchPad](https://docs.premai.io/get-started/launchpad). +> Note: If you change the `model` or any other parameters like `temperature` or `max_tokens` while setting the client, it will override existing default configurations, that was used in LaunchPad. ```python import os @@ -43,9 +41,9 @@ chat = ChatPremAI(project_id=1234, model_name="gpt-4o") ### Chat Completions -`ChatPremAI` supports two methods: `invoke` (which is the same as `generate`) and `stream`. +`ChatPremAI` supports two methods: `invoke` (which is the same as `generate`) and `stream`. -The first one will give us a static result. Whereas the second one will stream tokens one by one. Here's how you can generate chat-like completions. +The first one will give us a static result. Whereas the second one will stream tokens one by one. Here's how you can generate chat-like completions. ```python human_message = HumanMessage(content="Who are you?") @@ -72,18 +70,17 @@ chat.invoke( ) ``` -> If you are going to place system prompt here, then it will override your system prompt that was fixed while deploying the application from the platform. +> If you are going to place system prompt here, then it will override your system prompt that was fixed while deploying the application from the platform. > You can find all the optional parameters [here](https://docs.premai.io/get-started/sdk#optional-parameters). Any parameters other than [these supported parameters](https://docs.premai.io/get-started/sdk#optional-parameters) will be automatically removed before calling the model. - ### Native RAG Support with Prem Repositories Prem Repositories which allows users to upload documents (.txt, .pdf etc) and connect those repositories to the LLMs. You can think Prem repositories as native RAG, where each repository can be considered as a vector database. You can connect multiple repositories. You can learn more about repositories [here](https://docs.premai.io/get-started/repositories). -Repositories are also supported in langchain premai. Here is how you can do it. +Repositories are also supported in langchain premai. Here is how you can do it. -```python +```python query = "Which models are used for dense retrieval" repository_ids = [1985,] @@ -94,13 +91,13 @@ repositories = dict( ) ``` -First we start by defining our repository with some repository ids. Make sure that the ids are valid repository ids. You can learn more about how to get the repository id [here](https://docs.premai.io/get-started/repositories). +First we start by defining our repository with some repository ids. Make sure that the ids are valid repository ids. You can learn more about how to get the repository id [here](https://docs.premai.io/get-started/repositories). -> Please note: Similar like `model_name` when you invoke the argument `repositories`, then you are potentially overriding the repositories connected in the launchpad. +> Please note: Similar like `model_name` when you invoke the argument `repositories`, then you are potentially overriding the repositories connected in the launchpad. -Now, we connect the repository with our chat object to invoke RAG based generations. +Now, we connect the repository with our chat object to invoke RAG based generations. -```python +```python import json response = chat.invoke(query, max_tokens=100, repositories=repositories) @@ -109,7 +106,7 @@ print(response.content) print(json.dumps(response.response_metadata, indent=4)) ``` -This is how an output looks like. +This is how an output looks like. ```bash Dense retrieval models typically include: @@ -134,11 +131,11 @@ Dense retrieval models typically include: So, this also means that you do not need to make your own RAG pipeline when using the Prem Platform. Prem uses it's own RAG technology to deliver best in class performance for Retrieval Augmented Generations. -> Ideally, you do not need to connect Repository IDs here to get Retrieval Augmented Generations. You can still get the same result if you have connected the repositories in prem platform. +> Ideally, you do not need to connect Repository IDs here to get Retrieval Augmented Generations. You can still get the same result if you have connected the repositories in prem platform. ### Streaming -In this section, let's see how we can stream tokens using langchain and PremAI. Here's how you do it. +In this section, let's see how we can stream tokens using langchain and PremAI. Here's how you do it. ```python import sys @@ -163,16 +160,15 @@ for chunk in chat.stream( This will stream tokens one after the other. -> Please note: As of now, RAG with streaming is not supported. However we still support it with our API. You can learn more about that [here](https://docs.premai.io/get-started/chat-completion-sse). - +> Please note: As of now, RAG with streaming is not supported. However we still support it with our API. You can learn more about that [here](https://docs.premai.io/get-started/chat-completion-sse). ## Prem Templates -Writing Prompt Templates can be super messy. Prompt templates are long, hard to manage, and must be continuously tweaked to improve and keep the same throughout the application. +Writing Prompt Templates can be super messy. Prompt templates are long, hard to manage, and must be continuously tweaked to improve and keep the same throughout the application. -With **Prem**, writing and managing prompts can be super easy. The **_Templates_** tab inside the [launchpad](https://docs.premai.io/get-started/launchpad) helps you write as many prompts you need and use it inside the SDK to make your application running using those prompts. You can read more about Prompt Templates [here](https://docs.premai.io/get-started/prem-templates). +With **Prem**, writing and managing prompts can be super easy. The **_Templates_** tab inside the [launchpad](https://docs.premai.io/get-started/launchpad) helps you write as many prompts you need and use it inside the SDK to make your application running using those prompts. You can read more about Prompt Templates [here](https://docs.premai.io/get-started/prem-templates). -To use Prem Templates natively with LangChain, you need to pass an id the `HumanMessage`. This id should be the name the variable of your prompt template. the `content` in `HumanMessage` should be the value of that variable. +To use Prem Templates natively with LangChain, you need to pass an id the `HumanMessage`. This id should be the name the variable of your prompt template. the `content` in `HumanMessage` should be the value of that variable. let's say for example, if your prompt template was this: @@ -198,7 +194,7 @@ template_id = "78069ce8-xxxxx-xxxxx-xxxx-xxx" response = chat.invoke([human_message], template_id=template_id) ``` -Prem Templates are also available for Streaming too. +Prem Templates are also available for Streaming too. ## Prem Embeddings @@ -215,7 +211,7 @@ if os.environ.get("PREMAI_API_KEY") is None: ``` -We support lots of state of the art embedding models. You can view our list of supported LLMs and embedding models [here](https://docs.premai.io/get-started/supported-models). For now let's go for `text-embedding-3-large` model for this example. . +We support lots of state of the art embedding models. You can view our list of supported LLMs and embedding models [here](https://docs.premai.io/get-started/supported-models). For now let's go for `text-embedding-3-large` model for this example. . ```python @@ -231,7 +227,7 @@ print(query_result[:5]) ``` :::note -Setting `model_name` argument in mandatory for PremAIEmbeddings unlike chat. +Setting `model_name` argument in mandatory for PremAIEmbeddings unlike chat. ::: Finally, let's embed some sample document @@ -254,11 +250,13 @@ print(doc_result[0][:5]) ```python print(f"Dimension of embeddings: {len(query_result)}") ``` + Dimension of embeddings: 3072 ```python doc_result[:5] ``` + >Result: > >[-0.02129288576543331, @@ -269,20 +267,20 @@ doc_result[:5] ## Tool/Function Calling -LangChain PremAI supports tool/function calling. Tool/function calling allows a model to respond to a given prompt by generating output that matches a user-defined schema. +LangChain PremAI supports tool/function calling. Tool/function calling allows a model to respond to a given prompt by generating output that matches a user-defined schema. - You can learn all about tool calling in details [in our documentation here](https://docs.premai.io/get-started/function-calling). - You can learn more about langchain tool calling in [this part of the docs](https://python.langchain.com/v0.1/docs/modules/model_io/chat/function_calling). **NOTE:** -> The current version of LangChain ChatPremAI do not support function/tool calling with streaming support. Streaming support along with function calling will come soon. +> The current version of LangChain ChatPremAI do not support function/tool calling with streaming support. Streaming support along with function calling will come soon. ### Passing tools to model -In order to pass tools and let the LLM choose the tool it needs to call, we need to pass a tool schema. A tool schema is the function definition along with proper docstring on what does the function do, what each argument of the function is etc. Below are some simple arithmetic functions with their schema. +In order to pass tools and let the LLM choose the tool it needs to call, we need to pass a tool schema. A tool schema is the function definition along with proper docstring on what does the function do, what each argument of the function is etc. Below are some simple arithmetic functions with their schema. -**NOTE:** +**NOTE:** > When defining function/tool schema, do not forget to add information around the function arguments, otherwise it would throw error. ```python @@ -320,27 +318,28 @@ def multiply(a: int, b: int) -> int: ### Binding tool schemas with our LLM -We will now use the `bind_tools` method to convert our above functions to a "tool" and binding it with the model. This means we are going to pass these tool information everytime we invoke the model. +We will now use the `bind_tools` method to convert our above functions to a "tool" and binding it with the model. This means we are going to pass these tool information every time we invoke the model. ```python tools = [add, multiply] llm_with_tools = chat.bind_tools(tools) ``` -After this, we get the response from the model which is now binded with the tools. +After this, we get the response from the model which is now binded with the tools. -```python +```python query = "What is 3 * 12? Also, what is 11 + 49?" messages = [HumanMessage(query)] ai_msg = llm_with_tools.invoke(messages) ``` -As we can see, when our chat model is binded with tools, then based on the given prompt, it calls the correct set of the tools and sequentially. +As we can see, when our chat model is binded with tools, then based on the given prompt, it calls the correct set of the tools and sequentially. -```python +```python ai_msg.tool_calls ``` + **Output** ```python @@ -352,15 +351,15 @@ ai_msg.tool_calls 'id': 'call_MPKYGLHbf39csJIyb5BZ9xIk'}] ``` -We append this message shown above to the LLM which acts as a context and makes the LLM aware that what all functions it has called. +We append this message shown above to the LLM which acts as a context and makes the LLM aware that what all functions it has called. -```python +```python messages.append(ai_msg) ``` Since tool calling happens into two phases, where: -1. in our first call, we gathered all the tools that the LLM decided to tool, so that it can get the result as an added context to give more accurate and hallucination free result. +1. in our first call, we gathered all the tools that the LLM decided to tool, so that it can get the result as an added context to give more accurate and hallucination free result. 2. in our second call, we will parse those set of tools decided by LLM and run them (in our case it will be the functions we defined, with the LLM's extracted arguments) and pass this result to the LLM @@ -373,12 +372,13 @@ for tool_call in ai_msg.tool_calls: messages.append(ToolMessage(tool_output, tool_call_id=tool_call["id"])) ``` -Finally, we call the LLM (binded with the tools) with the function response added in it's context. +Finally, we call the LLM (binded with the tools) with the function response added in it's context. ```python response = llm_with_tools.invoke(messages) print(response.content) ``` + **Output** ```txt @@ -425,4 +425,4 @@ chain.invoke(query) [multiply(a=3, b=12), add(a=11, b=49)] ``` -Now, as done above, we parse this and run this functions and call the LLM once again to get the result. \ No newline at end of file +Now, as done above, we parse this and run this functions and call the LLM once again to get the result. diff --git a/docs/scripts/kv_store_feat_table.py b/docs/scripts/kv_store_feat_table.py index 6730ec650d0..fb3709e5641 100644 --- a/docs/scripts/kv_store_feat_table.py +++ b/docs/scripts/kv_store_feat_table.py @@ -1,9 +1,6 @@ import sys from pathlib import Path -from langchain_community import document_loaders -from langchain_core.document_loaders.base import BaseLoader - KV_STORE_TEMPLATE = """\ --- sidebar_class_name: hidden diff --git a/docs/scripts/notebook_convert.py b/docs/scripts/notebook_convert.py index 33da9a5d30b..5c9dc7f77c6 100644 --- a/docs/scripts/notebook_convert.py +++ b/docs/scripts/notebook_convert.py @@ -175,8 +175,23 @@ def _modify_frontmatter( def _convert_notebook( notebook_path: Path, output_path: Path, intermediate_docs_dir: Path ) -> Path: - with open(notebook_path) as f: - nb = nbformat.read(f, as_version=4) + import json + import uuid + + with open(notebook_path, "r", encoding="utf-8") as f: + nb_json = json.load(f) + + # Fix missing and duplicate cell IDs before nbformat validation + seen_ids = set() + for cell in nb_json.get("cells", []): + if "id" not in cell or not cell.get("id") or cell.get("id") in seen_ids: + cell["id"] = str(uuid.uuid4())[:8] + seen_ids.add(cell["id"]) + + nb = nbformat.reads(json.dumps(nb_json), as_version=4) + + # Upgrade notebook format + nb = nbformat.v4.upgrade(nb) body, resources = exporter.from_notebook_node(nb) diff --git a/docs/sidebars.js b/docs/sidebars.js index f1e867c6f5c..26d7102f2d9 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -315,8 +315,8 @@ module.exports = { }, ], link: { - type: "doc", - id: "integrations/stores/index", + type: "generated-index", + slug: "integrations/stores", }, }, { diff --git a/docs/vercel_overrides.txt b/docs/vercel_overrides.txt index 3507cdb4d94..966f3b329cf 100644 --- a/docs/vercel_overrides.txt +++ b/docs/vercel_overrides.txt @@ -4,3 +4,9 @@ aiohttp<3.11 protobuf<3.21 tenacity urllib3 +# Fix numpy conflicts between langchain-astradb and langchain-chroma +numpy>=1.26.0,<2.0.0 +# Fix simsimd build error in langchain-weaviate +simsimd>=5.0.0 +# Fix sentencepiece build error - use newer version that supports modern CMake +sentencepiece>=0.2.1 diff --git a/libs/cli/langchain_cli/integration_template/Makefile b/libs/cli/langchain_cli/integration_template/Makefile index f660290fd1b..cb965ba5b3c 100644 --- a/libs/cli/langchain_cli/integration_template/Makefile +++ b/libs/cli/langchain_cli/integration_template/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/core/Makefile b/libs/core/Makefile index bf74eadd9e0..f5bef5c1a4a 100644 --- a/libs/core/Makefile +++ b/libs/core/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests test_watch integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests test_watch integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/core/langchain_core/outputs/llm_result.py b/libs/core/langchain_core/outputs/llm_result.py index 3e38687022a..08e5e78f2a7 100644 --- a/libs/core/langchain_core/outputs/llm_result.py +++ b/libs/core/langchain_core/outputs/llm_result.py @@ -46,7 +46,10 @@ class LLMResult(BaseModel): relevant information from standardized fields present in AIMessage. """ run: Optional[list[RunInfo]] = None - """List of metadata info for model call for each input.""" + """List of metadata info for model call for each input. + + See :class:`~langchain_core.outputs.run_info.RunInfo` for details. + """ type: Literal["LLMResult"] = "LLMResult" """Type is used exclusively for serialization purposes.""" diff --git a/libs/core/langchain_core/tools/base.py b/libs/core/langchain_core/tools/base.py index 38404292550..8fcd1e42218 100644 --- a/libs/core/langchain_core/tools/base.py +++ b/libs/core/langchain_core/tools/base.py @@ -443,9 +443,7 @@ class ChildTool(BaseTool): Args schema should be either: - A subclass of pydantic.BaseModel. - or - A subclass of pydantic.v1.BaseModel if accessing v1 namespace in pydantic 2 - or - a JSON schema dict """ return_direct: bool = False @@ -1258,8 +1256,8 @@ class InjectedToolCallId(InjectedToolArg): This annotation is used to mark a tool parameter that should receive the tool call ID at runtime. - Example: - ```python + .. code-block:: python + from typing_extensions import Annotated from langchain_core.messages import ToolMessage from langchain_core.tools import tool, InjectedToolCallId @@ -1275,7 +1273,6 @@ class InjectedToolCallId(InjectedToolArg): name="foo", tool_call_id=tool_call_id ) - ``` """ diff --git a/libs/core/langchain_core/tools/convert.py b/libs/core/langchain_core/tools/convert.py index 124b0dffc9e..d045179ee46 100644 --- a/libs/core/langchain_core/tools/convert.py +++ b/libs/core/langchain_core/tools/convert.py @@ -144,7 +144,8 @@ def tool( return "partial json of results", {"full": "object of results"} .. versionadded:: 0.2.14 - Parse Google-style docstrings: + + Parse Google-style docstrings: .. code-block:: python diff --git a/libs/core/langchain_core/tracers/log_stream.py b/libs/core/langchain_core/tracers/log_stream.py index caae5d31886..5246ea8456e 100644 --- a/libs/core/langchain_core/tracers/log_stream.py +++ b/libs/core/langchain_core/tracers/log_stream.py @@ -210,7 +210,9 @@ class LogStreamCallbackHandler(BaseTracer, _StreamingCallbackHandler): exclude_tags: Exclude runs from Runnables with matching tags. _schema_format: Primarily changes how the inputs and outputs are handled. + **For internal use only. This API will change.** + - 'original' is the format used by all current tracers. This format is slightly inconsistent with respect to inputs and outputs. diff --git a/libs/core/langchain_core/utils/aiter.py b/libs/core/langchain_core/utils/aiter.py index 96ab5e459a6..02a6d84da54 100644 --- a/libs/core/langchain_core/utils/aiter.py +++ b/libs/core/langchain_core/utils/aiter.py @@ -266,17 +266,20 @@ class aclosing(AbstractAsyncContextManager): # noqa: N801 Code like this: + .. code-block:: python + async with aclosing(.fetch()) as agen: is equivalent to this: + .. code-block:: python + agen = .fetch() try: finally: await agen.aclose() - """ def __init__( diff --git a/libs/langchain/Makefile b/libs/langchain/Makefile index f08261b3502..3a445f2a35d 100644 --- a/libs/langchain/Makefile +++ b/libs/langchain/Makefile @@ -1,4 +1,4 @@ -.PHONY: all clean docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck format lint test tests test_watch integration_tests docker_tests help extended_tests +.PHONY: all clean docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck format lint test tests test_watch integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help @@ -36,10 +36,6 @@ test_watch_extended: integration_tests: uv run --group test --group test_integration pytest tests/integration_tests -docker_tests: - docker build -t my-langchain-image:test . - docker run --rm my-langchain-image:test - check_imports: $(shell find langchain -name '*.py') uv run python ./scripts/check_imports.py $^ @@ -98,5 +94,4 @@ help: @echo 'extended_tests - run only extended unit tests' @echo 'test_watch - run unit tests in watch mode' @echo 'integration_tests - run integration tests' - @echo 'docker_tests - run unit tests in docker' @echo '-- DOCUMENTATION tasks are from the top-level Makefile --' diff --git a/libs/langchain/langchain/chains/combine_documents/map_rerank.py b/libs/langchain/langchain/chains/combine_documents/map_rerank.py index 32323bf1e95..e2ed619a355 100644 --- a/libs/langchain/langchain/chains/combine_documents/map_rerank.py +++ b/libs/langchain/langchain/chains/combine_documents/map_rerank.py @@ -31,8 +31,8 @@ class MapRerankDocumentsChain(BaseCombineDocumentsChain): """Combining documents by mapping a chain over them, then reranking results. This algorithm calls an LLMChain on each input document. The LLMChain is expected - to have an OutputParser that parses the result into both an answer (`answer_key`) - and a score (`rank_key`). The answer with the highest score is then returned. + to have an OutputParser that parses the result into both an answer (``answer_key``) + and a score (``rank_key``). The answer with the highest score is then returned. Example: .. code-block:: python diff --git a/libs/langchain/langchain/chains/conversation/base.py b/libs/langchain/langchain/chains/conversation/base.py index 428031d2785..f81a47940a1 100644 --- a/libs/langchain/langchain/chains/conversation/base.py +++ b/libs/langchain/langchain/chains/conversation/base.py @@ -53,6 +53,7 @@ class ConversationChain(LLMChain): "Hi I'm Bob.", config={"configurable": {"session_id": "1"}}, ) # session_id determines thread + Memory objects can also be incorporated into the ``get_session_history`` callable: .. code-block:: python diff --git a/libs/langchain/langchain/chains/conversational_retrieval/base.py b/libs/langchain/langchain/chains/conversational_retrieval/base.py index 9fb89bd027b..ba01acf7caf 100644 --- a/libs/langchain/langchain/chains/conversational_retrieval/base.py +++ b/libs/langchain/langchain/chains/conversational_retrieval/base.py @@ -267,68 +267,67 @@ class ConversationalRetrievalChain(BaseConversationalRetrievalChain): `create_retrieval_chain`. Additional walkthroughs can be found at https://python.langchain.com/docs/use_cases/question_answering/chat_history - .. code-block:: python + .. code-block:: python - from langchain.chains import ( - create_history_aware_retriever, - create_retrieval_chain, - ) - from langchain.chains.combine_documents import create_stuff_documents_chain - from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder - from langchain_openai import ChatOpenAI + from langchain.chains import ( + create_history_aware_retriever, + create_retrieval_chain, + ) + from langchain.chains.combine_documents import create_stuff_documents_chain + from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder + from langchain_openai import ChatOpenAI + retriever = ... # Your retriever - retriever = ... # Your retriever + llm = ChatOpenAI() - llm = ChatOpenAI() + # Contextualize question + contextualize_q_system_prompt = ( + "Given a chat history and the latest user question " + "which might reference context in the chat history, " + "formulate a standalone question which can be understood " + "without the chat history. Do NOT answer the question, just " + "reformulate it if needed and otherwise return it as is." + ) + contextualize_q_prompt = ChatPromptTemplate.from_messages( + [ + ("system", contextualize_q_system_prompt), + MessagesPlaceholder("chat_history"), + ("human", "{input}"), + ] + ) + history_aware_retriever = create_history_aware_retriever( + llm, retriever, contextualize_q_prompt + ) - # Contextualize question - contextualize_q_system_prompt = ( - "Given a chat history and the latest user question " - "which might reference context in the chat history, " - "formulate a standalone question which can be understood " - "without the chat history. Do NOT answer the question, just " - "reformulate it if needed and otherwise return it as is." - ) - contextualize_q_prompt = ChatPromptTemplate.from_messages( - [ - ("system", contextualize_q_system_prompt), - MessagesPlaceholder("chat_history"), - ("human", "{input}"), - ] - ) - history_aware_retriever = create_history_aware_retriever( - llm, retriever, contextualize_q_prompt - ) + # Answer question + qa_system_prompt = ( + "You are an assistant for question-answering tasks. Use " + "the following pieces of retrieved context to answer the " + "question. If you don't know the answer, just say that you " + "don't know. Use three sentences maximum and keep the answer " + "concise." + "\n\n" + "{context}" + ) + qa_prompt = ChatPromptTemplate.from_messages( + [ + ("system", qa_system_prompt), + MessagesPlaceholder("chat_history"), + ("human", "{input}"), + ] + ) + # Below we use create_stuff_documents_chain to feed all retrieved context + # into the LLM. Note that we can also use StuffDocumentsChain and other + # instances of BaseCombineDocumentsChain. + question_answer_chain = create_stuff_documents_chain(llm, qa_prompt) + rag_chain = create_retrieval_chain( + history_aware_retriever, question_answer_chain + ) - # Answer question - qa_system_prompt = ( - "You are an assistant for question-answering tasks. Use " - "the following pieces of retrieved context to answer the " - "question. If you don't know the answer, just say that you " - "don't know. Use three sentences maximum and keep the answer " - "concise." - "\n\n" - "{context}" - ) - qa_prompt = ChatPromptTemplate.from_messages( - [ - ("system", qa_system_prompt), - MessagesPlaceholder("chat_history"), - ("human", "{input}"), - ] - ) - # Below we use create_stuff_documents_chain to feed all retrieved context - # into the LLM. Note that we can also use StuffDocumentsChain and other - # instances of BaseCombineDocumentsChain. - question_answer_chain = create_stuff_documents_chain(llm, qa_prompt) - rag_chain = create_retrieval_chain( - history_aware_retriever, question_answer_chain - ) - - # Usage: - chat_history = [] # Collect chat history here (a sequence of messages) - rag_chain.invoke({"input": query, "chat_history": chat_history}) + # Usage: + chat_history = [] # Collect chat history here (a sequence of messages) + rag_chain.invoke({"input": query, "chat_history": chat_history}) This chain takes in chat history (a list of messages) and new questions, and then returns an answer to that question. @@ -381,7 +380,9 @@ class ConversationalRetrievalChain(BaseConversationalRetrievalChain): """Retriever to use to fetch documents.""" max_tokens_limit: Optional[int] = None """If set, enforces that the documents returned are less than this limit. - This is only enforced if `combine_docs_chain` is of type StuffDocumentsChain.""" + + This is only enforced if ``combine_docs_chain`` is of type StuffDocumentsChain. + """ def _reduce_tokens_below_limit(self, docs: list[Document]) -> list[Document]: num_docs = len(docs) diff --git a/libs/langchain_v1/Makefile b/libs/langchain_v1/Makefile index 2ec03f203bd..885a56cf7b6 100644 --- a/libs/langchain_v1/Makefile +++ b/libs/langchain_v1/Makefile @@ -1,4 +1,4 @@ -.PHONY: all clean docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck format lint test tests test_watch integration_tests docker_tests help extended_tests +.PHONY: all clean docs_build docs_clean docs_linkcheck api_docs_build api_docs_clean api_docs_linkcheck format lint test tests test_watch integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help @@ -36,10 +36,6 @@ test_watch_extended: integration_tests: uv run --group test --group test_integration pytest tests/integration_tests -docker_tests: - docker build -t my-langchain-image:test . - docker run --rm my-langchain-image:test - check_imports: $(shell find langchain -name '*.py') uv run python ./scripts/check_imports.py $^ @@ -97,5 +93,4 @@ help: @echo 'extended_tests - run only extended unit tests' @echo 'test_watch - run unit tests in watch mode' @echo 'integration_tests - run integration tests' - @echo 'docker_tests - run unit tests in docker' @echo '-- DOCUMENTATION tasks are from the top-level Makefile --' diff --git a/libs/partners/anthropic/Makefile b/libs/partners/anthropic/Makefile index 494352a0eda..e78e84a51af 100644 --- a/libs/partners/anthropic/Makefile +++ b/libs/partners/anthropic/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/chroma/Makefile b/libs/partners/chroma/Makefile index ea9fe087c3f..024e708c69e 100644 --- a/libs/partners/chroma/Makefile +++ b/libs/partners/chroma/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/deepseek/Makefile b/libs/partners/deepseek/Makefile index 08cefe3a33d..e74e2f32bef 100644 --- a/libs/partners/deepseek/Makefile +++ b/libs/partners/deepseek/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/exa/Makefile b/libs/partners/exa/Makefile index ce85556f3f0..64daa2957d9 100644 --- a/libs/partners/exa/Makefile +++ b/libs/partners/exa/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/fireworks/Makefile b/libs/partners/fireworks/Makefile index 7cb001a6fe6..76594a5dbcc 100644 --- a/libs/partners/fireworks/Makefile +++ b/libs/partners/fireworks/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/groq/Makefile b/libs/partners/groq/Makefile index e0981cec452..5af03cd4c98 100644 --- a/libs/partners/groq/Makefile +++ b/libs/partners/groq/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/huggingface/Makefile b/libs/partners/huggingface/Makefile index a6564f43dfe..ac12a1382ca 100644 --- a/libs/partners/huggingface/Makefile +++ b/libs/partners/huggingface/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/mistralai/Makefile b/libs/partners/mistralai/Makefile index ede572f9e46..38ead2bb6b0 100644 --- a/libs/partners/mistralai/Makefile +++ b/libs/partners/mistralai/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/nomic/Makefile b/libs/partners/nomic/Makefile index 6e4a4afb339..54a7e1bba6a 100644 --- a/libs/partners/nomic/Makefile +++ b/libs/partners/nomic/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/ollama/Makefile b/libs/partners/ollama/Makefile index 9d78cf3cae6..68f307e27e1 100644 --- a/libs/partners/ollama/Makefile +++ b/libs/partners/ollama/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/openai/Makefile b/libs/partners/openai/Makefile index 512cff409e1..ab0a6cbf423 100644 --- a/libs/partners/openai/Makefile +++ b/libs/partners/openai/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/perplexity/Makefile b/libs/partners/perplexity/Makefile index 9bff2953226..06fe870b59f 100644 --- a/libs/partners/perplexity/Makefile +++ b/libs/partners/perplexity/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/prompty/Makefile b/libs/partners/prompty/Makefile index 3df127b25ec..303faaa29ea 100644 --- a/libs/partners/prompty/Makefile +++ b/libs/partners/prompty/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/partners/xai/Makefile b/libs/partners/xai/Makefile index 92198d1a529..1419c1f1baa 100644 --- a/libs/partners/xai/Makefile +++ b/libs/partners/xai/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/standard-tests/Makefile b/libs/standard-tests/Makefile index afa09134485..4e1d8bae5d0 100644 --- a/libs/standard-tests/Makefile +++ b/libs/standard-tests/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/libs/text-splitters/Makefile b/libs/text-splitters/Makefile index 7ee6d99a5cb..8532a0f4276 100644 --- a/libs/text-splitters/Makefile +++ b/libs/text-splitters/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test tests test_watch integration_tests docker_tests help extended_tests +.PHONY: all format lint test tests test_watch integration_tests help extended_tests # Default target executed when no arguments are given to make. all: help diff --git a/pyproject.toml b/pyproject.toml index be2ae6a0241..a79bb2120eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,10 @@ dev = [ "langchain-openai", "ipykernel<7.0.0,>=6.29.2", ] -codespell = ["codespell<3.0.0,>=2.2.0"] +codespell = [ + "codespell<3.0.0,>=2.2.0", + "tomli>=2.2.1", +] typing = [] test = [ "langchain-experimental @ git+https://github.com/langchain-ai/langchain-experimental.git#subdirectory=libs/experimental", @@ -51,8 +54,22 @@ test = [ "wikipedia<2.0.0,>=1.4.0", "pypdf<6.0.0,>=5.0.0", "vcrpy<7.0.0,>=6.0.1", + "linkchecker>=10.5.0", +] +docs = [ + "toml>=0.10.2", + "autodoc-pydantic>=2,<3", + "sphinx>=6,<8", + "myst-parser>=3", + "sphinx-autobuild>=2024", + "pydata-sphinx-theme>=0.15", + "myst-nb>=1.1.1", + "pyyaml", + "sphinx-design", + "sphinx-copybutton", + "beautifulsoup4", + "sphinxcontrib-googleanalytics", ] - [tool.uv.sources] langchain-core = { path = "./libs/core", editable = true } @@ -72,7 +89,7 @@ build-backend = "pdm.backend" [tool.codespell] -skip = '.git,*.pdf,*.svg,*.pdf,*.yaml,*.ipynb,poetry.lock,*.min.js,*.css,package-lock.json,example_data,_dist,examples,templates,*.trig' +skip = '.git,*.pdf,*.svg,*.pdf,*.yaml,*.ipynb,poetry.lock,*.min.js,*.css,package-lock.json,example_data,_dist,examples,templates,*.trig,*cache*,*.msgpack.zlib,*.csv,*.lock,*.png,*.jpg,*.jpeg,*.gif,*.bmp,*.ico,*.webp,*.tiff,*.mp4,*.mp3,*.wav,*.avi,*.mov,*.zip,*.tar,*.gz,*.rar,*.7z,*.exe,*.dll,*.so,*.dylib,*.bin,*.dat,*.db,*.sqlite' # Ignore latin etc ignore-regex = '.*(Stati Uniti|Tense=Pres).*' # whats is a typo but used frequently in queries so kept as is diff --git a/uv.lock b/uv.lock index 161fac01490..bb8f22f98e7 100644 --- a/uv.lock +++ b/uv.lock @@ -16,6 +16,18 @@ resolution-markers = [ "python_full_version < '3.10' and platform_python_implementation != 'PyPy'", ] +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872", size = 1377899, upload-time = "2024-05-10T11:23:10.216Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, +] + [[package]] name = "aiofiles" version = "24.1.0" @@ -149,6 +161,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597, upload-time = "2024-12-13T17:10:38.469Z" }, ] +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776, upload-time = "2024-01-10T00:56:10.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511, upload-time = "2024-01-10T00:56:08.388Z" }, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -297,6 +318,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152, upload-time = "2025-01-25T11:30:10.164Z" }, ] +[[package]] +name = "autodoc-pydantic" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "sphinx" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/df/87120e2195f08d760bc5cf8a31cfa2381a6887517aa89453b23f1ae3354f/autodoc_pydantic-2.2.0-py3-none-any.whl", hash = "sha256:8c6a36fbf6ed2700ea9c6d21ea76ad541b621fbdf16b5a80ee04673548af4d95", size = 34001, upload-time = "2024-04-27T10:57:00.542Z" }, +] + [[package]] name = "babel" version = "2.17.0" @@ -807,6 +841,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] +[[package]] +name = "dnspython" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197, upload-time = "2024-10-05T20:14:59.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632, upload-time = "2024-10-05T20:14:57.687Z" }, +] + [[package]] name = "docstring-parser" version = "0.16" @@ -816,6 +859,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/7c/e9fcff7623954d86bdc17782036cbf715ecab1bec4847c008557affe1ca8/docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637", size = 36533, upload-time = "2024-03-15T10:39:41.527Z" }, ] +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, +] + [[package]] name = "durationpy" version = "0.9" @@ -1603,6 +1655,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026, upload-time = "2022-07-01T12:21:05.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" }, +] + [[package]] name = "importlib-metadata" version = "8.5.0" @@ -1949,6 +2010,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, ] +[[package]] +name = "jupyter-cache" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "click" }, + { name = "importlib-metadata" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "pyyaml" }, + { name = "sqlalchemy" }, + { name = "tabulate" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bb/f7/3627358075f183956e8c4974603232b03afd4ddc7baf72c2bc9fff522291/jupyter_cache-1.0.1.tar.gz", hash = "sha256:16e808eb19e3fb67a223db906e131ea6e01f03aa27f49a7214ce6a5fec186fb9", size = 32048, upload-time = "2024-11-15T16:03:55.322Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/6b/67b87da9d36bff9df7d0efbd1a325fa372a43be7158effaf43ed7b22341d/jupyter_cache-1.0.1-py3-none-any.whl", hash = "sha256:9c3cafd825ba7da8b5830485343091143dff903e4d8c69db9349b728b140abf6", size = 33907, upload-time = "2024-11-15T16:03:54.021Z" }, +] + [[package]] name = "jupyter-client" version = "8.6.3" @@ -2616,6 +2696,7 @@ source = { editable = "." } [package.dev-dependencies] codespell = [ { name = "codespell" }, + { name = "tomli" }, ] dev = [ { name = "ipykernel" }, @@ -2625,6 +2706,21 @@ dev = [ { name = "langchain-openai" }, { name = "langchain-text-splitters" }, ] +docs = [ + { name = "autodoc-pydantic" }, + { name = "beautifulsoup4" }, + { name = "myst-nb" }, + { name = "myst-parser", version = "3.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pydata-sphinx-theme" }, + { name = "pyyaml" }, + { name = "sphinx" }, + { name = "sphinx-autobuild" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinxcontrib-googleanalytics" }, + { name = "toml" }, +] lint = [ { name = "ruff" }, ] @@ -2648,6 +2744,7 @@ test = [ { name = "langchain-unstructured" }, { name = "langgraph" }, { name = "lark" }, + { name = "linkchecker" }, { name = "msgpack" }, { name = "pandas" }, { name = "pypdf" }, @@ -2661,7 +2758,10 @@ test = [ [package.metadata] [package.metadata.requires-dev] -codespell = [{ name = "codespell", specifier = ">=2.2.0,<3.0.0" }] +codespell = [ + { name = "codespell", specifier = ">=2.2.0,<3.0.0" }, + { name = "tomli", specifier = ">=2.2.1" }, +] dev = [ { name = "ipykernel", specifier = ">=6.29.2,<7.0.0" }, { name = "langchain", editable = "libs/langchain" }, @@ -2670,6 +2770,20 @@ dev = [ { name = "langchain-openai", editable = "libs/partners/openai" }, { name = "langchain-text-splitters", editable = "libs/text-splitters" }, ] +docs = [ + { name = "autodoc-pydantic", specifier = ">=2,<3" }, + { name = "beautifulsoup4" }, + { name = "myst-nb", specifier = ">=1.1.1" }, + { name = "myst-parser", specifier = ">=3" }, + { name = "pydata-sphinx-theme", specifier = ">=0.15" }, + { name = "pyyaml" }, + { name = "sphinx", specifier = ">=6,<8" }, + { name = "sphinx-autobuild", specifier = ">=2024" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinxcontrib-googleanalytics" }, + { name = "toml", specifier = ">=0.10.2" }, +] lint = [{ name = "ruff", specifier = ">=0.12.2,<0.13" }] test = [ { name = "aiofiles", specifier = ">=24.1.0,<25.0.0" }, @@ -2691,6 +2805,7 @@ test = [ { name = "langchain-unstructured", git = "https://github.com/langchain-ai/langchain-unstructured.git?subdirectory=libs%2Funstructured" }, { name = "langgraph" }, { name = "lark", specifier = ">=1.1.9,<2.0.0" }, + { name = "linkchecker", specifier = ">=10.5.0" }, { name = "msgpack" }, { name = "pandas", specifier = ">=2,<3" }, { name = "pypdf", specifier = ">=5.0.0,<6.0.0" }, @@ -2925,6 +3040,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, ] +[[package]] +name = "linkchecker" +version = "10.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "dnspython" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/8a/20cfbda1a4f5e9fd307cbb68dd15c2f14428deaf1eab89a79b9b7d03bf6e/LinkChecker-10.5.0.tar.gz", hash = "sha256:978b42b803e58b7a8f6ffae1ff88fa7fd1e87b944403b5dc82380dd59f516bb9", size = 546451, upload-time = "2024-09-03T18:42:46.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/c6/8d6a8383a92fbd19337b7a3c4ed57042a3f39f57772774a11bd56316af2e/LinkChecker-10.5.0-py3-none-any.whl", hash = "sha256:eb25bf11c795eedc290f93311c497312f4e967e1c5b242b24ce3fc335b4c47c5", size = 280788, upload-time = "2024-09-03T18:42:45.039Z" }, +] + [[package]] name = "lxml" version = "5.3.0" @@ -3146,6 +3275,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, ] +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542, upload-time = "2024-09-09T20:27:49.564Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316, upload-time = "2024-09-09T20:27:48.397Z" }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -3472,6 +3613,79 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, ] +[[package]] +name = "myst-nb" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, + { name = "ipykernel" }, + { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "ipython", version = "8.32.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "jupyter-cache" }, + { name = "myst-parser", version = "3.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "pyyaml" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/83/a894bd8dea7a6e9f053502ee8413484dcbf75a219013d6a72e971c0fecfd/myst_nb-1.3.0.tar.gz", hash = "sha256:df3cd4680f51a5af673fd46b38b562be3559aef1475e906ed0f2e66e4587ce4b", size = 81963, upload-time = "2025-07-13T22:49:38.493Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/a6/03d410c114b8c4856579b3d294dafc27626a7690a552625eec42b16dfa41/myst_nb-1.3.0-py3-none-any.whl", hash = "sha256:1f36af3c19964960ec4e51ac30949b6ed6df220356ffa8d60dd410885e132d7d", size = 82396, upload-time = "2025-07-13T22:49:37.019Z" }, +] + +[[package]] +name = "myst-parser" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10' and platform_python_implementation == 'PyPy'", + "python_full_version < '3.10' and platform_python_implementation != 'PyPy'", +] +dependencies = [ + { name = "docutils", marker = "python_full_version < '3.10'" }, + { name = "jinja2", marker = "python_full_version < '3.10'" }, + { name = "markdown-it-py", marker = "python_full_version < '3.10'" }, + { name = "mdit-py-plugins", marker = "python_full_version < '3.10'" }, + { name = "pyyaml", marker = "python_full_version < '3.10'" }, + { name = "sphinx", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/64/e2f13dac02f599980798c01156393b781aec983b52a6e4057ee58f07c43a/myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87", size = 92392, upload-time = "2024-04-28T20:22:42.116Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", size = 83163, upload-time = "2024-04-28T20:22:39.985Z" }, +] + +[[package]] +name = "myst-parser" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.13' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.13' and platform_python_implementation != 'PyPy'", + "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.12.4' and python_full_version < '3.13' and platform_python_implementation != 'PyPy'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_python_implementation == 'PyPy'", + "python_full_version >= '3.12' and python_full_version < '3.12.4' and platform_python_implementation != 'PyPy'", + "python_full_version == '3.11.*' and platform_python_implementation == 'PyPy'", + "python_full_version == '3.11.*' and platform_python_implementation != 'PyPy'", + "python_full_version == '3.10.*' and platform_python_implementation == 'PyPy'", + "python_full_version == '3.10.*' and platform_python_implementation != 'PyPy'", +] +dependencies = [ + { name = "docutils", marker = "python_full_version >= '3.10'" }, + { name = "jinja2", marker = "python_full_version >= '3.10'" }, + { name = "markdown-it-py", marker = "python_full_version >= '3.10'" }, + { name = "mdit-py-plugins", marker = "python_full_version >= '3.10'" }, + { name = "pyyaml", marker = "python_full_version >= '3.10'" }, + { name = "sphinx", marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/df/76d0321c3797b54b60fef9ec3bd6f4cfd124b9e422182156a1dd418722cf/myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d", size = 84579, upload-time = "2025-02-12T10:53:02.078Z" }, +] + [[package]] name = "nbclient" version = "0.10.2" @@ -4574,6 +4788,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/46/93416fdae86d40879714f72956ac14df9c7b76f7d41a4d68aa9f71a0028b/pydantic_settings-2.7.1-py3-none-any.whl", hash = "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd", size = 29718, upload-time = "2024-12-31T11:27:43.201Z" }, ] +[[package]] +name = "pydata-sphinx-theme" +version = "0.16.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/20/bb50f9de3a6de69e6abd6b087b52fa2418a0418b19597601605f855ad044/pydata_sphinx_theme-0.16.1.tar.gz", hash = "sha256:a08b7f0b7f70387219dc659bff0893a7554d5eb39b59d3b8ef37b8401b7642d7", size = 2412693, upload-time = "2024-12-17T10:53:39.537Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/0d/8ba33fa83a7dcde13eb3c1c2a0c1cc29950a048bfed6d9b0d8b6bd710b4c/pydata_sphinx_theme-0.16.1-py3-none-any.whl", hash = "sha256:225331e8ac4b32682c18fcac5a57a6f717c4e632cea5dd0e247b55155faeccde", size = 6723264, upload-time = "2024-12-17T10:53:35.645Z" }, +] + [[package]] name = "pygments" version = "2.19.1" @@ -5475,6 +5707,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] +[[package]] +name = "snowballstemmer" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575, upload-time = "2025-05-09T16:34:51.843Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, +] + [[package]] name = "soupsieve" version = "2.6" @@ -5484,6 +5725,142 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186, upload-time = "2024-08-13T13:39:10.986Z" }, ] +[[package]] +name = "sphinx" +version = "7.4.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911, upload-time = "2024-07-20T14:46:56.059Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624, upload-time = "2024-07-20T14:46:52.142Z" }, +] + +[[package]] +name = "sphinx-autobuild" +version = "2024.10.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "sphinx" }, + { name = "starlette" }, + { name = "uvicorn" }, + { name = "watchfiles" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/2c/155e1de2c1ba96a72e5dba152c509a8b41e047ee5c2def9e9f0d812f8be7/sphinx_autobuild-2024.10.3.tar.gz", hash = "sha256:248150f8f333e825107b6d4b86113ab28fa51750e5f9ae63b59dc339be951fb1", size = 14023, upload-time = "2024-10-02T23:15:30.172Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/c0/eba125db38c84d3c74717008fd3cb5000b68cd7e2cbafd1349c6a38c3d3b/sphinx_autobuild-2024.10.3-py3-none-any.whl", hash = "sha256:158e16c36f9d633e613c9aaf81c19b0fc458ca78b112533b20dafcda430d60fa", size = 11908, upload-time = "2024-10-02T23:15:28.739Z" }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343, upload-time = "2023-04-14T08:10:20.844Z" }, +] + +[[package]] +name = "sphinx-design" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689, upload-time = "2024-08-02T13:48:44.277Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338, upload-time = "2024-08-02T13:48:42.106Z" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[package]] +name = "sphinxcontrib-googleanalytics" +version = "0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/78/ad9a210c24499ccfd97f0eccc902576b587af82ae2dc27021e0662929940/sphinxcontrib_googleanalytics-0.5.tar.gz", hash = "sha256:a2ac6df9d16b9c124febf6b44e714c1fd9725e692b73ee84ec6b52b377ff5561", size = 4650, upload-time = "2025-05-26T15:31:42.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/c7/e68a33ba7b8a4a697c8ad278a37d7bc8521c4175b0f9248fec80ae6fed4f/sphinxcontrib_googleanalytics-0.5-py3-none-any.whl", hash = "sha256:437e529c33c441bcccceabe3ead1585115e6ba83fe90e23bd42e42521333cc0a", size = 4246, upload-time = "2025-05-26T15:32:03.111Z" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + [[package]] name = "sqlalchemy" version = "2.0.37" @@ -5687,6 +6064,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/44/69/d21eb253fa91622da25585d362a874fa4710be600f0ea9446d8d0217cec1/tokenizers-0.21.0-cp39-abi3-win_amd64.whl", hash = "sha256:87841da5a25a3a5f70c102de371db120f41873b854ba65e52bccd57df5a3780c", size = 2389192, upload-time = "2024-11-27T13:11:25.724Z" }, ] +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +] + [[package]] name = "tomli" version = "2.2.1"