From c514605f7fb743b673e39cd97f6ef0287c5cc866 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 00:15:22 -0700
Subject: [PATCH 1/8] fix code error in the agent tutorial
---
.github/workflows/documentation.yml | 2 +-
docs/source/developer_notes/agent.rst | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index fd2d6971..aecce85b 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -3,7 +3,7 @@ name: Documentation
on:
push:
branches:
- - release # Trigger the workflow when changes are pushed to the release branch
+ - li # Trigger the workflow when changes are pushed to the release branch
permissions:
contents: write
diff --git a/docs/source/developer_notes/agent.rst b/docs/source/developer_notes/agent.rst
index 90e46e91..9a39767c 100644
--- a/docs/source/developer_notes/agent.rst
+++ b/docs/source/developer_notes/agent.rst
@@ -353,8 +353,8 @@ Now, let's run the test function to see the agent in action.
.. code-block:: python
- test_react_agent(ModelClientType.GROQ, llama3_model_kwargs)
- test_react_agent(ModelClientType.OPENAI, gpt_model_kwargs)
+ test_react_agent(ModelClientType.GROQ(), llama3_model_kwargs)
+ test_react_agent(ModelClientType.OPENAI(), gpt_model_kwargs)
Our agent will show the core steps for developers via colored printout, including input_query, steps, and the final answer.
The printout of the first query with llama3 is shown below (without the color here):
From dd29e083f9bd52a3609a639d2c1a068fd3d79f34 Mon Sep 17 00:00:00 2001
From: Nishant Bhansali
Date: Thu, 11 Jul 2024 13:59:50 +0530
Subject: [PATCH 2/8] fix: spelling error
---
docs/source/developer_notes/component.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/source/developer_notes/component.rst b/docs/source/developer_notes/component.rst
index 9e465d4d..02ade72e 100644
--- a/docs/source/developer_notes/component.rst
+++ b/docs/source/developer_notes/component.rst
@@ -188,7 +188,7 @@ To add even more flexibility, we provide :class:`FunComponent
Date: Thu, 11 Jul 2024 14:48:02 +0530
Subject: [PATCH 3/8] fix: syntax error
the existing line had a syntax error
---
docs/source/get_started/installation.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/source/get_started/installation.rst b/docs/source/get_started/installation.rst
index 6c01c878..c1a514e4 100644
--- a/docs/source/get_started/installation.rst
+++ b/docs/source/get_started/installation.rst
@@ -40,7 +40,7 @@ You can use the following import:
.. code-block:: python
- from lightrag.utils import setup_env()
+ from lightrag.utils import setup_env
setup_env()
From da3d254f894e5ffc6b69481563e89463e26f3cba Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 17:42:40 -0700
Subject: [PATCH 4/8] update the developer_notes to tutorials, add container in
the index, clean up code and edit the generator, and add customization for
the react agent, and allow users to pass template
---
.github/workflows/documentation.yml | 2 +-
README.md | 8 +-
developer_notes/generator_note.py | 2 +-
developer_notes/react_note.py | 41 ++-
docs/README.md | 30 +-
docs/pyproject.toml | 4 +-
docs/source/apis/core/index.rst | 1 +
docs/source/developer_notes/index.rst | 321 -----------------
docs/source/developer_notes/logging.rst | 197 -----------
docs/source/developer_notes/rag.rst | 2 -
docs/source/index.rst | 21 +-
docs/source/insert_labels.py | 5 +-
.../{developer_notes => tutorials}/agent.rst | 87 ++++-
.../base_data_class.rst | 0
.../class_hierarchy.rst | 0
.../component.rst | 0
.../configs.rst | 2 +
.../data_class.py | 2 -
.../data_pipeline.rst | 2 +
.../datasets.rst | 2 +
.../{developer_notes => tutorials}/db.rst | 0
.../embedder.rst | 2 +
.../embedder_xy.rst | 2 +
.../evaluation.rst | 0
.../generator.rst | 87 +++--
docs/source/tutorials/index.rst | 324 +++++++++++++++++-
.../lightrag_design_philosophy.rst | 2 +
.../llm_intro.rst | 8 +-
docs/source/tutorials/logging.rst | 197 +++++++++++
.../logging_tracing.rst | 2 +
.../model_client.rst | 2 +
.../optimizer.rst | 2 +
.../output_parsers.rst | 0
.../parameter.rst | 2 +
.../{developer_notes => tutorials}/prompt.rst | 0
docs/source/tutorials/rag.rst | 4 +
.../react_agent_xy.rst | 2 +
.../retriever.rst | 3 +
.../retriever_xy.rst | 2 +
.../text_splitter.rst | 3 +
.../tool_helper.rst | 2 +
.../trainer.rst | 2 +
.../{tutorials => use_cases}/eval_a_rag.rst | 0
docs/source/use_cases/index.rst | 13 +
.../introduction_to_basedataclass.rst | 28 +-
docs/source/use_cases/logging.rst | 0
lightrag/README.md | 6 +-
lightrag/lightrag/components/agent/react.py | 45 ++-
lightrag/lightrag/core/base_data_class.py | 2 +-
lightrag/lightrag/core/generator.py | 11 -
lightrag/lightrag/core/types.py | 44 ++-
lightrag/lightrag/tracing/decorators.py | 58 ++--
52 files changed, 901 insertions(+), 683 deletions(-)
delete mode 100644 docs/source/developer_notes/index.rst
delete mode 100644 docs/source/developer_notes/logging.rst
delete mode 100644 docs/source/developer_notes/rag.rst
rename docs/source/{developer_notes => tutorials}/agent.rst (89%)
rename docs/source/{developer_notes => tutorials}/base_data_class.rst (100%)
rename docs/source/{developer_notes => tutorials}/class_hierarchy.rst (100%)
rename docs/source/{developer_notes => tutorials}/component.rst (100%)
rename docs/source/{developer_notes => tutorials}/configs.rst (71%)
rename docs/source/{developer_notes => tutorials}/data_class.py (74%)
rename docs/source/{developer_notes => tutorials}/data_pipeline.rst (60%)
rename docs/source/{developer_notes => tutorials}/datasets.rst (72%)
rename docs/source/{developer_notes => tutorials}/db.rst (100%)
rename docs/source/{developer_notes => tutorials}/embedder.rst (99%)
rename docs/source/{developer_notes => tutorials}/embedder_xy.rst (99%)
rename docs/source/{developer_notes => tutorials}/evaluation.rst (100%)
rename docs/source/{developer_notes => tutorials}/generator.rst (78%)
rename docs/source/{developer_notes => tutorials}/lightrag_design_philosophy.rst (99%)
rename docs/source/{developer_notes => tutorials}/llm_intro.rst (97%)
rename docs/source/{developer_notes => tutorials}/logging_tracing.rst (99%)
rename docs/source/{developer_notes => tutorials}/model_client.rst (99%)
rename docs/source/{developer_notes => tutorials}/optimizer.rst (83%)
rename docs/source/{developer_notes => tutorials}/output_parsers.rst (100%)
rename docs/source/{developer_notes => tutorials}/parameter.rst (73%)
rename docs/source/{developer_notes => tutorials}/prompt.rst (100%)
create mode 100644 docs/source/tutorials/rag.rst
rename docs/source/{developer_notes => tutorials}/react_agent_xy.rst (99%)
rename docs/source/{developer_notes => tutorials}/retriever.rst (99%)
rename docs/source/{developer_notes => tutorials}/retriever_xy.rst (99%)
rename docs/source/{developer_notes => tutorials}/text_splitter.rst (99%)
rename docs/source/{developer_notes => tutorials}/tool_helper.rst (99%)
rename docs/source/{developer_notes => tutorials}/trainer.rst (73%)
rename docs/source/{tutorials => use_cases}/eval_a_rag.rst (100%)
create mode 100644 docs/source/use_cases/index.rst
rename docs/source/{tutorials => use_cases}/introduction_to_basedataclass.rst (96%)
create mode 100644 docs/source/use_cases/logging.rst
diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index aecce85b..fd2d6971 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -3,7 +3,7 @@ name: Documentation
on:
push:
branches:
- - li # Trigger the workflow when changes are pushed to the release branch
+ - release # Trigger the workflow when changes are pushed to the release branch
permissions:
contents: write
diff --git a/README.md b/README.md
index 672084c7..4780c735 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Because of this, no library can provide out-of-the-box solutions. Users must bui
LightRAG is born to be light, modular, and robust, with a 100% readable codebase.
-Further reading: [Introduction](https://lightrag.sylph.ai/), [Design Philosophy](https://lightrag.sylph.ai/developer_notes/lightrag_design_philosophy.html) and [Class hierarchy](https://lightrag.sylph.ai/developer_notes/class_hierarchy.html).
+Further reading: [Introduction](https://lightrag.sylph.ai/), [Design Philosophy](https://lightrag.sylph.ai/tutorials/lightrag_design_philosophy.html) and [Class hierarchy](https://lightrag.sylph.ai/tutorials/class_hierarchy.html).
### **3. Build the Documentation**
+Go to the `docs` directory and run the following command to build the documentation:
```python
cd docs
make html
```
-Build with more options:
+Build with more verbose output:
```
sphinx-build -b html source build -v
@@ -77,10 +82,6 @@ The `docs/source/index.rst` is the root document for Sphinx-generated documentat
For example, in the `index.rst`, the `:caption: Get Started` corresponds to the section name of the documentation site. `installation` and `introduction` are the detailed pages.
```python
-What is LightRAG?
-=================
-LightRAG comes from the best of the AI research and engineering. Fundamentally, we ask ourselves: what kind of system that combines the best of research(such as LLM), engineering (such as 'jinja') to build the best applications? We are not a framework. We do not want you to directly install the package. We want you to carefully decide to take modules and structures from here to build your own library and applications. This is a cookbook organized uniquely for easy understanding: you can read the 1000 lines of code to see a typical RAG end-to-end without jumping between files and going through multi-level class inheritance. If we build our system expanding from light_rag.py, we as a community will share the same RAG languages, and share other building blocks and use cases easily without depending on a complex framework.
-
.. toctree::
:glob:
:maxdepth: 1
@@ -90,19 +91,20 @@ LightRAG comes from the best of the AI research and engineering. Fundamentally,
get_started/introduction
```
-![Untitled](https://prod-files-secure.s3.us-west-2.amazonaws.com/bf4570a3-1b74-45d8-8b3b-10221ec99a40/edd3bba3-265a-44cc-94d5-5ab222f9cb71/Untitled.png)
+
### **Existing Sections**
Existing sections include:
-`get_started/`: Includes installation and LightRAG introduction
+`get_started/`: Includes installation and LightRAG in 10 minutes
-`tutorials/`: Includes sample code and instructions
+`tutorials/`: Includes our main tutorials
+`use_cases/`: Includes the use cases of LightRAG that will be added in the future and which accepts community contributions
`apis/`: All the source-code-related documents will be included in this directory
-`resources/`: Include all the LightRAG-relevant resources.
+
## How to Edit the Documentation
diff --git a/docs/pyproject.toml b/docs/pyproject.toml
index b182d7d8..70aeace9 100644
--- a/docs/pyproject.toml
+++ b/docs/pyproject.toml
@@ -1,13 +1,13 @@
[tool.poetry]
name = "lightrag-docs"
-version = "0.1.0"
+version = "0.0.0.beta.1"
description = "Documentation for the lightrag project"
authors = ["Your Name "]
license = "MIT"
packages = [{ from = "_dummy", include = "dummy" }] # empty packages
[tool.poetry.dependencies]
-python = ">=3.11, <4.0"
+python = ">=3.9, <4.0"
lightrag = { path = "../lightrag", develop = true } # document always follow the latest version of the library
[tool.poetry.group.doc.dependencies]
diff --git a/docs/source/apis/core/index.rst b/docs/source/apis/core/index.rst
index e95b5f0f..f047578a 100644
--- a/docs/source/apis/core/index.rst
+++ b/docs/source/apis/core/index.rst
@@ -39,6 +39,7 @@ Overview
core.base_data_class
core.component
+ core.container
core.default_prompt_template
core.embedder
core.generator
diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst
deleted file mode 100644
index 79b37ca4..00000000
--- a/docs/source/developer_notes/index.rst
+++ /dev/null
@@ -1,321 +0,0 @@
-.. _developer_notes:
-
-
-Tutorials
-=============================
-
-.. *Why and How Each Part works*
-
-Learn the `why` and `how-to` (customize and integrate) behind each core part within the `LightRAG` library.
-These are our most important tutorials before you move ahead to build your use cases end to end.
-
-
-.. raw::
-
- .. note::
-
- You can read interchangably between :ref:`Use Cases `.
-
-
-
-.. figure:: /_static/images/LLM_arch.png
- :alt: LLM application is no different from a mode training/eval workflow
- :align: center
- :width: 600px
-
- LLM application is no different from a mode training/evaluation workflow
-
- .. :height: 100px
- .. :width: 200px
-
-
-The `LightRAG` library focuses on providing building blocks for developers to **build** and **optimize** the task pipeline.
-We have a clear :doc:`lightrag_design_philosophy`, which results in this :doc:`class_hierarchy`.
-
-.. toctree::
- :maxdepth: 1
- :caption: Introduction
- :hidden:
-
- lightrag_design_philosophy
- class_hierarchy
-
-
-Introduction
--------------------
-
-
-:ref:`Component` is to LLM task pipelines what `nn.Module` is to PyTorch models.
-An LLM task pipeline in LightRAG mainly consists of components, such as a `Prompt`, `ModelClient`, `Generator`, `Retriever`, `Agent`, or any other custom components.
-This pipeline can be `Sequential` or a Directed Acyclic Graph (DAG) of components.
-A `Prompt` will work with `DataClass` to ease data interaction with the LLM model.
-A `Retriever` will work with databases to retrieve context and overcome the hallucination and knowledge limitations of LLM, following the paradigm of Retrieval-Augmented Generation (RAG).
-An `Agent` will work with tools and an LLM planner for enhanced ability to reason, plan, and act on real-world tasks.
-
-
-Additionally, what shines in LightRAG is that all orchestrator components, like `Retriever`, `Embedder`, `Generator`, and `Agent`, are model-agnostic.
-You can easily make each component work with different models from different providers by switching out the `ModelClient` and its `model_kwargs`.
-
-
-We will introduce the libraries starting from the core base classes, then move to the RAG essentials, and finally to the agent essentials.
-With these building blocks, we will further introduce optimizing, where the optimizer uses building blocks such as Generator for auto-prompting and retriever for dynamic few-shot in-context learning (ICL).
-
-Building
--------------------
-
-
-
-Base classes
-~~~~~~~~~~~~~~~~~~~~~~
-Code path: :ref:`lightrag.core `.
-
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Base Class
- - Description
- * - :doc:`component`
- - The building block for task pipeline. It standardizes the interface of all components with `call`, `acall`, and `__call__` methods, handles state serialization, nested components, and parameters for optimization. Components can be easily chained together via ``Sequential``.
- * - :doc:`base_data_class`
- - The base class for data. It eases the data interaction with LLMs for both prompt formatting and output parsing.
-
-
-
-
-.. create side bar navigation
-
-.. toctree::
- :maxdepth: 1
- :caption: Base Classes
- :hidden:
-
- component
- base_data_class
-
-RAG Essentials
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-RAG components
-^^^^^^^^^^^^^^^^^^^
-
-
-Code path: :ref:`lightrag.core`. For abstract classes:
-
-- ``ModelClient``: the functional subclass is in :ref:`lightrag.components.model_client`.
-- ``Retriever``: the functional subclass is in :ref:`lightrag.components.retriever`.
-
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`prompt`
- - Built on `jinja2`, it programmatically and flexibly formats prompts as input to the generator.
- * - :doc:`model_client`
- - The standard `protocol` to intergrate LLMs, Embedding models, ranking models, etc into respective `orchestrator` components, either via APIs or local to reach to `model agnostic`.
- * - :doc:`generator`
- - The `orchestrator` for LLM prediction. It streamlines three components: `ModelClient`, `Prompt`, and `output_processors` and works with optimizer for prompt optimization.
- * - :doc:`output_parsers`
- - The `interpreter` of the LLM output. The component that parses the output string to structured data.
- * - :doc:`embedder`
- - The component that orchestrates model client (Embedding models in particular) and output processors.
- * - :doc:`retriever`
- - The base class for all retrievers who in particular retrieve relevant documents from a given database to add **context** to the generator.
-
-
-Data Pipeline and Storage
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Data Processing: including transformer, pipeline, and storage. Code path: ``lightrag.components.data_process``, ``lightrag.core.db``, and ``lightrag.database``.
-Components work on a sequence of ``Document`` and return a sequence of ``Document``.
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`text_splitter`
- - To split long text into smaller chunks to fit into the token limits of embedder and generator or to ensure more relevant context while being used in RAG.
- * - :doc:`db`
- - Understanding the **data modeling, processing, and storage** as a whole. We will build a chatbot with enhanced memory and memoy retrieval in this note (RAG).
-
-
-.. * - :doc:`data_pipeline`
-.. - The pipeline to process data, including text splitting, embedding, and retrieval.
-
-.. Let us put all of these components together to build a :doc:`rag` (Retrieval Augmented Generation), which requires data processing pipeline along with a task pipeline to run user queries.
-
-.. toctree::
- :maxdepth: 1
- :caption: RAG Essentials
- :hidden:
-
- prompt
- model_client
- generator
- output_parsers
- embedder
- retriever
- text_splitter
- db
-
-
-
-Agent Essentials
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Agent in ``components.agent`` is LLM great with reasoning, planning, and using tools to interact and accomplish tasks.
-
-.. list-table::
- :widths: 30 70
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`tool_helper`
- - Provide tools (function calls) to interact with the generator.
- * - :doc:`agent`
- - The ReactAgent.
-
-.. toctree::
- :maxdepth: 1
- :caption: Agent Essentials
- :hidden:
-
- tool_helper
- agent
-
-.. Core functionals
-.. -------------------
-.. Code path: ``lightrag.core``
-
-.. :widths: 20 80
-.. :header-rows: 1
-
-.. * - Functional
-.. - Description
-.. * - :doc:`string_parser`
-.. - Parse the output string to structured data.
-.. * - :doc:`tool_helper`
-.. - Provide tools to interact with the generator.
-
-.. * - :doc:`memory`
-.. - Store the history of the conversation.
-
-
-
-
-
-
-
-
-Optimizing
--------------------
-
-Evaluating
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`datasets`
- - The datasets used in the evaluation.
- * - :doc:`evaluation`
- - The evaluation metrics and methods.
-
-.. toctree::
- :maxdepth: 1
- :caption: Evaluating
- :hidden:
-
-
- datasets
-
- evaluation
-
-
-Training
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**Tutorials in this section are coming soon!**
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`parameter`
- - The parameter class to optimize.
- * - :doc:`optimizer`
- - The optimizer to optimize the parameters.
- * - :doc:`trainer`
- - The trainer to train the model.
-
-.. toctree::
- :maxdepth: 1
- :caption: Training
- :hidden:
-
- parameter
-
- optimizer
- trainer
-
-
-Logging & Tracing
-------------------------------------
-Code path: :ref:`lightrag.utils ` and :ref:`lightrag.tracing `.
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`logging`
- - LightRAG uses native ``logging`` module as the first line of debugging tooling. We made the effort to help you set it up easily.
- * - :doc:`logging_tracing`
- - We provide two tracing methods to help you develop and improve the Generator:
- 1. Trace the history change(states) on prompt during your development process.
- 2. Trace all failed LLM predictions in a unified file for further improvement.
-
-.. toctree::
- :maxdepth: 1
- :caption: Logging & Tracing
- :hidden:
-
-
- logging
- logging_tracing
-
-
-
-Configurations
--------------------
-Code path: :ref:`lightrag.utils `.
-
-.. list-table::
- :widths: 20 80
- :header-rows: 1
-
- * - Part
- - Description
- * - :doc:`configs`
- - The configurations for the components.
-
-
-
-.. toctree::
- :maxdepth: 1
- :caption: Configurations
- :hidden:
-
-
- configs
diff --git a/docs/source/developer_notes/logging.rst b/docs/source/developer_notes/logging.rst
deleted file mode 100644
index 1252bfd8..00000000
--- a/docs/source/developer_notes/logging.rst
+++ /dev/null
@@ -1,197 +0,0 @@
-Logging
-====================
-
-
-The Python logging module [1]_ is a powerful and flexible tool for debugging and tracing.
-LightRAG uses the native logging module as the *first line of defense*.
-
-Design
---------------------
-Some libraries may use hooks [2]_ and callbacks [3]_ [4]_, or advanced web-based debugging tools [5]_ [6]_ [7]_.
-Hooks and callbacks are conceptually similar in that they both allow users to execute custom code at specific points during the execution of a program.
-Both provide mechanisms to inject additional behavior in response to certain events or conditions, without modifying the core logic.
-PyTorch defines, registers, and executes hooks mainly in its base classes like `nn.Module` and `Tensor`, without polluting the functional and user-facing APIs.
-
-At this point, our objectives are:
-
-1. Maximize debugging capabilities via the simple logging module to keep the source code clean.
-2. Additionally, as we can't always control the outputs of generators, we will provide customized logger and tracers(drop-in decorators) for them, for which we will explain in :doc:`logging_tracing`. This will not break the first objective.
-
-In the future, when we have more complex requirements from users, we will consider adding hooks/callbacks but we will do it in a way to keep the functional and user-facing APIs clean.
-
-How the library logs
-~~~~~~~~~~~~~~~~~~~~~~
-In each file, we simply set the logger with the following code:
-
-.. code-block:: python
-
- import logging
-
- log = logging.getLogger(__name__)
-
-We then use `log` and decide what level of logging we want to use in each function.
-Here is how :ref:`Generator ` logs.
-
-How users set up the logger
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We provide a simple function :func:`get_logger` to help users set up loggers with great default formatting and handlers.
-The simplest way to get up a logger and see the library logs is to call this function:
-
-.. code-block:: python
-
- from lightrag.utils.logger import get_logger
-
-
- root_logger = get_logger()
-
-Here is an example of the printed log message if users run the generator after setting up the logger:
-
-.. code-block::
-
- 2024-07-05 18:49:39 - generator - INFO - [generator.py:249:call] - output: GeneratorOutput(data="Hello! I'm just a computer program, so I don't have feelings, but I'm here and ready to help you. How can I assist you today?", error=None, usage=None, raw_response="Hello! I'm just a computer program, so I don't have feelings, but I'm here and ready to help you. How can I assist you today?", metadata=None)
-
-
-printc function
-~~~~~~~~~~~~~~~~~~~~~~
-A neat tiny function :func:`printc` is provided to print colored text to the console.
-It has similar formatting to the logger.
-Here is an example of how to use it:
-
-.. code-block:: python
-
- from lightrag.utils.logger import printc
-
- printc("All logging examples are done. Feeling green!", color="green")
-
-The output will be:
-
-.. raw:: html
-
-
- 2024-07-05 22:25:43 - [logging_config.py:98:<module>] - All logging examples are done. Feeling green!
-
-
-
-
-.. .. list-table:: Parameters of :func:`get_logger`
-.. :header-rows: 1
-.. :widths: 30 70
-
-.. * - **Argument**
-.. - **Description**
-.. * - ``name: Optional[str] = None``
-.. - Name of the logger. If None, the root logger is used.
-.. * - ``level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"``
-.. - Log level for the logger. Can be "DEBUG", "INFO", "WARNING", "ERROR", or "CRITICAL".
-.. * - ``save_dir: Optional[str] = None``
-.. - Directory where the log files will be saved. Defaults to "./logs".
-.. * - ``filename: Optional[str] = None``
-.. - Name of the log file. Defaults to "lib.log" for the root logger and "{name}.log" for named logger.
-.. * - ``enable_console: bool = True``
-.. - Whether to enable logging to console. Defaults to True.
-.. * - ``enable_file: bool = False``
-.. - Whether to enable logging to a file. Defaults to False.
-
-Use Logger in Projects
--------------------------
-There are two distinct ways to set up the logging in your project:
-
-1. Have both the library loggind and your application logging in a single file. This is the simplest setup.
-2. Use both root and named logger to log library and application logs separately.
-
-Set up all logs in one file
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Assume your source code is at `src/task.py`. You can log simply by:
-
-.. code-block:: python
-
- import logging
-
- log = logging.getLogger(__name__)
-
- class Task:
- def __init__(self):
- log.info("This is a user program child logger")
-
-In the main file, you can config a single root logger to log both library and application logs:
-
-.. code-block:: python
-
- import logging
- from lightrag.utils.logger import get_logger
-
- root_logger = get_logger(level="DEBUG", save_dir="./logs") # log to ./logs/lib.log
-
- # run code from the library components such as generator
- # ....
-
- root_logger.info("This is the log in the main file")
-
-This way, all logs will be saved in `./logs/lib.log`.
-
-Separate library and application logs
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In some cases, if users prefer to separate the library and application logs, they can use a named logger.
-
-In the user program, such as at `src/task.py`, you can set up a named logger and logs to `./logs/my_app.log`:
-
-.. code-block:: python
-
- from lightrag.utils.logger import get_logger
-
- app_logger = get_logger(name="my_app", level="DEBUG", save_dir="./logs") # log to ./logs/my_app.log
-
- class Task:
- def __init__(self):
- app_logger.info("This is a user program child logger")
-
-The difference is that you have already attached handlers to the app_logger.
-In the main file, you do not need to set up a root logger to enable your application logs.
-However, you can still set up a root logger to log the library logs separately if needed, and create another named logger to continue logging in the main file.
-
-
-
-.. It works similarly if it is to be logged to console.
-.. Config 3 can be quite neat:
-
-.. - You can enable different levels of logging for the library and your application.
-.. - You can easily focus on debugging your own code without being distracted by the library logs and still have the option to see the library logs if needed.
-
-.. .. Create a named logger
-.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. .. code-block:: python
-
-.. from lightrag.utils.logger import get_logger
-
-.. app_logger = get_logger(name="my_app", level="DEBUG", save_dir="./logs") # log to ./logs/my_app.log
-.. # or
-.. logger = get_logger(name=__name__, level="DEBUG", save_dir="./logs", filename="my_app.log")
-
-.. app_logger.debug("This is a debug message")
-.. app_logger.info("This is an info message")
-.. app_logger.warning("This is a warning message")
-.. app_logger.error("This is an error message")
-.. app_logger.critical("This is a critical message")
-
-
-.. admonition:: References
- :class: highlight
-
- .. [1] Python logging module: https://docs.python.org/3/library/logging.html
- .. [2] Hooks in PyTorch: https://pytorch.org/docs/stable/generated/torch.nn.modules.module.register_module_forward_hook.html
- .. [3] Callbacks in Transformers: https://huggingface.co/docs/transformers/main/en/main_classes/callback
- .. [4] Callbacks in PyTorch Lightning: https://pytorch-lightning.readthedocs.io/en/1.5.10/extensions/callbacks.html
- .. [5] Weights & Biases: https://wandb.ai/site
- .. [6] TensorBoard: https://www.tensorflow.org/tensorboard
- .. [7] Arize Phoenix: https://docs.arize.com/phoenix
-
-
-
-.. admonition:: API References
- :class: highlight
-
- - :func:`utils.logger.get_logger`
- - :func:`utils.logger.printc`
- - :ref:`Generator`
diff --git a/docs/source/developer_notes/rag.rst b/docs/source/developer_notes/rag.rst
deleted file mode 100644
index b1d74de1..00000000
--- a/docs/source/developer_notes/rag.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-RAG application
-===================
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 7ed3b674..c138e8c5 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -52,7 +52,7 @@ LightRAG shares similar design pattern as `PyTorch` for deep learning modeling.
We provide developers with fundamental building blocks of *100% clarity and simplicity*.
- Only two fundamental but powerful base classes: `Component` for the pipeline and `DataClass` for data interaction with LLMs.
-- A highly readable codebase and less than two levels of class inheritance. :doc:`developer_notes/class_hierarchy`.
+- A highly readable codebase and less than two levels of class inheritance. :doc:`tutorials/class_hierarchy`.
- We maximize the library's tooling and prompting capabilities to minimize the reliance on LLM API features such as tools and JSON format.
- The result is a library with bare minimum abstraction, providing developers with *maximum customizability*.
@@ -152,6 +152,19 @@ Similar to the PyTorch `module`, our `Component` provides excellent visualizatio
)
)
+To switch to `gpt-3.5-turbo` by OpenAI, simply update the `model_client`` and `model_kwargs` in the Generator component.
+
+.. code-block:: python
+
+ from lightrag.components.model_client import OpenAIClient
+
+ self.generator = Generator(
+ model_client=OpenAIClient(),
+ model_kwargs={"model": "gpt-3.5-turbo"},
+ template=template,
+ )
+
+
.. and Robustness
@@ -160,8 +173,8 @@ Robust
Our simplicity did not come from doing less.
On the contrary, we have to do more and go deeper and wider on any topic to offer developers *maximum control and robustness*.
-- LLMs are sensitive to the prompt. We allow developers full control over their prompts without relying on LLM API features such as tools and JSON format with components like ``Prompt``, ``OutputParser``, ``FunctionTool``, and ``ToolManager``.
-- Our goal is not to optimize for integration, but to provide a robust abstraction with representative examples. See this in ``ModelClient`` and ``Retriever``.
+- LLMs are sensitive to the prompt. We allow developers full control over their prompts without relying on LLM API features such as tools and JSON format with components like `Prompt`, `OutputParser`, `FunctionTool`, and `ToolManager`.
+- Our goal is not to optimize for integration, but to provide a robust abstraction with representative examples. See this in :ref:`ModelClient` and :ref:`Retriever` components.
- All integrations, such as different API SDKs, are formed as optional packages but all within the same library. You can easily switch to any models from different providers that we officially support.
@@ -199,7 +212,7 @@ We are building a library that unites the two worlds, forming a healthy LLM appl
:maxdepth: 1
:hidden:
- developer_notes/index
+ tutorials/index
.. :caption: Tutorials - How each part works
.. :hidden:
diff --git a/docs/source/insert_labels.py b/docs/source/insert_labels.py
index 324c10af..7b0fbd46 100644
--- a/docs/source/insert_labels.py
+++ b/docs/source/insert_labels.py
@@ -25,10 +25,9 @@ def add_reference_labels(directory: str):
# Specify the directories you want to process
add_reference_labels("./source/apis/core")
add_reference_labels("./source/apis/components")
- add_reference_labels(
- "./source/apis/components/_autosummary"
- ) # add label to component autosummary
+
add_reference_labels("./source/apis/eval")
add_reference_labels("./source/apis/utils")
add_reference_labels("./source/apis/tracing")
add_reference_labels("./source/apis/optim")
+ # add_reference_labels("./source/tutorials")
diff --git a/docs/source/developer_notes/agent.rst b/docs/source/tutorials/agent.rst
similarity index 89%
rename from docs/source/developer_notes/agent.rst
rename to docs/source/tutorials/agent.rst
index 9a39767c..26afd674 100644
--- a/docs/source/developer_notes/agent.rst
+++ b/docs/source/tutorials/agent.rst
@@ -1,3 +1,6 @@
+.. _tutorials-agent:
+
+
Agent
====================
@@ -178,8 +181,8 @@ Additionally, it manages `step_history` as a list of ``StepOutput`` instances fo
* - **Name**
- **Description**
- * - ``__init__(self, tools: List[Union[Callable, AsyncCallable, FunctionTool]] = [], max_steps: int = 10, add_llm_as_fallback: bool = True, examples: List[FunctionExpression] = [], *, model_client: ModelClient, model_kwargs: Dict = {})``
- - Initialize the `ReActAgent` with the specified tools, maximum steps, fallback option, examples, model client, and model arguments.
+ * - ``__init__(self, tools: List[Union[Callable, AsyncCallable, FunctionTool]] = [], max_steps: int = 10, add_llm_as_fallback: bool = True, examples: List[FunctionExpression] = [], *, model_client: ModelClient, model_kwargs: Dict = {}, template: Optional[str] = None)``
+ - Initialize the `ReActAgent` with the specified tools, maximum steps, fallback option, examples, model client, model arguments, and template if you want to customize the prompt.
* - ``call(self, input: str, prompt_kwargs: Optional[Dict] = {}, model_kwargs: Optional[Dict] = {}) -> Any``
- Prompt the agent with an input query and process the steps to generate a response.
@@ -292,9 +295,11 @@ The structure of React, including the initialization arguments and two major com
{% endif %}
{# output format and examples #}
+
{{output_format_str}}
+
- {# Specifications TODO: preference between the usage of llm tool vs the other tool #}
+ {# Task specification to teach the agent how to think using 'divide and conquer' strategy #}
- For simple queries: Directly call the ``finish`` action and provide the answer.
- For complex queries:
- Step 1: Read the user query and potentially divide it into subqueries. And get started with the first subquery.
@@ -423,8 +428,82 @@ For the second query, the comparison is shown below:
Answer without agent: GeneratorOutput(data='Here are 5 words that rhyme with "cool":\n\n1. rule\n2. tool\n3. fool\n4. pool\n5. school\n\nAnd here\'s a 4-sentence poem using these words:\n\nIn the summer heat, I like to be cool,\nFollowing the rule, I take a dip in the pool.\nI\'m not a fool, I know just what to do,\nI grab my tool and head back to school.', error=None, usage=None, raw_response='Here are 5 words that rhyme with "cool":\n\n1. rule\n2. tool\n3. fool\n4. pool\n5. school\n\nAnd here\'s a 4-sentence poem using these words:\n\nIn the summer heat, I like to be cool,\nFollowing the rule, I take a dip in the pool.\nI\'m not a fool, I know just what to do,\nI grab my tool and head back to school.', metadata=None)
The ReAct agent is particularly helpful for answering queries that require capabilities like computation or more complicated reasoning and planning.
-However, using it on general queries might not be an overkill, as it might take more steps than necessary to answer the query.
+However, using it on general queries might be an overkill, as it might take more steps than necessary to answer the query.
+
+Customization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**Template**
+
+
+The first thing you want to customize is the template itself.
+You can do this by passing your own template to the agent's constructor.
+We suggest you to modify our default template: :const:`DEFAULT_REACT_AGENT_SYSTEM_PROMPT`.
+
+
+
+**Examples for Better Output Format**
+
+
+Secondly, the ``examples`` in the constructor allow you to provide more examples to enforce the correct output format.
+For instance, if we want it to learn how to correctly call `multiply`, we can pass in a list of ``FunctionExpression`` instances with the correct format.
+Classmethod ``from_function`` can be used to create a ``FunctionExpression`` instance from a function and its arguments.
+
+.. code-block:: python
+
+ from lightrag.core.types import FunctionExpression
+
+ # generate an example of calling multiply with key-word arguments
+ example_using_multiply = FunctionExpression.from_function(
+ func=multiply,
+ thought="Now, let's multiply two numbers.",
+ a=3,
+ b=4,
+ )
+ examples = [example_using_multiply]
+
+ # pass it to the agent
+
+We can visualize how this is passed to the planner prompt via:
+
+.. code-block:: python
+
+ react.planner.print_prompt()
+
+
+The above example will be formated as:
+
+.. code-block::
+
+
+ Your output should be formatted as a standard JSON instance with the following schema:
+ ```
+ {
+ "thought": "Why the function is called (Optional[str]) (optional)",
+ "action": "FuncName() Valid function call expression. Example: \"FuncName(a=1, b=2)\" Follow the data type specified in the function parameters.e.g. for Type object with x,y properties, use \"ObjectType(x=1, y=2) (str) (required)"
+ }
+ ```
+ Examples:
+ ```
+ {
+ "thought": "Now, let's multiply two numbers.",
+ "action": "multiply(a=3, b=4)"
+ }
+ ________
+ {
+ "thought": "I have finished the task.",
+ "action": "finish(answer=\"final answer: 'answer'\")"
+ }
+ ________
+ ```
+ -Make sure to always enclose the JSON output in triple backticks (```). Please do not add anything other than valid JSON output!
+ -Use double quotes for the keys and string values.
+ -DO NOT mistaken the "properties" and "type" in the schema as the actual fields in the JSON output.
+ -Follow the JSON formatting conventions.
+
+
+**Subclass ReActAgent**
+If you want to customize the agent further, you can subclass the :class:`ReActAgent` and override the methods you want to change.
.. .. figure:: /_static/images/query_1.png
.. :align: center
.. :alt: DataClass
diff --git a/docs/source/developer_notes/base_data_class.rst b/docs/source/tutorials/base_data_class.rst
similarity index 100%
rename from docs/source/developer_notes/base_data_class.rst
rename to docs/source/tutorials/base_data_class.rst
diff --git a/docs/source/developer_notes/class_hierarchy.rst b/docs/source/tutorials/class_hierarchy.rst
similarity index 100%
rename from docs/source/developer_notes/class_hierarchy.rst
rename to docs/source/tutorials/class_hierarchy.rst
diff --git a/docs/source/developer_notes/component.rst b/docs/source/tutorials/component.rst
similarity index 100%
rename from docs/source/developer_notes/component.rst
rename to docs/source/tutorials/component.rst
diff --git a/docs/source/developer_notes/configs.rst b/docs/source/tutorials/configs.rst
similarity index 71%
rename from docs/source/developer_notes/configs.rst
rename to docs/source/tutorials/configs.rst
index 6cf0e7e8..8b8db123 100644
--- a/docs/source/developer_notes/configs.rst
+++ b/docs/source/tutorials/configs.rst
@@ -1,2 +1,4 @@
+.. _configs:
+
Configurations
===================
diff --git a/docs/source/developer_notes/data_class.py b/docs/source/tutorials/data_class.py
similarity index 74%
rename from docs/source/developer_notes/data_class.py
rename to docs/source/tutorials/data_class.py
index e09c9513..551f5e75 100644
--- a/docs/source/developer_notes/data_class.py
+++ b/docs/source/tutorials/data_class.py
@@ -8,5 +8,3 @@ class TrecData:
# lightrag
-
-from lightrag.core import DataClass
diff --git a/docs/source/developer_notes/data_pipeline.rst b/docs/source/tutorials/data_pipeline.rst
similarity index 60%
rename from docs/source/developer_notes/data_pipeline.rst
rename to docs/source/tutorials/data_pipeline.rst
index ab4b2bd2..b9da3d63 100644
--- a/docs/source/developer_notes/data_pipeline.rst
+++ b/docs/source/tutorials/data_pipeline.rst
@@ -1,2 +1,4 @@
+.. _data_pipeline:
+
Data Pipeline
================
diff --git a/docs/source/developer_notes/datasets.rst b/docs/source/tutorials/datasets.rst
similarity index 72%
rename from docs/source/developer_notes/datasets.rst
rename to docs/source/tutorials/datasets.rst
index 365591a1..186ce090 100644
--- a/docs/source/developer_notes/datasets.rst
+++ b/docs/source/tutorials/datasets.rst
@@ -1,3 +1,5 @@
+.. _datasets:
+
Datasets
================
Coming soon!
diff --git a/docs/source/developer_notes/db.rst b/docs/source/tutorials/db.rst
similarity index 100%
rename from docs/source/developer_notes/db.rst
rename to docs/source/tutorials/db.rst
diff --git a/docs/source/developer_notes/embedder.rst b/docs/source/tutorials/embedder.rst
similarity index 99%
rename from docs/source/developer_notes/embedder.rst
rename to docs/source/tutorials/embedder.rst
index 525e1007..187a99a7 100644
--- a/docs/source/developer_notes/embedder.rst
+++ b/docs/source/tutorials/embedder.rst
@@ -1,3 +1,5 @@
+.. _tutorials-embedder:
+
Embedder
============
.. .. admonition:: Author
diff --git a/docs/source/developer_notes/embedder_xy.rst b/docs/source/tutorials/embedder_xy.rst
similarity index 99%
rename from docs/source/developer_notes/embedder_xy.rst
rename to docs/source/tutorials/embedder_xy.rst
index e714a153..9bd59334 100644
--- a/docs/source/developer_notes/embedder_xy.rst
+++ b/docs/source/tutorials/embedder_xy.rst
@@ -1,3 +1,5 @@
+.. _embedder_xy:
+
Embedder
============
diff --git a/docs/source/developer_notes/evaluation.rst b/docs/source/tutorials/evaluation.rst
similarity index 100%
rename from docs/source/developer_notes/evaluation.rst
rename to docs/source/tutorials/evaluation.rst
diff --git a/docs/source/developer_notes/generator.rst b/docs/source/tutorials/generator.rst
similarity index 78%
rename from docs/source/developer_notes/generator.rst
rename to docs/source/tutorials/generator.rst
index 08fdf804..baef7675 100644
--- a/docs/source/developer_notes/generator.rst
+++ b/docs/source/tutorials/generator.rst
@@ -10,8 +10,9 @@ Generator
.. *The Center of it All*
+
`Generator` is a user-facing orchestration component with a simple and unified interface for LLM prediction.
-It is a pipeline that consists of three subcomponents.
+It is a pipeline consisting of three subcomponents.
Design
---------------------------------------
@@ -21,69 +22,83 @@ Design
:alt: LightRAG generator design
:width: 700px
- Generator-The orchestrator for LLM prediction
+ Generator - The Orchestrator for LLM Prediction
+
+
+
+
+The :class:`Generator` is designed to achieve the following goals:
-:class:`Generator` is designed to achieve the following goals:
+1. Model Agnostic: The Generator should be able to call any LLM model with the same prompt.
+2. Unified Interface: It should manage the pipeline from prompt(input)->model call -> output parsing.
+3. Unified Output: This will make it easy to log and save records of all LLM predictions.
+4. Work with Optimizer: It should be able to work with Optimizer to optimize the prompt.
-- Model Agnostic: The Generator should be able to call any LLM model with the same prompt.
-- Unified Interface: It should manage the pipeline of prompt(input)->model call -> output parsing.
-- Unified Output: This will make it easy to log and save records of all LLM predictions.
-- Work with Optimizer: It should be able to work with Optimizer to optimize the prompt.
+The first three goals apply to other orchestrator components like :ref:`Retriever`, :ref:`Embedder`, and :ref:`Agent` (mostly) as well.
-An orchestrator
+
+An Orchestrator
^^^^^^^^^^^^^^^^^
It orchestrates three components:
-- ``Prompt``: by taking in ``template`` (string) and ``prompt_kwargs`` (dict) to format the prompt at initialization. When the ``template`` is not given, it defaults to :const:`DEFAULT_LIGHTRAG_SYSTEM_PROMPT`.
+- `Prompt`: by taking in ``template`` (string) and ``prompt_kwargs`` (dict) to format the prompt at initialization.
+ When the ``template`` is not provided, it defaults to :const:`DEFAULT_LIGHTRAG_SYSTEM_PROMPT`.
-- ``ModelClient``: by taking in already instantiated ``model_client`` and ``model_kwargs`` to call the model. Switching out the model client will allow you to call any LLM model on the same prompt and output parsing.
+- `ModelClient`: by taking in an already instantiated ``model_client`` and ``model_kwargs`` to call the model.
+ Switching out the model client allows you to call any LLM model using the same prompt and output parsing.
-- ``output_processors``: component or chained components via ``Sequential`` to process the raw response to desired format. If no output processor provided, it is decided by Model client, often return raw string response (from the first response message).
+- `output_processors`: A single component or chained components via :class:`Sequential` to process the raw response to desired format.
+ If no output processor provided, it is decided by the model client and often returns raw string response (from the first response message).
**Call and arguments**
-Generator supports both ``call`` (``__call__``) and ``acall`` method.
+The `Generator` supports both the ``call`` (``__call__``) and ``acall`` methods.
They take two optional arguments:
-- ``prompt_kwargs`` (dict): to be passed to its ``Prompt`` component.
-- ``model_kwargs`` (dict): will be combined with the ``model_kwargs`` from the initial model client.
+- ``prompt_kwargs`` (dict): This is combined with the ``prompt_kwargs`` from the initial ``Prompt`` component and used to format the prompt.
+- ``model_kwargs`` (dict): This is combined with the ``model_kwargs`` from the initial model client, and along with :const:`ModelType.LLM`, it is passed to the ``ModelClient``.
+ The ModelClient will interpret all the inputs as ``api_kwargs`` specific to each model API provider.
-The generator will call ``Prompt`` to format the final prompt and adapt the inputs to ones workable with ``ModelClient``.
-In particular, it passes:
-- Formatted prompt after calling ``Prompt``.
-- All combined ``model_kwargs`` and :const:`ModelType.LLM` to the ``ModelClient``.
.. note ::
- This also means any ``ModelClient`` who wants to be compatible with `Generator` should take in ``model_kwargs`` and ``model_type`` as arguments.
+ This also means any ``ModelClient`` that wants to be compatible with `Generator` should take accept ``model_kwargs`` and ``model_type`` as arguments.
+
+
+
GeneratorOutput
^^^^^^^^^^^^^^^^^
-Different from all other components, we can not alway enforce LLM to output the right format.
-Some part of the `Generator` pipeline can fail.
+Unlike other components, we cannot always enforce the LLM to follow the output format. The `ModelClient` and the `output_processors` may fail.
+
.. note::
- Whenever there is an error happens, we do not raise the error and stop this pipeline.
+ Whenever an error occurs, we do not raise the error and force the program to stop.
Instead, `Generator` will always return an output record.
- We made this design choice as it can be really helpful to log various failed cases on your test examples without stopping the pipeline for further investigation and improvement.
+ We made this design choice because it can be really helpful to log various failed cases in your train/eval sets all together for further investigation and improvement.
+
+
+
+In particular, we created :class:`GeneratorOutput` to capture important information.
+
+- `data` (object) : Stores the final processed response after all three components in the pipeline, indicating `success`.
+- `error` (str): Contains the error message if any of the three components in the pipeline fail. When this is not `None`, it indicates `failure`.
+- `raw_response` (str): Raw string response for reference of any LLM predictions. Currently, it is a string that comes from the first response message. [This might change and be different in the future]
+- `metadata` (dict): Stores any additional information
+- `usage`: Reserved for tracking the usage of the LLM prediction.
-In particular, we created :class:`GeneratorOutput` (subclass of ``DataClass``) to capture important information.
+Whether to do further processing or terminate the pipeline whenever an error occurs is up to the user from here on.
-- `data` (object) : to store the final processed response after all three components in the pipeline. This means `success`.
-- `error` (str): error message if any of the three components in the pipeline fail. When this is not `None`, it means `failure`.
-- `raw_response` (str): raw string response for reference for any LLM predictions. For now it is a string, which comes from the first response message. [This might change and be different in the future]
-- `metadata` (dict): to store any additional information and `usage` reserved to track the usage of the LLM prediction.
-Whether to do further processing or terminate the pipeline whenever an error happens is up to the user from here on.
Generator In Action
---------------------------------------
-We will create a simple one-turn chatbot to demonstrate how to use the Generator in action.
+We will create a simple one-turn chatbot to demonstrate how to use the Generator.
Minimum Example
^^^^^^^^^^^^^^^^^
@@ -111,12 +126,12 @@ The structure of generator using ``print``:
Generator(
model_kwargs={'model': 'llama3-8b-8192'},
(prompt): Prompt(
- template: {% if task_desc_str or output_format_str or tools_str or examples_str or chat_history_str or context_str or steps_str %}
-
- {% endif %}
+ template:
{# task desc #}
{% if task_desc_str %}
{{task_desc_str}}
+ {% else %}
+ You are a helpful assistant.
{% endif %}
{# output format #}
{% if output_format_str %}
@@ -154,19 +169,17 @@ The structure of generator using ``print``:
{{steps_str}}
{% endif %}
- {% if task_desc_str or output_format_str or tools_str or examples_str or chat_history_str or context_str or steps_str %}
- {% endif %}
{% if input_str %}
{{input_str}}
{% endif %}
You:
- , prompt_variables: ['output_format_str', 'chat_history_str', 'task_desc_str', 'context_str', 'steps_str', 'input_str', 'tools_str', 'examples_str']
+ , prompt_variables: ['input_str', 'tools_str', 'context_str', 'steps_str', 'task_desc_str', 'chat_history_str', 'output_format_str', 'examples_str']
)
(model_client): GroqAPIClient()
- )
+ )
diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst
index c174f250..03440921 100644
--- a/docs/source/tutorials/index.rst
+++ b/docs/source/tutorials/index.rst
@@ -1,13 +1,323 @@
-.. _use_cases:
+.. _source-tutorials:
-Use Cases
+.. _developer_notes:
+
+
+Tutorials
=============================
-How different parts are used to build various LLM applications.
+.. *Why and How Each Part works*
+
+Learn the `why` and `how-to` (customize and integrate) behind each core part within the `LightRAG` library.
+These are our most important tutorials before you move ahead to build your use cases end to end.
+
+
+.. raw::
+
+ .. note::
+
+ You can read interchangably between :ref:`Use Cases `.
+
+
+
+.. figure:: /_static/images/LLM_arch.png
+ :alt: LLM application is no different from a mode training/eval workflow
+ :align: center
+ :width: 600px
+
+ LLM application is no different from a mode training/evaluation workflow
+
+ .. :height: 100px
+ .. :width: 200px
+
+
+The `LightRAG` library focuses on providing building blocks for developers to **build** and **optimize** the task pipeline.
+We have a clear :doc:`lightrag_design_philosophy`, which results in this :doc:`class_hierarchy`.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Introduction
+ :hidden:
+
+ lightrag_design_philosophy
+ class_hierarchy
+
+
+Introduction
+-------------------
+
+
+:ref:`Component` is to LLM task pipelines what `nn.Module` is to PyTorch models.
+An LLM task pipeline in LightRAG mainly consists of components, such as a `Prompt`, `ModelClient`, `Generator`, `Retriever`, `Agent`, or any other custom components.
+This pipeline can be `Sequential` or a Directed Acyclic Graph (DAG) of components.
+A `Prompt` will work with `DataClass` to ease data interaction with the LLM model.
+A `Retriever` will work with databases to retrieve context and overcome the hallucination and knowledge limitations of LLM, following the paradigm of Retrieval-Augmented Generation (RAG).
+An `Agent` will work with tools and an LLM planner for enhanced ability to reason, plan, and act on real-world tasks.
+
+
+Additionally, what shines in LightRAG is that all orchestrator components, like `Retriever`, `Embedder`, `Generator`, and `Agent`, are model-agnostic.
+You can easily make each component work with different models from different providers by switching out the `ModelClient` and its `model_kwargs`.
+
+
+We will introduce the libraries starting from the core base classes, then move to the RAG essentials, and finally to the agent essentials.
+With these building blocks, we will further introduce optimizing, where the optimizer uses building blocks such as Generator for auto-prompting and retriever for dynamic few-shot in-context learning (ICL).
+
+Building
+-------------------
+
+
+
+Base classes
+~~~~~~~~~~~~~~~~~~~~~~
+Code path: :ref:`lightrag.core `.
+
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Base Class
+ - Description
+ * - :doc:`component`
+ - The building block for task pipeline. It standardizes the interface of all components with `call`, `acall`, and `__call__` methods, handles state serialization, nested components, and parameters for optimization. Components can be easily chained together via ``Sequential``.
+ * - :doc:`base_data_class`
+ - The base class for data. It eases the data interaction with LLMs for both prompt formatting and output parsing.
+
+
+
+
+.. create side bar navigation
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Base Classes
+ :hidden:
+
+ component
+ base_data_class
+
+RAG Essentials
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+RAG components
+^^^^^^^^^^^^^^^^^^^
+
+
+Code path: :ref:`lightrag.core`. For abstract classes:
+
+- ``ModelClient``: the functional subclass is in :ref:`lightrag.components.model_client`.
+- ``Retriever``: the functional subclass is in :ref:`lightrag.components.retriever`.
+
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`prompt`
+ - Built on `jinja2`, it programmatically and flexibly formats prompts as input to the generator.
+ * - :doc:`model_client`
+ - The standard `protocol` to intergrate LLMs, Embedding models, ranking models, etc into respective `orchestrator` components, either via APIs or local to reach to `model agnostic`.
+ * - :doc:`generator`
+ - The `orchestrator` for LLM prediction. It streamlines three components: `ModelClient`, `Prompt`, and `output_processors` and works with optimizer for prompt optimization.
+ * - :doc:`output_parsers`
+ - The `interpreter` of the LLM output. The component that parses the output string to structured data.
+ * - :doc:`embedder`
+ - The component that orchestrates model client (Embedding models in particular) and output processors.
+ * - :doc:`retriever`
+ - The base class for all retrievers who in particular retrieve relevant documents from a given database to add **context** to the generator.
+
+
+Data Pipeline and Storage
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Data Processing: including transformer, pipeline, and storage. Code path: ``lightrag.components.data_process``, ``lightrag.core.db``, and ``lightrag.database``.
+Components work on a sequence of ``Document`` and return a sequence of ``Document``.
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`text_splitter`
+ - To split long text into smaller chunks to fit into the token limits of embedder and generator or to ensure more relevant context while being used in RAG.
+ * - :doc:`db`
+ - Understanding the **data modeling, processing, and storage** as a whole. We will build a chatbot with enhanced memory and memoy retrieval in this note (RAG).
+
+
+.. * - :doc:`data_pipeline`
+.. - The pipeline to process data, including text splitting, embedding, and retrieval.
+
+.. Let us put all of these components together to build a :doc:`rag` (Retrieval Augmented Generation), which requires data processing pipeline along with a task pipeline to run user queries.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: RAG Essentials
+ :hidden:
+
+ prompt
+ model_client
+ generator
+ output_parsers
+ embedder
+ retriever
+ text_splitter
+ db
+
+
+
+Agent Essentials
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Agent in ``components.agent`` is LLM great with reasoning, planning, and using tools to interact and accomplish tasks.
+
+.. list-table::
+ :widths: 30 70
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`tool_helper`
+ - Provide tools (function calls) to interact with the generator.
+ * - :doc:`agent`
+ - The ReactAgent.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Agent Essentials
+ :hidden:
+
+ tool_helper
+ agent
+
+.. Core functionals
+.. -------------------
+.. Code path: ``lightrag.core``
+
+.. :widths: 20 80
+.. :header-rows: 1
+
+.. * - Functional
+.. - Description
+.. * - :doc:`string_parser`
+.. - Parse the output string to structured data.
+.. * - :doc:`tool_helper`
+.. - Provide tools to interact with the generator.
+
+.. * - :doc:`memory`
+.. - Store the history of the conversation.
+
+
+
+
+
+
+
+
+Optimizing
+-------------------
+
+Evaluating
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`datasets`
+ - The datasets used in the evaluation.
+ * - :doc:`evaluation`
+ - The evaluation metrics and methods.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Evaluating
+ :hidden:
+
+
+ datasets
+
+ evaluation
+
+
+Training
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**Tutorials in this section are coming soon!**
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`parameter`
+ - The parameter class to optimize.
+ * - :doc:`optimizer`
+ - The optimizer to optimize the parameters.
+ * - :doc:`trainer`
+ - The trainer to train the model.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Training
+ :hidden:
+
+ parameter
+
+ optimizer
+ trainer
+
+
+Logging & Tracing
+------------------------------------
+Code path: :ref:`lightrag.utils ` and :ref:`lightrag.tracing `.
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`logging`
+ - LightRAG uses native ``logging`` module as the first line of debugging tooling. We made the effort to help you set it up easily.
+ * - :doc:`logging_tracing`
+ - We provide two tracing methods to help you develop and improve the Generator:
+ 1. Trace the history change(states) on prompt during your development process.
+ 2. Trace all failed LLM predictions in a unified file for further improvement.
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Logging & Tracing
+ :hidden:
+
+
+ logging
+ logging_tracing
+
+
+
+Configurations
+-------------------
+Code path: :ref:`lightrag.utils `.
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Part
+ - Description
+ * - :doc:`configs`
+ - The configurations for the components.
+
+
-**The documentation of this section is coming soon.**
+.. toctree::
+ :maxdepth: 1
+ :caption: Configurations
+ :hidden:
-.. :maxdepth: 2
-.. eval_a_rag
-.. introduction_to_basedataclass
+ configs
diff --git a/docs/source/developer_notes/lightrag_design_philosophy.rst b/docs/source/tutorials/lightrag_design_philosophy.rst
similarity index 99%
rename from docs/source/developer_notes/lightrag_design_philosophy.rst
rename to docs/source/tutorials/lightrag_design_philosophy.rst
index faee40f1..8120ebf6 100644
--- a/docs/source/developer_notes/lightrag_design_philosophy.rst
+++ b/docs/source/tutorials/lightrag_design_philosophy.rst
@@ -1,3 +1,5 @@
+.. _lightrag_design_philosophy:
+
Design Philosophy
====================================
diff --git a/docs/source/developer_notes/llm_intro.rst b/docs/source/tutorials/llm_intro.rst
similarity index 97%
rename from docs/source/developer_notes/llm_intro.rst
rename to docs/source/tutorials/llm_intro.rst
index 7612093b..13ae09a7 100644
--- a/docs/source/developer_notes/llm_intro.rst
+++ b/docs/source/tutorials/llm_intro.rst
@@ -1,3 +1,5 @@
+.. _llm_intro:
+
Introduction
====================================
@@ -13,7 +15,7 @@ Here is one example from OpenAI:
from openai import OpenAI
client = OpenAI()
-
+
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
@@ -43,7 +45,7 @@ Different API providers may have different input format, e.g. Anthropic's system
Why do we need chat completion instead of the previous text completion?
-----------------------------------------------------------------------
-There are generally three roles("system", "user", "assistant") in chat, and potentially more especially in multi-agent.
+There are generally three roles("system", "user", "assistant") in chat, and potentially more especially in multi-agent.
Behind the scene, when the API provider receives the messages, they will compose them into a single text using special tokens to denote different messages.
If we follow `Llama3 special tokens `_, the above anthropic example will be converted into text:
@@ -81,4 +83,4 @@ Resources
[2] `Anthropic text generation `_
-[3] `Meta Llama3 `_
\ No newline at end of file
+[3] `Meta Llama3 `_
diff --git a/docs/source/tutorials/logging.rst b/docs/source/tutorials/logging.rst
index e69de29b..1252bfd8 100644
--- a/docs/source/tutorials/logging.rst
+++ b/docs/source/tutorials/logging.rst
@@ -0,0 +1,197 @@
+Logging
+====================
+
+
+The Python logging module [1]_ is a powerful and flexible tool for debugging and tracing.
+LightRAG uses the native logging module as the *first line of defense*.
+
+Design
+--------------------
+Some libraries may use hooks [2]_ and callbacks [3]_ [4]_, or advanced web-based debugging tools [5]_ [6]_ [7]_.
+Hooks and callbacks are conceptually similar in that they both allow users to execute custom code at specific points during the execution of a program.
+Both provide mechanisms to inject additional behavior in response to certain events or conditions, without modifying the core logic.
+PyTorch defines, registers, and executes hooks mainly in its base classes like `nn.Module` and `Tensor`, without polluting the functional and user-facing APIs.
+
+At this point, our objectives are:
+
+1. Maximize debugging capabilities via the simple logging module to keep the source code clean.
+2. Additionally, as we can't always control the outputs of generators, we will provide customized logger and tracers(drop-in decorators) for them, for which we will explain in :doc:`logging_tracing`. This will not break the first objective.
+
+In the future, when we have more complex requirements from users, we will consider adding hooks/callbacks but we will do it in a way to keep the functional and user-facing APIs clean.
+
+How the library logs
+~~~~~~~~~~~~~~~~~~~~~~
+In each file, we simply set the logger with the following code:
+
+.. code-block:: python
+
+ import logging
+
+ log = logging.getLogger(__name__)
+
+We then use `log` and decide what level of logging we want to use in each function.
+Here is how :ref:`Generator ` logs.
+
+How users set up the logger
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We provide a simple function :func:`get_logger` to help users set up loggers with great default formatting and handlers.
+The simplest way to get up a logger and see the library logs is to call this function:
+
+.. code-block:: python
+
+ from lightrag.utils.logger import get_logger
+
+
+ root_logger = get_logger()
+
+Here is an example of the printed log message if users run the generator after setting up the logger:
+
+.. code-block::
+
+ 2024-07-05 18:49:39 - generator - INFO - [generator.py:249:call] - output: GeneratorOutput(data="Hello! I'm just a computer program, so I don't have feelings, but I'm here and ready to help you. How can I assist you today?", error=None, usage=None, raw_response="Hello! I'm just a computer program, so I don't have feelings, but I'm here and ready to help you. How can I assist you today?", metadata=None)
+
+
+printc function
+~~~~~~~~~~~~~~~~~~~~~~
+A neat tiny function :func:`printc` is provided to print colored text to the console.
+It has similar formatting to the logger.
+Here is an example of how to use it:
+
+.. code-block:: python
+
+ from lightrag.utils.logger import printc
+
+ printc("All logging examples are done. Feeling green!", color="green")
+
+The output will be:
+
+.. raw:: html
+
+
+ 2024-07-05 22:25:43 - [logging_config.py:98:<module>] - All logging examples are done. Feeling green!
+
+
+
+
+.. .. list-table:: Parameters of :func:`get_logger`
+.. :header-rows: 1
+.. :widths: 30 70
+
+.. * - **Argument**
+.. - **Description**
+.. * - ``name: Optional[str] = None``
+.. - Name of the logger. If None, the root logger is used.
+.. * - ``level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"``
+.. - Log level for the logger. Can be "DEBUG", "INFO", "WARNING", "ERROR", or "CRITICAL".
+.. * - ``save_dir: Optional[str] = None``
+.. - Directory where the log files will be saved. Defaults to "./logs".
+.. * - ``filename: Optional[str] = None``
+.. - Name of the log file. Defaults to "lib.log" for the root logger and "{name}.log" for named logger.
+.. * - ``enable_console: bool = True``
+.. - Whether to enable logging to console. Defaults to True.
+.. * - ``enable_file: bool = False``
+.. - Whether to enable logging to a file. Defaults to False.
+
+Use Logger in Projects
+-------------------------
+There are two distinct ways to set up the logging in your project:
+
+1. Have both the library loggind and your application logging in a single file. This is the simplest setup.
+2. Use both root and named logger to log library and application logs separately.
+
+Set up all logs in one file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Assume your source code is at `src/task.py`. You can log simply by:
+
+.. code-block:: python
+
+ import logging
+
+ log = logging.getLogger(__name__)
+
+ class Task:
+ def __init__(self):
+ log.info("This is a user program child logger")
+
+In the main file, you can config a single root logger to log both library and application logs:
+
+.. code-block:: python
+
+ import logging
+ from lightrag.utils.logger import get_logger
+
+ root_logger = get_logger(level="DEBUG", save_dir="./logs") # log to ./logs/lib.log
+
+ # run code from the library components such as generator
+ # ....
+
+ root_logger.info("This is the log in the main file")
+
+This way, all logs will be saved in `./logs/lib.log`.
+
+Separate library and application logs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In some cases, if users prefer to separate the library and application logs, they can use a named logger.
+
+In the user program, such as at `src/task.py`, you can set up a named logger and logs to `./logs/my_app.log`:
+
+.. code-block:: python
+
+ from lightrag.utils.logger import get_logger
+
+ app_logger = get_logger(name="my_app", level="DEBUG", save_dir="./logs") # log to ./logs/my_app.log
+
+ class Task:
+ def __init__(self):
+ app_logger.info("This is a user program child logger")
+
+The difference is that you have already attached handlers to the app_logger.
+In the main file, you do not need to set up a root logger to enable your application logs.
+However, you can still set up a root logger to log the library logs separately if needed, and create another named logger to continue logging in the main file.
+
+
+
+.. It works similarly if it is to be logged to console.
+.. Config 3 can be quite neat:
+
+.. - You can enable different levels of logging for the library and your application.
+.. - You can easily focus on debugging your own code without being distracted by the library logs and still have the option to see the library logs if needed.
+
+.. .. Create a named logger
+.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. .. code-block:: python
+
+.. from lightrag.utils.logger import get_logger
+
+.. app_logger = get_logger(name="my_app", level="DEBUG", save_dir="./logs") # log to ./logs/my_app.log
+.. # or
+.. logger = get_logger(name=__name__, level="DEBUG", save_dir="./logs", filename="my_app.log")
+
+.. app_logger.debug("This is a debug message")
+.. app_logger.info("This is an info message")
+.. app_logger.warning("This is a warning message")
+.. app_logger.error("This is an error message")
+.. app_logger.critical("This is a critical message")
+
+
+.. admonition:: References
+ :class: highlight
+
+ .. [1] Python logging module: https://docs.python.org/3/library/logging.html
+ .. [2] Hooks in PyTorch: https://pytorch.org/docs/stable/generated/torch.nn.modules.module.register_module_forward_hook.html
+ .. [3] Callbacks in Transformers: https://huggingface.co/docs/transformers/main/en/main_classes/callback
+ .. [4] Callbacks in PyTorch Lightning: https://pytorch-lightning.readthedocs.io/en/1.5.10/extensions/callbacks.html
+ .. [5] Weights & Biases: https://wandb.ai/site
+ .. [6] TensorBoard: https://www.tensorflow.org/tensorboard
+ .. [7] Arize Phoenix: https://docs.arize.com/phoenix
+
+
+
+.. admonition:: API References
+ :class: highlight
+
+ - :func:`utils.logger.get_logger`
+ - :func:`utils.logger.printc`
+ - :ref:`Generator`
diff --git a/docs/source/developer_notes/logging_tracing.rst b/docs/source/tutorials/logging_tracing.rst
similarity index 99%
rename from docs/source/developer_notes/logging_tracing.rst
rename to docs/source/tutorials/logging_tracing.rst
index 087bf980..06a2b59e 100644
--- a/docs/source/developer_notes/logging_tracing.rst
+++ b/docs/source/tutorials/logging_tracing.rst
@@ -1,3 +1,5 @@
+.. _logging_tracing:
+
Tracing
==================
diff --git a/docs/source/developer_notes/model_client.rst b/docs/source/tutorials/model_client.rst
similarity index 99%
rename from docs/source/developer_notes/model_client.rst
rename to docs/source/tutorials/model_client.rst
index 7bb83b34..15527667 100644
--- a/docs/source/developer_notes/model_client.rst
+++ b/docs/source/tutorials/model_client.rst
@@ -1,3 +1,5 @@
+.. _tutorials-model_client:
+
ModelClient
============
diff --git a/docs/source/developer_notes/optimizer.rst b/docs/source/tutorials/optimizer.rst
similarity index 83%
rename from docs/source/developer_notes/optimizer.rst
rename to docs/source/tutorials/optimizer.rst
index abc4c5a7..f3d2cf0b 100644
--- a/docs/source/developer_notes/optimizer.rst
+++ b/docs/source/tutorials/optimizer.rst
@@ -1,3 +1,5 @@
+.. _optimizer:
+
Optimizer
==========================================================
Coming soon!
diff --git a/docs/source/developer_notes/output_parsers.rst b/docs/source/tutorials/output_parsers.rst
similarity index 100%
rename from docs/source/developer_notes/output_parsers.rst
rename to docs/source/tutorials/output_parsers.rst
diff --git a/docs/source/developer_notes/parameter.rst b/docs/source/tutorials/parameter.rst
similarity index 73%
rename from docs/source/developer_notes/parameter.rst
rename to docs/source/tutorials/parameter.rst
index 2b4b9290..aed9b0a9 100644
--- a/docs/source/developer_notes/parameter.rst
+++ b/docs/source/tutorials/parameter.rst
@@ -1,3 +1,5 @@
+.. _parameter:
+
Parameter
====================
Coming soon!
diff --git a/docs/source/developer_notes/prompt.rst b/docs/source/tutorials/prompt.rst
similarity index 100%
rename from docs/source/developer_notes/prompt.rst
rename to docs/source/tutorials/prompt.rst
diff --git a/docs/source/tutorials/rag.rst b/docs/source/tutorials/rag.rst
new file mode 100644
index 00000000..e65c2c90
--- /dev/null
+++ b/docs/source/tutorials/rag.rst
@@ -0,0 +1,4 @@
+.. _rag:
+
+RAG application
+===================
diff --git a/docs/source/developer_notes/react_agent_xy.rst b/docs/source/tutorials/react_agent_xy.rst
similarity index 99%
rename from docs/source/developer_notes/react_agent_xy.rst
rename to docs/source/tutorials/react_agent_xy.rst
index c5440dca..c26a91c8 100644
--- a/docs/source/developer_notes/react_agent_xy.rst
+++ b/docs/source/tutorials/react_agent_xy.rst
@@ -1,3 +1,5 @@
+.. _react_agent_xy:
+
ReAct Agent
=================
diff --git a/docs/source/developer_notes/retriever.rst b/docs/source/tutorials/retriever.rst
similarity index 99%
rename from docs/source/developer_notes/retriever.rst
rename to docs/source/tutorials/retriever.rst
index b5e25048..05c40173 100644
--- a/docs/source/developer_notes/retriever.rst
+++ b/docs/source/tutorials/retriever.rst
@@ -1,3 +1,6 @@
+.. _tutorials-retriever:
+
+
Retriever
============
diff --git a/docs/source/developer_notes/retriever_xy.rst b/docs/source/tutorials/retriever_xy.rst
similarity index 99%
rename from docs/source/developer_notes/retriever_xy.rst
rename to docs/source/tutorials/retriever_xy.rst
index ff67c41b..e2fa332e 100644
--- a/docs/source/developer_notes/retriever_xy.rst
+++ b/docs/source/tutorials/retriever_xy.rst
@@ -1,3 +1,5 @@
+.. _retriever_xy:
+
Retriever
===================
diff --git a/docs/source/developer_notes/text_splitter.rst b/docs/source/tutorials/text_splitter.rst
similarity index 99%
rename from docs/source/developer_notes/text_splitter.rst
rename to docs/source/tutorials/text_splitter.rst
index 75cd177e..9b2c710a 100644
--- a/docs/source/developer_notes/text_splitter.rst
+++ b/docs/source/tutorials/text_splitter.rst
@@ -1,3 +1,6 @@
+.. _tutorials-text_splitter:
+
+
Text Splitter
-----------------
.. .. admonition:: Author
diff --git a/docs/source/developer_notes/tool_helper.rst b/docs/source/tutorials/tool_helper.rst
similarity index 99%
rename from docs/source/developer_notes/tool_helper.rst
rename to docs/source/tutorials/tool_helper.rst
index 08c1dd99..0416db2e 100644
--- a/docs/source/developer_notes/tool_helper.rst
+++ b/docs/source/tutorials/tool_helper.rst
@@ -1,3 +1,5 @@
+.. _tool_helper:
+
Function calls
===========================
.. .. admonition:: Author
diff --git a/docs/source/developer_notes/trainer.rst b/docs/source/tutorials/trainer.rst
similarity index 73%
rename from docs/source/developer_notes/trainer.rst
rename to docs/source/tutorials/trainer.rst
index 30e90187..a8b1d750 100644
--- a/docs/source/developer_notes/trainer.rst
+++ b/docs/source/tutorials/trainer.rst
@@ -1,3 +1,5 @@
+.. _trainer:
+
Trainer
================
Coming soon!
diff --git a/docs/source/tutorials/eval_a_rag.rst b/docs/source/use_cases/eval_a_rag.rst
similarity index 100%
rename from docs/source/tutorials/eval_a_rag.rst
rename to docs/source/use_cases/eval_a_rag.rst
diff --git a/docs/source/use_cases/index.rst b/docs/source/use_cases/index.rst
new file mode 100644
index 00000000..c174f250
--- /dev/null
+++ b/docs/source/use_cases/index.rst
@@ -0,0 +1,13 @@
+.. _use_cases:
+
+Use Cases
+=============================
+
+How different parts are used to build various LLM applications.
+
+**The documentation of this section is coming soon.**
+
+.. :maxdepth: 2
+
+.. eval_a_rag
+.. introduction_to_basedataclass
diff --git a/docs/source/tutorials/introduction_to_basedataclass.rst b/docs/source/use_cases/introduction_to_basedataclass.rst
similarity index 96%
rename from docs/source/tutorials/introduction_to_basedataclass.rst
rename to docs/source/use_cases/introduction_to_basedataclass.rst
index 27d782d3..ffca1fb5 100644
--- a/docs/source/tutorials/introduction_to_basedataclass.rst
+++ b/docs/source/use_cases/introduction_to_basedataclass.rst
@@ -3,20 +3,20 @@ Introduction to BaseDataClass
In this tutorial, we will discuss how to use ``BaseDataClass`` to streamline the data handling, serialization and description in LightRAG.
-`OpenAI's cookbook `_ emphasizes that LLM works better when operating **structured** and **consistent** data.
+`OpenAI's cookbook `_ emphasizes that LLM works better when operating **structured** and **consistent** data.
To solve this, ``LightRAG`` provides ``BaseDataClass`` for developers to manage data with control and flexibility, including:
* getting structured dataclass/instance metadata(`signature` or `schema`)
* formatting class instance to ``yaml``, ``dict`` or ``json``
* loading data from dictionary
-Like the role of ``Tensor`` in ``PyTorch``, ``BaseDataClass`` in ``LightRAG`` is the base class across all **dataclasses**.
+Like the role of ``Tensor`` in ``PyTorch``, ``BaseDataClass`` in ``LightRAG`` is the base class across all **dataclasses**.
``BaseDataClass`` offers to create `signature` or `schema` from both classeses and instances. It will also generate structured instances data. Developers can use ``BaseDataClass`` to easily define and describe dataclasses that handle the data input or output in LLM applications, keeping data consistent and structured.
In the following tutorial, we will investigate the functionality of ``BaseDataClass`` with examples.
**1. Create Signature and Schema**
-* **Signature:** Signature has simpler content and structure and hence more token efficient than schema. ``LightRAG`` supports ``json`` and ``yaml`` formating.
+* **Signature:** Signature has simpler content and structure and hence more token efficient than schema. ``LightRAG`` supports ``json`` and ``yaml`` formating.
* **Schema:** Schema is enssentially a dictionary containing more keys to show detailed information. Because of the detailed content, schema can mislead the model if not used properly.
@@ -55,14 +55,14 @@ Example to get signature and schema from a dataclass:
# yaml signature:
age: The age of the person (int) (required)
name: The name of the person (str) (required)
-
+
.. grid-item-card:: Schema Output
.. code-block:: python
-
+
{
- 'age': {'type': 'int', 'description': '', 'required': True},
+ 'age': {'type': 'int', 'description': '', 'required': True},
'name': {'type': 'str', 'description': '', 'required': True}
}
@@ -80,7 +80,7 @@ Example to get signiture and schema from an instance:
class MyOutputs(BaseDataClass):
age: int = field(metadata={"desc": "The age of the person", "prefix": "Age:"})
name: str = field(metadata={"desc": "The name of the person", "prefix": "Name:"})
-
+
my_instance = MyOutputs(age=25, name="John Doe")
# my_instance json signiture
print(my_instance.to_json_signature())
@@ -108,9 +108,9 @@ Example to get signiture and schema from an instance:
.. grid-item-card:: Schema Output
.. code-block:: python
-
+
{
- 'age': {'type': 'int', 'description': '', 'required': True},
+ 'age': {'type': 'int', 'description': '', 'required': True},
'name': {'type': 'str', 'description': '', 'required': True}
}
@@ -128,7 +128,7 @@ Example to get structured instance examples(``yaml`` or ``json``):
class MyOutputs(BaseDataClass):
age: int = field(metadata={"desc": "The age of the person", "prefix": "Age:"})
name: str = field(metadata={"desc": "The name of the person", "prefix": "Name:"})
-
+
my_instance = MyOutputs(age=25, name="John Doe")
# my_instance json signiture
print(my_instance.to_json())
@@ -146,16 +146,16 @@ Example to get structured instance examples(``yaml`` or ``json``):
"age": 25,
"name": "John Doe"
}
-
+
.. grid-item-card:: yaml Output
.. code-block:: python
-
+
age: 25
name: John Doe
-The examples demonstrate how ``BaseDataClass`` works for describing dataclasses and formatting instance to ``yaml`` and ``json``.
+The examples demonstrate how ``BaseDataClass`` works for describing dataclasses and formatting instance to ``yaml`` and ``json``.
Developers should select schema or signature depends on the use case.
**3. Load Data from Dictionary**
@@ -222,4 +222,4 @@ Example:
**5. Summary**
-In this tutorial, we've covered how to use ``BaseDataClass`` to create structured dataclass/instance `signature` and `schema`, format instance, load data from dictionary to the dataclass, and implement the ``BaseDataClass`` with other components.
\ No newline at end of file
+In this tutorial, we've covered how to use ``BaseDataClass`` to create structured dataclass/instance `signature` and `schema`, format instance, load data from dictionary to the dataclass, and implement the ``BaseDataClass`` with other components.
diff --git a/docs/source/use_cases/logging.rst b/docs/source/use_cases/logging.rst
new file mode 100644
index 00000000..e69de29b
diff --git a/lightrag/README.md b/lightrag/README.md
index 236a33dd..71b3294c 100644
--- a/lightrag/README.md
+++ b/lightrag/README.md
@@ -81,9 +81,9 @@ LightRAG full documentation available at [lightrag.sylph.ai](https://lightrag.sy
- [Introduction](https://lightrag.sylph.ai/)
- [Full installation guide](https://lightrag.sylph.ai/get_started/installation.html)
-- [Design philosophy](https://lightrag.sylph.ai/developer_notes/lightrag_design_philosophy.html): Design based on three principles: Simplicity over complexity, Quality over quantity, and Optimizing over building.
-- [Class hierarchy](https://lightrag.sylph.ai/developer_notes/class_hierarchy.html): We have no more than two levels of subclasses. The bare minimum abstraction provides developers with maximum customizability and simplicity.
-- [Tutorials](https://lightrag.sylph.ai/developer_notes/index.html): Learn the `why` and `how-to` (customize and integrate) behind each core part within the `LightRAG` library.
+- [Design philosophy](https://lightrag.sylph.ai/tutorials/lightrag_design_philosophy.html): Design based on three principles: Simplicity over complexity, Quality over quantity, and Optimizing over building.
+- [Class hierarchy](https://lightrag.sylph.ai/tutorials/class_hierarchy.html): We have no more than two levels of subclasses. The bare minimum abstraction provides developers with maximum customizability and simplicity.
+- [Tutorials](https://lightrag.sylph.ai/tutorials/index.html): Learn the `why` and `how-to` (customize and integrate) behind each core part within the `LightRAG` library.
- [API reference](https://lightrag.sylph.ai/apis/index.html)
diff --git a/lightrag/lightrag/components/agent/react.py b/lightrag/lightrag/components/agent/react.py
index 3a769e6c..c0c0672e 100644
--- a/lightrag/lightrag/components/agent/react.py
+++ b/lightrag/lightrag/components/agent/react.py
@@ -1,4 +1,4 @@
-"""Implementation of ReAct Agent."""
+"""Implementation and optimization of React agent."""
from typing import List, Union, Callable, Optional, Any, Dict
from copy import deepcopy
@@ -35,7 +35,6 @@
{% if tools %}
You available tools are:
-{# tools #}
{% for tool in tools %}
{{ loop.index }}.
{{tool}}
@@ -43,10 +42,12 @@
{% endfor %}
{% endif %}
-{# output format and examples #}
+{# output format and examples for output format #}
+
{{output_format_str}}
+
-{# Specifications TODO: preference between the usage of llm tool vs the other tool #}
+{# Task specification to teach the agent how to think using 'divide and conquer' strategy #}
- For simple queries: Directly call the ``finish`` action and provide the answer.
- For complex queries:
- Step 1: Read the user query and potentially divide it into subqueries. And get started with the first subquery.
@@ -84,6 +85,7 @@ class ReActAgent(Component):
- use_llm_as_fallback: a boolean to decide whether to use an additional LLM model as a fallback tool to answer the query.
- model_client: the model client to use to generate the response.
- model_kwargs: the model kwargs to use to generate the response.
+ - template: the template to use to generate the prompt. Default is DEFAULT_REACT_AGENT_SYSTEM_PROMPT.
For the generator, the default arguments are:
(1) default prompt: DEFAULT_REACT_AGENT_SYSTEM_PROMPT
@@ -94,6 +96,7 @@ class ReActAgent(Component):
Example:
.. code-block:: python
+
from core.openai_client import OpenAIClient
from components.agent.react import ReActAgent
from core.func_tool import FunctionTool
@@ -105,20 +108,17 @@ def add(a: int, b: int) -> int:
'''Add two numbers.'''
return a + b
agent = ReActAgent(
- tools=[multiply, add],
- model_client=OpenAIClient,
- model_kwargs={"model": "gpt-3.5-turbo"},
+ tools=[multiply, add],
+ model_client=OpenAIClient(),
+ model_kwargs={"model": "gpt-3.5-turbo"},
)
- Using examples:
+ # Using examples:
+
+ call_multiply = FunctionExpression.from_function(
+ thought="I want to multiply 3 and 4.",
+
- preset_prompt_kwargs = {"examples": examples}
- agent = ReActAgent(
- tools=[multiply, add],
- model_client=OpenAIClient,
- model_kwargs={"model": "gpt-3.5-turbo"},
- preset_prompt_kwargs=preset_prompt_kwargs,
- )
Reference:
[1] https://arxiv.org/abs/2210.03629, published in Mar, 2023.
@@ -131,14 +131,16 @@ def __init__(
tools: List[Union[Callable, AsyncCallable, FunctionTool]] = [],
max_steps: int = 10,
add_llm_as_fallback: bool = True,
+ # TODO: the examples are just for specifying the output format, not end to end input-output examples, need further optimization
examples: List[FunctionExpression] = [],
*,
# the following arguments are mainly for the planner
model_client: ModelClient,
model_kwargs: Dict = {},
+ template: Optional[str] = None, # allow users to customize the template
):
super().__init__()
- template = DEFAULT_REACT_AGENT_SYSTEM_PROMPT
+ template = template or DEFAULT_REACT_AGENT_SYSTEM_PROMPT
self.max_steps = max_steps
@@ -187,7 +189,6 @@ def _init_tools(
def llm_tool(input: str) -> str:
"""I answer any input query with llm's world knowledge. Use me as a fallback tool or when the query is simple."""
- # use the generator to answer the query
try:
output: GeneratorOutput = _additional_llm_tool(
prompt_kwargs={"input_str": input}
@@ -216,9 +217,7 @@ def reset(self):
self.step_history = []
def _execute_action(self, action_step: StepOutput) -> Optional[StepOutput]:
- """
- Parse the action string to a function call and execute it. Update the action_step with the result.
- """
+ """Parse the action string to a function call and execute it. Update the action_step with the result."""
action = action_step.action
try:
@@ -235,9 +234,7 @@ def _execute_action(self, action_step: StepOutput) -> Optional[StepOutput]:
return action_step
def _run_one_step(self, step: int, prompt_kwargs: Dict, model_kwargs: Dict) -> str:
- """
- Run one step of the agent. Plan and execute the action for the step.
- """
+ """Run one step of the agent. Plan and execute the action for the step."""
step_output: StepOutput = StepOutput(step=step)
prompt_kwargs["step_history"] = self.step_history
@@ -257,7 +254,6 @@ def _run_one_step(self, step: int, prompt_kwargs: Dict, model_kwargs: Dict) -> s
try:
fun_expr: FunctionExpression = response.data
step_output.action = fun_expr
- # print the func expr
log.debug(f"Step {step}: {fun_expr}")
# execute the action
@@ -283,7 +279,6 @@ def call(
) -> Any:
r"""prompt_kwargs: additional prompt kwargs to either replace or add to the preset prompt kwargs."""
prompt_kwargs = {**promt_kwargs, "input_str": input}
- # prompt_kwargs["input_str"] = input
printc(f"input_query: {input}", color="red")
for i in range(self.max_steps):
step = i + 1
diff --git a/lightrag/lightrag/core/base_data_class.py b/lightrag/lightrag/core/base_data_class.py
index c5d576ae..19585ada 100644
--- a/lightrag/lightrag/core/base_data_class.py
+++ b/lightrag/lightrag/core/base_data_class.py
@@ -107,7 +107,7 @@ class DataClass:
Describing:
- We defined :ref:`DataClassFormatType ` to categorize DataClass description formats
+ We defined :class:`DataClassFormatType` to categorize DataClass description formats
as input or output in LLM prompt.
diff --git a/lightrag/lightrag/core/generator.py b/lightrag/lightrag/core/generator.py
index 0e078ea3..d44ac6b8 100644
--- a/lightrag/lightrag/core/generator.py
+++ b/lightrag/lightrag/core/generator.py
@@ -139,16 +139,6 @@ def from_config(cls, config: Dict[str, Any]) -> "Generator":
assert "model_client" in config, "model_client is required in the config"
return super().from_config(config)
- # def _compose_lm_input_non_chat(self, **kwargs: Any) -> str:
- # """
- # This combines the default lm input using Prompt, and the passed input. history, steps, etc.
- # It builds the final chat input to the model.
-
- # As
- # """
- # prompt_text = self.prompt.call(**kwargs)
- # return prompt_text
-
def _compose_model_kwargs(self, **model_kwargs) -> Dict:
r"""
The model configuration exclude the input itself.
@@ -184,7 +174,6 @@ def _post_call(self, completion: Any) -> GeneratorOutputType:
# the output processors operate on the str, the raw_response field.
output: GeneratorOutputType = GeneratorOutput(raw_response=response)
- # TODO: this output processing patterns need to be more clear
response = deepcopy(response)
if self.output_processors:
try:
diff --git a/lightrag/lightrag/core/types.py b/lightrag/lightrag/core/types.py
index deac261b..c7d48f28 100644
--- a/lightrag/lightrag/core/types.py
+++ b/lightrag/lightrag/core/types.py
@@ -38,6 +38,7 @@
AnthropicAPIClient,
GroqAPIClient,
OpenAIClient,
+ GoogleGenAIClient,
)
@@ -51,6 +52,8 @@
# Data modeling for ModelClient
######################################################################################
class ModelType(Enum):
+ __doc__ = r"""The type of the model, including Embedder, LLM, Reranker.
+ It helps ModelClient identify the model type required to correctly call the model."""
EMBEDDER = auto()
LLM = auto()
RERANKER = auto() # ranking model
@@ -59,11 +62,30 @@ class ModelType(Enum):
@dataclass
class ModelClientType:
+ __doc__ = r"""A quick way to access all model clients in the ModelClient module.
+
+ From this:
+
+ .. code-block:: python
+
+ from lightrag.components.model_client import CohereAPIClient, TransformersClient, AnthropicAPIClient, GroqAPIClient, OpenAIClient
+
+ model_client = OpenAIClient()
+
+ To this:
+
+ .. code-block:: python
+
+ from lightrag.core.types import ModelClientType
+
+ model_client = ModelClientType.OPENAI()
+ """
COHERE = CohereAPIClient
TRANSFORMERS = TransformersClient
ANTHROPIC = AnthropicAPIClient
GROQ = GroqAPIClient
OPENAI = OpenAIClient
+ GOOGLE_GENAI = GoogleGenAIClient
# TODO: define standard required outputs
@@ -365,7 +387,6 @@ def add(a, b):
)
action: str = field(
default_factory=required_field,
- # metadata={"desc": "FuncName(, )"},
metadata={"desc": _action_desc},
)
@@ -389,6 +410,24 @@ def from_function(
1. Create a FunctionExpression object from a function call:
2. use :meth:`to_json` and :meth:`to_yaml` to get the schema in JSON or YAML format.
3. This will be used as an example in prompt showing LLM how to call the function.
+
+ Example:
+
+ .. code-block:: python
+
+ from lightrag.core.types import FunctionExpression
+
+ def add(a, b):
+ return a + b
+
+ # create an expression for the function call and using keyword arguments
+ fun_expr = FunctionExpression.from_function(
+ add, thought="Add two numbers", a=1, b=2
+ )
+ print(fun_expr)
+
+ # output
+ # FunctionExpression(thought='Add two numbers', action='add(a=1, b=2)')
"""
try:
action = generate_function_call_expression_from_callable(
@@ -400,9 +439,6 @@ def from_function(
return cls(action=action, thought=thought)
-# saves the output of a function tool.
-
-
@dataclass
class FunctionOutput(DataClass):
__doc__ = (
diff --git a/lightrag/lightrag/tracing/decorators.py b/lightrag/lightrag/tracing/decorators.py
index c360b3d7..ccb27d62 100644
--- a/lightrag/lightrag/tracing/decorators.py
+++ b/lightrag/lightrag/tracing/decorators.py
@@ -27,17 +27,24 @@ def trace_generator_states(
filename (str, Optional): The name of the trace file. If not provided, it will be "{class_name}_generator_trace.json".
Examples:
- >>> @trace_generator()
- >>> class TestGenerator:
- >>> def __init__(self):
- >>> preset_prompt_kwargs = {"input_str": "world"}
- >>> self.generator = Generator(
- >>> model_client=OpenAIClient(),
- >>> template=template,
- >>> preset_prompt_kwargs=preset_prompt_kwargs,
- >>> )
- >>> # now you will see log files in the ./traces/ with a filename like TestGenerator_generator_trace.json
- >>> # If you update the template or the preset_prompt_kwargs, it will be logged in the file.
+
+ .. code-block:: python
+
+ from lightrag.tracing import trace_generator_states
+
+ # Define a class and apply the decorator
+ @trace_generator_states()
+ class TestGenerator:
+ def __init__(self):
+ super().__init__()
+ prompt_kwargs = {"input_str": "world"}
+ self.generator = Generator(
+ model_client=OpenAIClient(),
+ prompt_kwargs=prompt_kwargs,
+ model_kwargs={"model": "gpt-3.5-turbo"},
+ )
+ # now you will see log files in the ./traces/ with a filename like TestGenerator_generator_trace.json
+ # If you update the prompt templates or the prompt_kwargs, it will be logged in the file.
"""
def decorator(cls):
@@ -112,21 +119,28 @@ def trace_generator_call(
error_only (bool): If True, only log the calls that have an error. Default is True.
Examples:
- >>> @trace_generator_call()
- >>> class TestGenerator:
- >>> def __init__(self):
- >>> preset_prompt_kwargs = {"input_str": "world"}
- >>> self.generator = Generator(
- >>> model_client=OpenAIClient(),
- >>> template=template,
- >>> preset_prompt_kwargs=preset_prompt_kwargs,
- >>> )
- >>> # now you will see ./traces/TestGenerator dir being created.
- >>> # If the generator call has an error, it will be logged in the error file generator_call.jsonl
+
+ .. code-block:: python
+
+ from lightrag.tracing import trace_generator_call
+ @trace_generator_call()
+ class TestGenerator:
+ def __init__(self):
+ super().__init__()
+ prompt_kwargs = {"input_str": "world"}
+ self.generator = Generator(
+ model_client=OpenAIClient(),
+ prompt_kwargs=prompt_kwargs,
+ model_kwargs={"model": "gpt-3.5-turbo"},
+ )
+ # now you will see log files in the ./traces/ with a filename like TestGenerator_generator_call.jsonl
+ # If the generator call has an error, it will be logged in the file.
+
If you want to decorate a component(such as LLMRetriever) from the library where you do not have access to the source code, you can do it like this:
.. code-block:: python
+
from lightrag.components.retriever import LLMRetriever
# Define a subclass and apply the decorator
From ecdff45c793962a8128dd8b3c41faa5917c6a631 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 18:36:22 -0700
Subject: [PATCH 5/8] complete generator editing
---
docs/source/tutorials/generator.rst | 67 ++++++++++++-----------
docs/source/tutorials/logging_tracing.rst | 4 +-
2 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/docs/source/tutorials/generator.rst b/docs/source/tutorials/generator.rst
index baef7675..60b6bdc9 100644
--- a/docs/source/tutorials/generator.rst
+++ b/docs/source/tutorials/generator.rst
@@ -184,9 +184,10 @@ The structure of generator using ``print``:
-**Show the final prompt**
+**Show the Final Prompt**
-`Generator` 's ``print_prompt`` method will simply relay the method from the `Prompt` component:
+
+The `Generator` 's ``print_prompt`` method will simply relay the method from the `Prompt` component:
.. code-block:: python
@@ -204,7 +205,7 @@ The output will be the formatted prompt:
-**Call the generator**
+**Call the Generator**
.. code-block:: python
@@ -219,11 +220,11 @@ The output will be the `GeneratorOutput` object:
GeneratorOutput(data='LLM stands for Large Language Model, a type of artificial intelligence that is trained on vast amounts of text data to generate human-like language outputs, such as conversations, text, or summaries.', error=None, usage=None, raw_response='LLM stands for Large Language Model, a type of artificial intelligence that is trained on vast amounts of text data to generate human-like language outputs, such as conversations, text, or summaries.', metadata=None)
-Use template
+Use Template
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this example, we will use a customized template to format the prompt.
-We intialized the prompt with one variable `task_desc_str` and it is further combined with the `input_str` in the prompt.
+We intialized the prompt with one variable `task_desc_str`, which is further combined with the `input_str` in the prompt.
.. code-block:: python
@@ -263,9 +264,10 @@ The final prompt is:
Use output_processors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-In this example, we will instruct LLM to output a JSON object to respond.
+In this example, we will instruct the LLM to output a JSON object in response.
We will use the `JsonParser` to parse the output back to a `dict` object.
+
.. code-block:: python
from lightrag.core import Generator
@@ -314,18 +316,20 @@ The final prompt is:
You:
-The output of the call is:
+The above printout is:
.. code-block::
{'explaination': 'LLM stands for Large Language Model, which are deep learning models trained on enormous amounts of text data.', 'example': 'An example of a LLM is GPT-3, which can generate human-like text based on the input provided.'}
-Switch model client
+Please refer to :doc:`output_parsers` for a more comprehensive guide on the `Parser` components.
+
+Switch the model_client
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Also, did you notice that we have already switched to use models from `OpenAI` in the above example?
-This is how easy to switch the model client in the Generator, making it a truly model-agnostic component.
+Also, did you notice that we have already switched to using models from `OpenAI` in the above example?
+This demonstrates how easy it is to switch the `model_client` in the Generator, making it a truly model-agnostic component.
We can even use :class:`ModelClientType` to switch the model client without handling multiple imports.
.. code-block:: python
@@ -337,22 +341,24 @@ We can even use :class:`ModelClientType` to switch t
model_kwargs={"model": "gpt-3.5-turbo"},
)
-Get errors in the output
-^^^^^^^^^^^^^^^^^^^^^^^^^
+Get Errors in GeneratorOutput
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We will use an incorrect API key to delibrately create an error.
+We will still get a response, but it will only contain empty ``data`` and an error message.
+Here is an example of an API key error with OpenAI:
-We will use a wrong API key to delibrately create an error.
-We will still get a response, but only with empty ``data`` and an error message.
-Here is the api key error with OpenAI:
.. code-block:: python
GeneratorOutput(data=None, error="Error code: 401 - {'error': {'message': 'Incorrect API key provided: ab. You can find your API key at https://platform.openai.com/account/api-keys.', 'type': 'invalid_request_error', 'param': None, 'code': 'invalid_api_key'}}", usage=None, raw_response=None, metadata=None)
-Create from configs
+Create from Configs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Same as all components, we can create the generator purely from configs.
+As with all components, we can create the generator purely from configs.
+
**Know it is a Generator**
@@ -383,12 +389,14 @@ In this case, we know we are creating a generator, we will use ``from_config`` m
print(output)
-**Purely from the configs**
+**Purely from the Configs**
This is even more general.
-This method fits to create any component from configs.
+This method can be used to create any component from configs.
We just need to follow the config structure: ``component_name`` and ``component_config`` for all arguments.
+
+
.. code-block:: python
from lightrag.utils.config import new_component
@@ -424,13 +432,13 @@ We imported ``Generator`` in this case to only show the type hinting.
.. note::
- Please refer the :doc:`configurations` for more details on how to create components from configs.
+ Please refer to the :doc:`configurations` for more details on how to create components from configs.
-Examples across the library
+Examples Across the Library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Beside of these examples, LLM is like water, even in our library, we have components that have adpated Generator to other various functionalities.
+Besides these examples, LLM is like water, even in our library, we have components that have adpated Generator to various other functionalities.
- :class:`LLMRetriever` is a retriever that uses Generator to call LLM to retrieve the most relevant documents.
- :class:`DefaultLLMJudge` is a judge that uses Generator to call LLM to evaluate the quality of the response.
@@ -438,22 +446,15 @@ Beside of these examples, LLM is like water, even in our library, we have compon
Tracing
---------------------------------------
-In particular, we provide two tracing methods to help you develop and improve the ``Generator``:
-1. Trace the history change (states) on prompt during your development process.
-
-Developers typically go through a long process of prompt optimization, and it is frustrating to lose track of the prompt changes when your current change actually makes the performance much worse.
-We created a :class:`GeneratorStateLogger` to handle the logging and saving into JSON files. To further simplify the developer's process, we provide a class decorator `trace_generator_states` where a single line of code can be added to any of your task components. It will automatically track any attributes of type `Generator`.
-
-2. Trace all failed LLM predictions for further improvement.
-Similarly, :class:`GeneratorCallLogger` is created to log generator call input arguments and output results.
-The `trace_generator_call` decorator is provided to offer a one-line setup to trace calls, which by default will log only failed predictions.
-.. note::
+In particular, we provide two tracing methods to help you develop and improve the ``Generator``:
- This note is getting rather long. Please go to the :doc:`tracing` for more details on how to use these tracing methods.
+1. Trace the history change (states) on prompt during your development process.
+2. Trace all failed LLM predictions for further improvement.
+As this note is getting rather long. Please refer to the :doc:`tracing` to learn about these two tracing methods.
Training [Experimental]
diff --git a/docs/source/tutorials/logging_tracing.rst b/docs/source/tutorials/logging_tracing.rst
index 06a2b59e..6eb1d890 100644
--- a/docs/source/tutorials/logging_tracing.rst
+++ b/docs/source/tutorials/logging_tracing.rst
@@ -3,8 +3,8 @@
Tracing
==================
-Tracing
-^^^^^^^^^^^
+
+
In particular, we provide two tracing methods to help you develop and improve the Generator:
1. Trace the history change(states) on prompt during your development process. Developers typically go through a long process of prompt optimization and it is frustrating
From 30045631f869877dbedf8a8042936ebf07cbb038 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 18:44:32 -0700
Subject: [PATCH 6/8] rename the developer_notes code directory to tutorials
---
docs/source/index.rst | 2 --
{developer_notes => tutorials}/.gitignore | 0
{developer_notes => tutorials}/__init__.py | 0
{developer_notes => tutorials}/agent.py | 0
{developer_notes => tutorials}/component.ipynb | 0
{developer_notes => tutorials}/database.ipynb | 0
{developer_notes => tutorials}/dataclass.ipynb | 0
{developer_notes => tutorials}/default_config.json | 0
{developer_notes => tutorials}/embedder.ipynb | 0
{developer_notes => tutorials}/generator.ipynb | 0
{developer_notes => tutorials}/generator_note.py | 0
{developer_notes => tutorials}/logging_config.py | 0
{developer_notes => tutorials}/model_client.ipynb | 0
{developer_notes => tutorials}/parser_note.py | 0
.../paul_graham/paul_graham_essay.txt | 0
{developer_notes => tutorials}/postgres.sql | 0
{developer_notes => tutorials}/prompt_note.py | 0
{developer_notes => tutorials}/rag.ipynb | 0
{developer_notes => tutorials}/react_note.py | 0
{developer_notes => tutorials}/retriever.ipynb | 8 ++++----
{developer_notes => tutorials}/tools.ipynb | 0
{developer_notes => tutorials}/tools.py | 0
22 files changed, 4 insertions(+), 6 deletions(-)
rename {developer_notes => tutorials}/.gitignore (100%)
rename {developer_notes => tutorials}/__init__.py (100%)
rename {developer_notes => tutorials}/agent.py (100%)
rename {developer_notes => tutorials}/component.ipynb (100%)
rename {developer_notes => tutorials}/database.ipynb (100%)
rename {developer_notes => tutorials}/dataclass.ipynb (100%)
rename {developer_notes => tutorials}/default_config.json (100%)
rename {developer_notes => tutorials}/embedder.ipynb (100%)
rename {developer_notes => tutorials}/generator.ipynb (100%)
rename {developer_notes => tutorials}/generator_note.py (100%)
rename {developer_notes => tutorials}/logging_config.py (100%)
rename {developer_notes => tutorials}/model_client.ipynb (100%)
rename {developer_notes => tutorials}/parser_note.py (100%)
rename {developer_notes => tutorials}/paul_graham/paul_graham_essay.txt (100%)
rename {developer_notes => tutorials}/postgres.sql (100%)
rename {developer_notes => tutorials}/prompt_note.py (100%)
rename {developer_notes => tutorials}/rag.ipynb (100%)
rename {developer_notes => tutorials}/react_note.py (100%)
rename {developer_notes => tutorials}/retriever.ipynb (99%)
rename {developer_notes => tutorials}/tools.ipynb (100%)
rename {developer_notes => tutorials}/tools.py (100%)
diff --git a/docs/source/index.rst b/docs/source/index.rst
index c138e8c5..8e113932 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -116,8 +116,6 @@ We provide developers with fundamental building blocks of *100% clarity and simp
.. - We use 10X less code than other libraries to achieve 10X more robustness and flexibility.
-.. - `Class Hierarchy Visualization `_
-.. We support them with require **Maximum Flexibility and Customizability**:
.. Each developer has unique data needs to build their own models/components, experiment with In-context Learning (ICL) or model finetuning, and deploy the LLM applications to production. This means the library must provide fundamental lower-level building blocks and strive for clarity and simplicity:
diff --git a/developer_notes/.gitignore b/tutorials/.gitignore
similarity index 100%
rename from developer_notes/.gitignore
rename to tutorials/.gitignore
diff --git a/developer_notes/__init__.py b/tutorials/__init__.py
similarity index 100%
rename from developer_notes/__init__.py
rename to tutorials/__init__.py
diff --git a/developer_notes/agent.py b/tutorials/agent.py
similarity index 100%
rename from developer_notes/agent.py
rename to tutorials/agent.py
diff --git a/developer_notes/component.ipynb b/tutorials/component.ipynb
similarity index 100%
rename from developer_notes/component.ipynb
rename to tutorials/component.ipynb
diff --git a/developer_notes/database.ipynb b/tutorials/database.ipynb
similarity index 100%
rename from developer_notes/database.ipynb
rename to tutorials/database.ipynb
diff --git a/developer_notes/dataclass.ipynb b/tutorials/dataclass.ipynb
similarity index 100%
rename from developer_notes/dataclass.ipynb
rename to tutorials/dataclass.ipynb
diff --git a/developer_notes/default_config.json b/tutorials/default_config.json
similarity index 100%
rename from developer_notes/default_config.json
rename to tutorials/default_config.json
diff --git a/developer_notes/embedder.ipynb b/tutorials/embedder.ipynb
similarity index 100%
rename from developer_notes/embedder.ipynb
rename to tutorials/embedder.ipynb
diff --git a/developer_notes/generator.ipynb b/tutorials/generator.ipynb
similarity index 100%
rename from developer_notes/generator.ipynb
rename to tutorials/generator.ipynb
diff --git a/developer_notes/generator_note.py b/tutorials/generator_note.py
similarity index 100%
rename from developer_notes/generator_note.py
rename to tutorials/generator_note.py
diff --git a/developer_notes/logging_config.py b/tutorials/logging_config.py
similarity index 100%
rename from developer_notes/logging_config.py
rename to tutorials/logging_config.py
diff --git a/developer_notes/model_client.ipynb b/tutorials/model_client.ipynb
similarity index 100%
rename from developer_notes/model_client.ipynb
rename to tutorials/model_client.ipynb
diff --git a/developer_notes/parser_note.py b/tutorials/parser_note.py
similarity index 100%
rename from developer_notes/parser_note.py
rename to tutorials/parser_note.py
diff --git a/developer_notes/paul_graham/paul_graham_essay.txt b/tutorials/paul_graham/paul_graham_essay.txt
similarity index 100%
rename from developer_notes/paul_graham/paul_graham_essay.txt
rename to tutorials/paul_graham/paul_graham_essay.txt
diff --git a/developer_notes/postgres.sql b/tutorials/postgres.sql
similarity index 100%
rename from developer_notes/postgres.sql
rename to tutorials/postgres.sql
diff --git a/developer_notes/prompt_note.py b/tutorials/prompt_note.py
similarity index 100%
rename from developer_notes/prompt_note.py
rename to tutorials/prompt_note.py
diff --git a/developer_notes/rag.ipynb b/tutorials/rag.ipynb
similarity index 100%
rename from developer_notes/rag.ipynb
rename to tutorials/rag.ipynb
diff --git a/developer_notes/react_note.py b/tutorials/react_note.py
similarity index 100%
rename from developer_notes/react_note.py
rename to tutorials/react_note.py
diff --git a/developer_notes/retriever.ipynb b/tutorials/retriever.ipynb
similarity index 99%
rename from developer_notes/retriever.ipynb
rename to tutorials/retriever.ipynb
index f0b49aac..1f93503b 100644
--- a/developer_notes/retriever.ipynb
+++ b/tutorials/retriever.ipynb
@@ -1312,7 +1312,7 @@
"\n",
"# 1. set up the tracing for failed call as the retriever has generator attribute\n",
"\n",
- "@trace_generator_call(save_dir=\"developer_notes/traces\")\n",
+ "@trace_generator_call(save_dir=\"tutorials/traces\")\n",
"class LoggedLLMRetriever(LLMRetriever):\n",
" pass\n",
"top_k = 2\n",
@@ -2175,7 +2175,7 @@
"outputs": [],
"source": [
"# save the db states, including the original documents with len 1, and transformed documents\n",
- "db.save_state(\"developer_notes/db_states.pkl\")"
+ "db.save_state(\"tutorials/db_states.pkl\")"
]
},
{
@@ -2325,7 +2325,7 @@
"source": [
"# construct the db\n",
"\n",
- "restored_db = LocalDB.load_state(\"developer_notes/db_states.pkl\")\n",
+ "restored_db = LocalDB.load_state(\"tutorials/db_states.pkl\")\n",
"restored_db"
]
},
@@ -2626,7 +2626,7 @@
"source": [
"# save the index\n",
"\n",
- "path = \"developer_notes/bm25_index.json\"\n",
+ "path = \"tutorials/bm25_index.json\"\n",
"retriever.save_to_file(path)"
]
},
diff --git a/developer_notes/tools.ipynb b/tutorials/tools.ipynb
similarity index 100%
rename from developer_notes/tools.ipynb
rename to tutorials/tools.ipynb
diff --git a/developer_notes/tools.py b/tutorials/tools.py
similarity index 100%
rename from developer_notes/tools.py
rename to tutorials/tools.py
From 700f0941dc8216491c8a6d98427b2ecc6ccbe340 Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 19:16:55 -0700
Subject: [PATCH 7/8] edit the design philosophy and complete all references
for retriver
---
.../tutorials/lightrag_design_philosophy.rst | 13 +-
docs/source/tutorials/retriever.rst | 34 +-
poetry.lock | 437 +++++++++---------
pyproject.toml | 4 +-
4 files changed, 242 insertions(+), 246 deletions(-)
diff --git a/docs/source/tutorials/lightrag_design_philosophy.rst b/docs/source/tutorials/lightrag_design_philosophy.rst
index 8120ebf6..83bb3272 100644
--- a/docs/source/tutorials/lightrag_design_philosophy.rst
+++ b/docs/source/tutorials/lightrag_design_philosophy.rst
@@ -21,7 +21,7 @@ Principle 2: Quality over Quantity
The Quality of core building blocks over the Quantity of integrations.
-We aim to provide developers with well-designed core building blocks that are **easy** to understand, **transparent** to debug, and **flexible** enough to customize.
+We aim to provide developers with well-designed core building blocks that are *easy* to understand, *transparent* to debug, and *flexible* enough to customize.
This goes for the prompt, the model client, the retriever, the optimizer, and the trainer.
@@ -32,15 +32,8 @@ Principle 3: Optimizing over Building
We help users build the task pipeline, but we want to help with optimizing even more so.
-
-We will design our building blocks with `optimization` in mind.
-This means beyond giving developers transparency and control, providing them with great `logging`, `observability`, `configurability`, `optimizers`, and `trainers`
-to ease the existing frustrations of optimizing the task pipeline.
-
-
-
-
-
+We design our building blocks with `optimization` in mind.
+This means we go beyond just providing developers with transparency and control; we also offer excellent `logging`, `observability`, `configurability`, `optimizers`, and `trainers` to ease the existing frustrations of optimizing the task pipeline.
Our understanding of LLM workflow
diff --git a/docs/source/tutorials/retriever.rst b/docs/source/tutorials/retriever.rst
index 05c40173..1b131463 100644
--- a/docs/source/tutorials/retriever.rst
+++ b/docs/source/tutorials/retriever.rst
@@ -9,14 +9,14 @@ Retriever
.. `Li Yin `_
-Context
-------------------
+.. Context
+.. ------------------
-**Why Retriever for LLM?**
+.. **Why Retriever for LLM?**
LLMs halluciate and also has knowledge cut-off. External and relevant context is needed to increase the factuality, relevancy, and freshness on the LLM answers.
-Due to LLM's context window limit(can only take so much tokens each time), the ``lost-in-the-middle`` problem[6], and the high cost on speed and resources using large context,
-it is practical to use a retriever to retrieve the most relevant information to get the best performance. Retrieval Augemented Generation (RAG)[7] applications become one of main applications in LLMs.
+Due to LLM's context window limit(can only take so much tokens each time), the ``lost-in-the-middle`` problem [6]_, and the high cost on speed and resources using large context,
+it is practical to use a retriever to retrieve the most relevant information to get the best performance. Retrieval Augemented Generation (RAG) [7]_ applications become one of main applications in LLMs.
.. It is easy to build a demo, but hard to excel due to the many different parts in the pipeline that made it difficult to evaluate and to optimize.
@@ -580,7 +580,7 @@ The response is:
PostgresRetriever
^^^^^^^^^^^^^^^^^^^^^^^^
-
+Coming soon.
Use Score Threshold instead of top_k
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -602,17 +602,17 @@ Additionally, ``LocalDB`` help us keep track of our initial documents and its tr
.. admonition:: References
:class: highlight
- 1. Full-text search on PostgreSQL: https://www.postgresql.org/docs/current/textsearch.html
- 2. BM25: https://en.wikipedia.org/wiki/Okapi_BM25
- 3. Representative learning models: https://arxiv.org/abs/2104.08663 [Find the right reference]
- 4. Reranking models: https://arxiv.org/abs/2104.08663 [Find the right reference]
- 5. FAISS: https://github.com/facebookresearch/faiss
- 6. Lost-in-the-middle: https://arxiv.org/abs/2104.08663 [Find the right reference]
- 7. RAG: https://arxiv.org/abs/2104.08663 [Find the first paper on RAG]
- 8. Use LLM as Reranker along with logprobs: https://cookbook.openai.com/examples/search_reranking_with_cross-encoders/
- 9. Rank_bm25: https://github.com/dorianbrown/rank_bm25
- 10. https://huggingface.co/BAAI/bge-reranker-base
- 11. Cohere reranker: https://docs.cohere.com/reference/rerank
+ .. [1] Full-text search on PostgreSQL: https://www.postgresql.org/docs/current/textsearch.html
+ .. [2] BM25: https://en.wikipedia.org/wiki/Okapi_BM25
+ .. [3] Representative learning models: https://arxiv.org/abs/2310.07554
+ .. [4] Reranking models: https://github.com/FlagOpen/FlagEmbedding/tree/master/FlagEmbedding/llm_reranker
+ .. [5] FAISS: https://github.com/facebookresearch/faiss
+ .. [6] Lost-in-the-middle: https://arxiv.org/abs/2307.03172
+ .. [7] Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(RAG): https://arxiv.org/abs/2005.11401
+ .. [8] Use LLM as Reranker along with logprobs: https://cookbook.openai.com/examples/search_reranking_with_cross-encoders/
+ .. [9] Rank_bm25: https://github.com/dorianbrown/rank_bm25
+ .. [10] https://huggingface.co/BAAI/bge-reranker-base
+ .. [11] Cohere reranker: https://docs.cohere.com/reference/rerank
.. admonition:: API References
diff --git a/poetry.lock b/poetry.lock
index 33f71658..5b79f07e 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -286,17 +286,17 @@ css = ["tinycss2 (>=1.1.0,<1.3)"]
[[package]]
name = "boto3"
-version = "1.34.140"
+version = "1.34.143"
description = "The AWS SDK for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "boto3-1.34.140-py3-none-any.whl", hash = "sha256:23ca8d8f7a30c3bbd989808056b5fc5d68ff5121c02c722c6167b6b1bb7f8726"},
- {file = "boto3-1.34.140.tar.gz", hash = "sha256:578bbd5e356005719b6b610d03edff7ea1b0824d078afe62d3fb8bea72f83a87"},
+ {file = "boto3-1.34.143-py3-none-any.whl", hash = "sha256:0d16832f23e6bd3ae94e35ea8e625529850bfad9baccd426de96ad8f445d8e03"},
+ {file = "boto3-1.34.143.tar.gz", hash = "sha256:b590ce80c65149194def43ebf0ea1cf0533945502507837389a8d22e3ecbcf05"},
]
[package.dependencies]
-botocore = ">=1.34.140,<1.35.0"
+botocore = ">=1.34.143,<1.35.0"
jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.10.0,<0.11.0"
@@ -305,13 +305,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]]
name = "botocore"
-version = "1.34.140"
+version = "1.34.143"
description = "Low-level, data-driven core of boto 3."
optional = false
python-versions = ">=3.8"
files = [
- {file = "botocore-1.34.140-py3-none-any.whl", hash = "sha256:43940d3a67d946ba3301631ba4078476a75f1015d4fb0fb0272d0b754b2cf9de"},
- {file = "botocore-1.34.140.tar.gz", hash = "sha256:86302b2226c743b9eec7915a4c6cfaffd338ae03989cd9ee181078ef39d1ab39"},
+ {file = "botocore-1.34.143-py3-none-any.whl", hash = "sha256:094aea179e8aaa1bc957ad49cc27d93b189dd3a1f3075d8b0ca7c445a2a88430"},
+ {file = "botocore-1.34.143.tar.gz", hash = "sha256:059f032ec05733a836e04e869c5a15534420102f93116f3bc9a5b759b0651caf"},
]
[package.dependencies]
@@ -810,42 +810,42 @@ packaging = "*"
[[package]]
name = "fastavro"
-version = "1.9.4"
+version = "1.9.5"
description = "Fast read/write of AVRO files"
optional = false
python-versions = ">=3.8"
files = [
- {file = "fastavro-1.9.4-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:60cb38f07462a7fb4e4440ed0de67d3d400ae6b3d780f81327bebde9aa55faef"},
- {file = "fastavro-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:063d01d197fc929c20adc09ca9f0ca86d33ac25ee0963ce0b438244eee8315ae"},
- {file = "fastavro-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a9053fcfbc895f2a16a4303af22077e3a8fdcf1cd5d6ed47ff2ef22cbba2f0"},
- {file = "fastavro-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:02bf1276b7326397314adf41b34a4890f6ffa59cf7e0eb20b9e4ab0a143a1598"},
- {file = "fastavro-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:56bed9eca435389a8861e6e2d631ec7f8f5dda5b23f93517ac710665bd34ca29"},
- {file = "fastavro-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:0cd2099c8c672b853e0b20c13e9b62a69d3fbf67ee7c59c7271ba5df1680310d"},
- {file = "fastavro-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:af8c6d8c43a02b5569c093fc5467469541ac408c79c36a5b0900d3dd0b3ba838"},
- {file = "fastavro-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a138710bd61580324d23bc5e3df01f0b82aee0a76404d5dddae73d9e4c723f"},
- {file = "fastavro-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:903d97418120ca6b6a7f38a731166c1ccc2c4344ee5e0470d09eb1dc3687540a"},
- {file = "fastavro-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c443eeb99899d062dbf78c525e4614dd77e041a7688fa2710c224f4033f193ae"},
- {file = "fastavro-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ac26ab0774d1b2b7af6d8f4300ad20bbc4b5469e658a02931ad13ce23635152f"},
- {file = "fastavro-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:cf7247874c22be856ba7d1f46a0f6e0379a6025f1a48a7da640444cbac6f570b"},
- {file = "fastavro-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:68912f2020e1b3d70557260b27dd85fb49a4fc6bfab18d384926127452c1da4c"},
- {file = "fastavro-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6925ce137cdd78e109abdb0bc33aad55de6c9f2d2d3036b65453128f2f5f5b92"},
- {file = "fastavro-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b928cd294e36e35516d0deb9e104b45be922ba06940794260a4e5dbed6c192a"},
- {file = "fastavro-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:90c9838bc4c991ffff5dd9d88a0cc0030f938b3fdf038cdf6babde144b920246"},
- {file = "fastavro-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:eca6e54da571b06a3c5a72dbb7212073f56c92a6fbfbf847b91c347510f8a426"},
- {file = "fastavro-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a4b02839ac261100cefca2e2ad04cdfedc556cb66b5ec735e0db428e74b399de"},
- {file = "fastavro-1.9.4-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:4451ee9a305a73313a1558d471299f3130e4ecc10a88bf5742aa03fb37e042e6"},
- {file = "fastavro-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8524fccfb379565568c045d29b2ebf71e1f2c0dd484aeda9fe784ef5febe1a8"},
- {file = "fastavro-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33d0a00a6e09baa20f6f038d7a2ddcb7eef0e7a9980e947a018300cb047091b8"},
- {file = "fastavro-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23d7e5b29c9bf6f26e8be754b2c8b919838e506f78ef724de7d22881696712fc"},
- {file = "fastavro-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2e6ab3ee53944326460edf1125b2ad5be2fadd80f7211b13c45fa0c503b4cf8d"},
- {file = "fastavro-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:64d335ec2004204c501f8697c385d0a8f6b521ac82d5b30696f789ff5bc85f3c"},
- {file = "fastavro-1.9.4-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:7e05f44c493e89e73833bd3ff3790538726906d2856f59adc8103539f4a1b232"},
- {file = "fastavro-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:253c63993250bff4ee7b11fb46cf3a4622180a783bedc82a24c6fdcd1b10ca2a"},
- {file = "fastavro-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24d6942eb1db14640c2581e0ecd1bbe0afc8a83731fcd3064ae7f429d7880cb7"},
- {file = "fastavro-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d47bb66be6091cd48cfe026adcad11c8b11d7d815a2949a1e4ccf03df981ca65"},
- {file = "fastavro-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c293897f12f910e58a1024f9c77f565aa8e23b36aafda6ad8e7041accc57a57f"},
- {file = "fastavro-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:f05d2afcb10a92e2a9e580a3891f090589b3e567fdc5641f8a46a0b084f120c3"},
- {file = "fastavro-1.9.4.tar.gz", hash = "sha256:56b8363e360a1256c94562393dc7f8611f3baf2b3159f64fb2b9c6b87b14e876"},
+ {file = "fastavro-1.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:61253148e95dd2b6457247b441b7555074a55de17aef85f5165bfd5facf600fc"},
+ {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b604935d671ad47d888efc92a106f98e9440874108b444ac10e28d643109c937"},
+ {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0adbf4956fd53bd74c41e7855bb45ccce953e0eb0e44f5836d8d54ad843f9944"},
+ {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:53d838e31457db8bf44460c244543f75ed307935d5fc1d93bc631cc7caef2082"},
+ {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:07b6288e8681eede16ff077632c47395d4925c2f51545cd7a60f194454db2211"},
+ {file = "fastavro-1.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:ef08cf247fdfd61286ac0c41854f7194f2ad05088066a756423d7299b688d975"},
+ {file = "fastavro-1.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c52d7bb69f617c90935a3e56feb2c34d4276819a5c477c466c6c08c224a10409"},
+ {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e05969956003df8fa4491614bc62fe40cec59e94d06e8aaa8d8256ee3aab82"},
+ {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06e6df8527493a9f0d9a8778df82bab8b1aa6d80d1b004e5aec0a31dc4dc501c"},
+ {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:27820da3b17bc01cebb6d1687c9d7254b16d149ef458871aaa207ed8950f3ae6"},
+ {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:195a5b8e33eb89a1a9b63fa9dce7a77d41b3b0cd785bac6044df619f120361a2"},
+ {file = "fastavro-1.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:be612c109efb727bfd36d4d7ed28eb8e0506617b7dbe746463ebbf81e85eaa6b"},
+ {file = "fastavro-1.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b133456c8975ec7d2a99e16a7e68e896e45c821b852675eac4ee25364b999c14"},
+ {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf586373c3d1748cac849395aad70c198ee39295f92e7c22c75757b5c0300fbe"},
+ {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:724ef192bc9c55d5b4c7df007f56a46a21809463499856349d4580a55e2b914c"},
+ {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bfd11fe355a8f9c0416803afac298960eb4c603a23b1c74ff9c1d3e673ea7185"},
+ {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9827d1654d7bcb118ef5efd3e5b2c9ab2a48d44dac5e8c6a2327bc3ac3caa828"},
+ {file = "fastavro-1.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:d84b69dca296667e6137ae7c9a96d060123adbc0c00532cc47012b64d38b47e9"},
+ {file = "fastavro-1.9.5-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:fb744e9de40fb1dc75354098c8db7da7636cba50a40f7bef3b3fb20f8d189d88"},
+ {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:240df8bacd13ff5487f2465604c007d686a566df5cbc01d0550684eaf8ff014a"},
+ {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3bb35c25bbc3904e1c02333bc1ae0173e0a44aa37a8e95d07e681601246e1f1"},
+ {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b47a54a9700de3eabefd36dabfb237808acae47bc873cada6be6990ef6b165aa"},
+ {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:48c7b5e6d2f3bf7917af301c275b05c5be3dd40bb04e80979c9e7a2ab31a00d1"},
+ {file = "fastavro-1.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:05d13f98d4e325be40387e27da9bd60239968862fe12769258225c62ec906f04"},
+ {file = "fastavro-1.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b47948eb196263f6111bf34e1cd08d55529d4ed46eb50c1bc8c7c30a8d18868"},
+ {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85b7a66ad521298ad9373dfe1897a6ccfc38feab54a47b97922e213ae5ad8870"},
+ {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44cb154f863ad80e41aea72a709b12e1533b8728c89b9b1348af91a6154ab2f5"},
+ {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7f2b1fe21231fd01f1a2a90e714ae267fe633cd7ce930c0aea33d1c9f4901"},
+ {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88fbbe16c61d90a89d78baeb5a34dc1c63a27b115adccdbd6b1fb6f787deacf2"},
+ {file = "fastavro-1.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:753f5eedeb5ca86004e23a9ce9b41c5f25eb64a876f95edcc33558090a7f3e4b"},
+ {file = "fastavro-1.9.5.tar.gz", hash = "sha256:6419ebf45f88132a9945c51fe555d4f10bb97c236288ed01894f957c6f914553"},
]
[package.extras]
@@ -1043,13 +1043,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
-version = "2.136.0"
+version = "2.137.0"
description = "Google API Client Library for Python"
optional = false
python-versions = ">=3.7"
files = [
- {file = "google-api-python-client-2.136.0.tar.gz", hash = "sha256:161c722c8864e7ed39393e2b7eea76ef4e1c933a6a59f9d7c70409b6635f225d"},
- {file = "google_api_python_client-2.136.0-py2.py3-none-any.whl", hash = "sha256:5a554c8b5edf0a609b905d89d7ced82e8f6ac31da1e4d8d5684ef63dbc0e49f5"},
+ {file = "google_api_python_client-2.137.0-py2.py3-none-any.whl", hash = "sha256:a8b5c5724885e5be9f5368739aa0ccf416627da4ebd914b410a090c18f84d692"},
+ {file = "google_api_python_client-2.137.0.tar.gz", hash = "sha256:e739cb74aac8258b1886cb853b0722d47c81fe07ad649d7f2206f06530513c04"},
]
[package.dependencies]
@@ -1061,13 +1061,13 @@ uritemplate = ">=3.0.1,<5"
[[package]]
name = "google-auth"
-version = "2.31.0"
+version = "2.32.0"
description = "Google Authentication Library"
optional = false
python-versions = ">=3.7"
files = [
- {file = "google-auth-2.31.0.tar.gz", hash = "sha256:87805c36970047247c8afe614d4e3af8eceafc1ebba0c679fe75ddd1d575e871"},
- {file = "google_auth-2.31.0-py2.py3-none-any.whl", hash = "sha256:042c4702efa9f7d3c48d3a69341c209381b125faa6dbf3ebe56bc7e40ae05c23"},
+ {file = "google_auth-2.32.0-py2.py3-none-any.whl", hash = "sha256:53326ea2ebec768070a94bee4e1b9194c9646ea0c2bd72422785bd0f9abfad7b"},
+ {file = "google_auth-2.32.0.tar.gz", hash = "sha256:49315be72c55a6a37d62819e3573f6b416aca00721f7e3e31a008d928bf64022"},
]
[package.dependencies]
@@ -1099,12 +1099,12 @@ httplib2 = ">=0.19.0"
[[package]]
name = "google-generativeai"
-version = "0.7.1"
+version = "0.7.2"
description = "Google Generative AI High level API client library and tools."
optional = false
python-versions = ">=3.9"
files = [
- {file = "google_generativeai-0.7.1-py3-none-any.whl", hash = "sha256:25017b1278c873b6db65ba41c70566ee9fce8f265498e8b2f6aac036528ba1c7"},
+ {file = "google_generativeai-0.7.2-py3-none-any.whl", hash = "sha256:3117d1ebc92ee77710d4bc25ab4763492fddce9b6332eb25d124cf5d8b78b339"},
]
[package.dependencies]
@@ -1229,61 +1229,61 @@ typing-extensions = ">=4.7,<5"
[[package]]
name = "grpcio"
-version = "1.64.1"
+version = "1.65.0"
description = "HTTP/2-based RPC framework"
optional = false
python-versions = ">=3.8"
files = [
- {file = "grpcio-1.64.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:55697ecec192bc3f2f3cc13a295ab670f51de29884ca9ae6cd6247df55df2502"},
- {file = "grpcio-1.64.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3b64ae304c175671efdaa7ec9ae2cc36996b681eb63ca39c464958396697daff"},
- {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:bac71b4b28bc9af61efcdc7630b166440bbfbaa80940c9a697271b5e1dabbc61"},
- {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c024ffc22d6dc59000faf8ad781696d81e8e38f4078cb0f2630b4a3cf231a90"},
- {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7cd5c1325f6808b8ae31657d281aadb2a51ac11ab081ae335f4f7fc44c1721d"},
- {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0a2813093ddb27418a4c99f9b1c223fab0b053157176a64cc9db0f4557b69bd9"},
- {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2981c7365a9353f9b5c864595c510c983251b1ab403e05b1ccc70a3d9541a73b"},
- {file = "grpcio-1.64.1-cp310-cp310-win32.whl", hash = "sha256:1262402af5a511c245c3ae918167eca57342c72320dffae5d9b51840c4b2f86d"},
- {file = "grpcio-1.64.1-cp310-cp310-win_amd64.whl", hash = "sha256:19264fc964576ddb065368cae953f8d0514ecc6cb3da8903766d9fb9d4554c33"},
- {file = "grpcio-1.64.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:58b1041e7c870bb30ee41d3090cbd6f0851f30ae4eb68228955d973d3efa2e61"},
- {file = "grpcio-1.64.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bbc5b1d78a7822b0a84c6f8917faa986c1a744e65d762ef6d8be9d75677af2ca"},
- {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5841dd1f284bd1b3d8a6eca3a7f062b06f1eec09b184397e1d1d43447e89a7ae"},
- {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8caee47e970b92b3dd948371230fcceb80d3f2277b3bf7fbd7c0564e7d39068e"},
- {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73819689c169417a4f978e562d24f2def2be75739c4bed1992435d007819da1b"},
- {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6503b64c8b2dfad299749cad1b595c650c91e5b2c8a1b775380fcf8d2cbba1e9"},
- {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1de403fc1305fd96cfa75e83be3dee8538f2413a6b1685b8452301c7ba33c294"},
- {file = "grpcio-1.64.1-cp311-cp311-win32.whl", hash = "sha256:d4d29cc612e1332237877dfa7fe687157973aab1d63bd0f84cf06692f04c0367"},
- {file = "grpcio-1.64.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e56462b05a6f860b72f0fa50dca06d5b26543a4e88d0396259a07dc30f4e5aa"},
- {file = "grpcio-1.64.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:4657d24c8063e6095f850b68f2d1ba3b39f2b287a38242dcabc166453e950c59"},
- {file = "grpcio-1.64.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:62b4e6eb7bf901719fce0ca83e3ed474ae5022bb3827b0a501e056458c51c0a1"},
- {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:ee73a2f5ca4ba44fa33b4d7d2c71e2c8a9e9f78d53f6507ad68e7d2ad5f64a22"},
- {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:198908f9b22e2672a998870355e226a725aeab327ac4e6ff3a1399792ece4762"},
- {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39b9d0acaa8d835a6566c640f48b50054f422d03e77e49716d4c4e8e279665a1"},
- {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5e42634a989c3aa6049f132266faf6b949ec2a6f7d302dbb5c15395b77d757eb"},
- {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1a82e0b9b3022799c336e1fc0f6210adc019ae84efb7321d668129d28ee1efb"},
- {file = "grpcio-1.64.1-cp312-cp312-win32.whl", hash = "sha256:55260032b95c49bee69a423c2f5365baa9369d2f7d233e933564d8a47b893027"},
- {file = "grpcio-1.64.1-cp312-cp312-win_amd64.whl", hash = "sha256:c1a786ac592b47573a5bb7e35665c08064a5d77ab88a076eec11f8ae86b3e3f6"},
- {file = "grpcio-1.64.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:a011ac6c03cfe162ff2b727bcb530567826cec85eb8d4ad2bfb4bd023287a52d"},
- {file = "grpcio-1.64.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4d6dab6124225496010bd22690f2d9bd35c7cbb267b3f14e7a3eb05c911325d4"},
- {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:a5e771d0252e871ce194d0fdcafd13971f1aae0ddacc5f25615030d5df55c3a2"},
- {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3c1b90ab93fed424e454e93c0ed0b9d552bdf1b0929712b094f5ecfe7a23ad"},
- {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20405cb8b13fd779135df23fabadc53b86522d0f1cba8cca0e87968587f50650"},
- {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0cc79c982ccb2feec8aad0e8fb0d168bcbca85bc77b080d0d3c5f2f15c24ea8f"},
- {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a3a035c37ce7565b8f4f35ff683a4db34d24e53dc487e47438e434eb3f701b2a"},
- {file = "grpcio-1.64.1-cp38-cp38-win32.whl", hash = "sha256:1257b76748612aca0f89beec7fa0615727fd6f2a1ad580a9638816a4b2eb18fd"},
- {file = "grpcio-1.64.1-cp38-cp38-win_amd64.whl", hash = "sha256:0a12ddb1678ebc6a84ec6b0487feac020ee2b1659cbe69b80f06dbffdb249122"},
- {file = "grpcio-1.64.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:75dbbf415026d2862192fe1b28d71f209e2fd87079d98470db90bebe57b33179"},
- {file = "grpcio-1.64.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e3d9f8d1221baa0ced7ec7322a981e28deb23749c76eeeb3d33e18b72935ab62"},
- {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5f8b75f64d5d324c565b263c67dbe4f0af595635bbdd93bb1a88189fc62ed2e5"},
- {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c84ad903d0d94311a2b7eea608da163dace97c5fe9412ea311e72c3684925602"},
- {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:940e3ec884520155f68a3b712d045e077d61c520a195d1a5932c531f11883489"},
- {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f10193c69fc9d3d726e83bbf0f3d316f1847c3071c8c93d8090cf5f326b14309"},
- {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac15b6c2c80a4d1338b04d42a02d376a53395ddf0ec9ab157cbaf44191f3ffdd"},
- {file = "grpcio-1.64.1-cp39-cp39-win32.whl", hash = "sha256:03b43d0ccf99c557ec671c7dede64f023c7da9bb632ac65dbc57f166e4970040"},
- {file = "grpcio-1.64.1-cp39-cp39-win_amd64.whl", hash = "sha256:ed6091fa0adcc7e4ff944090cf203a52da35c37a130efa564ded02b7aff63bcd"},
- {file = "grpcio-1.64.1.tar.gz", hash = "sha256:8d51dd1c59d5fa0f34266b80a3805ec29a1f26425c2a54736133f6d87fc4968a"},
+ {file = "grpcio-1.65.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:66ea0ca6108fcb391444bb7b37d04eac85bfaea1cfaf16db675d3734fc74ca1b"},
+ {file = "grpcio-1.65.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:45d371dc4436fdcc31677f75b3ebe6175fbf0712ced49e0e4dfc18bbaf50f5a7"},
+ {file = "grpcio-1.65.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:02dbbe113ec48581da07b7ddf52bfd49f5772374c4b5e36ea25131ce00b4f4f3"},
+ {file = "grpcio-1.65.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c9ee7b8f1ac82cc24f223cd7ec803c17079f90e63022d3e66c5e53fff0afb99"},
+ {file = "grpcio-1.65.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da927f8a44e42837ae0027a3a063c85e2b26491d2babd4554e116f66fd46045d"},
+ {file = "grpcio-1.65.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9916ea670a589f95f2453a4a5040294ace096271c126e684a1e45e61af76c988"},
+ {file = "grpcio-1.65.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c46114787c5f530e845d2781f914600aade04b4f132dd012efb31bc4f76a72bb"},
+ {file = "grpcio-1.65.0-cp310-cp310-win32.whl", hash = "sha256:1362d94ac9c05b202736180d23296840e00f495859b206261e6ed03a6d41978b"},
+ {file = "grpcio-1.65.0-cp310-cp310-win_amd64.whl", hash = "sha256:00ed0828980009ce852d98230cdd2d5a22a4bcb946b5a0f6334dfd8258374cd7"},
+ {file = "grpcio-1.65.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:25303f3747522252dd9cfcbacb88d828a36040f513e28fba17ee6184ebc3d330"},
+ {file = "grpcio-1.65.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a2b368717dd8e0f6cb7e412d3b3bfb0012f61c04b2f76dbed669b0f5cf3fb0c"},
+ {file = "grpcio-1.65.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:93c41fb74c576dc0130b190a5775197282115c6abbe1d913d42d9a2f9d98fdae"},
+ {file = "grpcio-1.65.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34eb4fb9ef4d11ea741d264916d1b31a9e169d539a6f1c8300e04c493eec747e"},
+ {file = "grpcio-1.65.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55c41272f9d7d3503e3e3e93f3f98589f07075eebd24e1c291a1df2e8ef40a49"},
+ {file = "grpcio-1.65.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c275bac926754022c89ef03f16470f65b811e2cc25f2167d365564ad43e31001"},
+ {file = "grpcio-1.65.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b02db2a59071f4d05cfc4d0c972759778d27e1d3347f22ca178b91117ad10541"},
+ {file = "grpcio-1.65.0-cp311-cp311-win32.whl", hash = "sha256:ec9f41b9b0eb6407a6edb21bc22cb32e03cae76cde9c1d8bb151ed77c2c5af94"},
+ {file = "grpcio-1.65.0-cp311-cp311-win_amd64.whl", hash = "sha256:3efc8b0600870f5e518dd2738188b3ba7b1bb2668244c9a2a8c4debda4ffe62b"},
+ {file = "grpcio-1.65.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:d787abafafa9ed71e17220d4178c883abdb380e0484bd8965cb2e06375c7495b"},
+ {file = "grpcio-1.65.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:52347f21d6ec77d7e7e4d5037f5e8ac0a0c851856d9459f9f95b009c2c740b4a"},
+ {file = "grpcio-1.65.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:b16e1cd9b9cb9ac942cb20b7a2b1c5d35b9e61017e2998bf242a6f7748071795"},
+ {file = "grpcio-1.65.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89bc9c8c6743a48f115fea8f3fada76be269d1914bf636e5fdb7cec9cdf192bc"},
+ {file = "grpcio-1.65.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5a2ae900e6423438c4a9a5be38e9228621340a18333371215c0419d24a254ef"},
+ {file = "grpcio-1.65.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4f451091ddd28f00c655f0b1e208cca705d40e4fde56a3cf849fead61a700d10"},
+ {file = "grpcio-1.65.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4e30cd885e02abb98d6b0d5beb6259a567b0ce1416c498ec815fe383adb77864"},
+ {file = "grpcio-1.65.0-cp312-cp312-win32.whl", hash = "sha256:9a9a0ce10a07923ebd48c056060052ebddfbec3193cdd32207af358ef317b00a"},
+ {file = "grpcio-1.65.0-cp312-cp312-win_amd64.whl", hash = "sha256:87d9350ffe1a84b7441db7c70fdb4e51269a379f7a95d696d0d133831c4f9a19"},
+ {file = "grpcio-1.65.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:0c504b30fc2fba143d9254e0240243b5866df9b7523162448797f4b21b5f30d5"},
+ {file = "grpcio-1.65.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:480be4d41ceb5a7f22ecfc8db1ab68aeb58cc1a2da0865a91917d3cd0438dac7"},
+ {file = "grpcio-1.65.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:984a1627b50d5df4a24120302ca95adb5139ba1c40354ba258fc2913666d8ee7"},
+ {file = "grpcio-1.65.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f242956c0f4985dfcc920cd251cd7a899ca168e157e98c9b74a688657e813ad6"},
+ {file = "grpcio-1.65.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ea93f570b2341c69635b8a333afb99fb4d5584f26a9cc94f06e56c943648aab"},
+ {file = "grpcio-1.65.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1bebefd76517a43d0e77a5dcd61a8b69e9775340d856a0b35c6368ae628f7714"},
+ {file = "grpcio-1.65.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:356d10a491a92a08c21aef806379f7b020f591c23580e3d29aeeb59d45908c86"},
+ {file = "grpcio-1.65.0-cp38-cp38-win32.whl", hash = "sha256:c3294fd3ef9faa1fe14ad15d72dd7d2ee9fee6d3bd29a08c53e59a3c94de9cc9"},
+ {file = "grpcio-1.65.0-cp38-cp38-win_amd64.whl", hash = "sha256:a2defc49c984550f25034e88d17a7e69dba6deb2b981d8f56f19b3aaa788ff30"},
+ {file = "grpcio-1.65.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:b73022222ed4bf718d3d8527a9b88b162074a62c7530d30f4e951b56304b0f19"},
+ {file = "grpcio-1.65.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16e0f789158ecc8309e0a2f16cb8c5e4753f351a7673aab75f42783c83f1e38b"},
+ {file = "grpcio-1.65.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:cb0bd8bfba21fe0318317bf11687c67a3f8ce726369c0b3ccf4e6607fc5bc5f2"},
+ {file = "grpcio-1.65.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1096f0fa79ec601aefd71685d3a610cdde96274c38cd8adcef972660297669a"},
+ {file = "grpcio-1.65.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e576a88ce82fea70e68c548aceb5cd560c27da50091581996858bbbe01230c83"},
+ {file = "grpcio-1.65.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab70bd1ccb05ef373b691a9b9985289d8b2cf63c704471f5ee132e228d351af5"},
+ {file = "grpcio-1.65.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:03eab632a8ce8dba00d97482d2821bf752a7c3cb4dc051be6c587ad3ca1c3e6d"},
+ {file = "grpcio-1.65.0-cp39-cp39-win32.whl", hash = "sha256:f19bb85795ca82e007be427e7b6ac5e730023ffbab69d39ddeb1b84c6339df16"},
+ {file = "grpcio-1.65.0-cp39-cp39-win_amd64.whl", hash = "sha256:dbd7eeafa67d8e403ac61caa31ebda2861435dcfd7bb7953c4ef05ad2ecf74bf"},
+ {file = "grpcio-1.65.0.tar.gz", hash = "sha256:2c7891f66daefc80cce1bed6bc0c2802d26dac46544ba1be79c4e7d85661dd73"},
]
[package.extras]
-protobuf = ["grpcio-tools (>=1.64.1)"]
+protobuf = ["grpcio-tools (>=1.65.0)"]
[[package]]
name = "grpcio-status"
@@ -1418,13 +1418,13 @@ typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "t
[[package]]
name = "identify"
-version = "2.5.36"
+version = "2.6.0"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"},
- {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"},
+ {file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"},
+ {file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"},
]
[package.extras]
@@ -1742,13 +1742,13 @@ files = [
[[package]]
name = "jsonschema"
-version = "4.22.0"
+version = "4.23.0"
description = "An implementation of JSON Schema validation for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"},
- {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"},
+ {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"},
+ {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"},
]
[package.dependencies]
@@ -1763,11 +1763,11 @@ rfc3339-validator = {version = "*", optional = true, markers = "extra == \"forma
rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""}
rpds-py = ">=0.7.1"
uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""}
-webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""}
+webcolors = {version = ">=24.6.0", optional = true, markers = "extra == \"format-nongpl\""}
[package.extras]
format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
-format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
+format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"]
[[package]]
name = "jsonschema-specifications"
@@ -2179,10 +2179,10 @@ typing = ["mypy (>=1.0.0)", "types-setuptools"]
[[package]]
name = "lightrag"
-version = "0.0.0-alpha.13"
-description = "The 'PyTorch' library for LLM applications. RAG=Retriever-Agent-Generator."
+version = "0.0.0-beta.1"
+description = "The Lightning Library for LLM Applications."
optional = false
-python-versions = ">=3.10, <4.0"
+python-versions = ">=3.9, <4.0"
files = []
develop = true
@@ -2749,13 +2749,13 @@ files = [
[[package]]
name = "openai"
-version = "1.35.10"
+version = "1.35.13"
description = "The official Python library for the openai API"
optional = false
python-versions = ">=3.7.1"
files = [
- {file = "openai-1.35.10-py3-none-any.whl", hash = "sha256:962cb5c23224b5cbd16078308dabab97a08b0a5ad736a4fdb3dc2ffc44ac974f"},
- {file = "openai-1.35.10.tar.gz", hash = "sha256:85966949f4f960f3e4b239a659f9fd64d3a97ecc43c44dc0a044b5c7f11cccc6"},
+ {file = "openai-1.35.13-py3-none-any.whl", hash = "sha256:36ec3e93e0d1f243f69be85c89b9221a471c3e450dfd9df16c9829e3cdf63e60"},
+ {file = "openai-1.35.13.tar.gz", hash = "sha256:c684f3945608baf7d2dcc0ef3ee6f3e27e4c66f21076df0b47be45d57e6ae6e4"},
]
[package.dependencies]
@@ -3844,110 +3844,110 @@ files = [
[[package]]
name = "rpds-py"
-version = "0.18.1"
+version = "0.19.0"
description = "Python bindings to Rust's persistent data structures (rpds)"
optional = false
python-versions = ">=3.8"
files = [
- {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"},
- {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"},
- {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"},
- {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"},
- {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"},
- {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"},
- {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"},
- {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"},
- {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"},
- {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"},
- {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"},
- {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"},
- {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"},
- {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"},
- {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"},
- {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"},
- {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"},
- {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"},
- {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"},
- {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"},
- {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"},
- {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"},
- {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"},
- {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"},
- {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"},
- {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"},
- {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"},
- {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"},
- {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"},
- {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"},
- {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"},
- {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"},
- {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"},
- {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"},
- {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"},
- {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"},
- {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"},
- {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"},
- {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"},
- {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"},
- {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"},
- {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"},
- {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"},
- {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"},
+ {file = "rpds_py-0.19.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:fb37bd599f031f1a6fb9e58ec62864ccf3ad549cf14bac527dbfa97123edcca4"},
+ {file = "rpds_py-0.19.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3384d278df99ec2c6acf701d067147320b864ef6727405d6470838476e44d9e8"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54548e0be3ac117595408fd4ca0ac9278fde89829b0b518be92863b17ff67a2"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8eb488ef928cdbc05a27245e52de73c0d7c72a34240ef4d9893fdf65a8c1a955"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5da93debdfe27b2bfc69eefb592e1831d957b9535e0943a0ee8b97996de21b5"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79e205c70afddd41f6ee79a8656aec738492a550247a7af697d5bd1aee14f766"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:959179efb3e4a27610e8d54d667c02a9feaa86bbabaf63efa7faa4dfa780d4f1"},
+ {file = "rpds_py-0.19.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a6e605bb9edcf010f54f8b6a590dd23a4b40a8cb141255eec2a03db249bc915b"},
+ {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9133d75dc119a61d1a0ded38fb9ba40a00ef41697cc07adb6ae098c875195a3f"},
+ {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd36b712d35e757e28bf2f40a71e8f8a2d43c8b026d881aa0c617b450d6865c9"},
+ {file = "rpds_py-0.19.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354f3a91718489912f2e0fc331c24eaaf6a4565c080e00fbedb6015857c00582"},
+ {file = "rpds_py-0.19.0-cp310-none-win32.whl", hash = "sha256:ebcbf356bf5c51afc3290e491d3722b26aaf5b6af3c1c7f6a1b757828a46e336"},
+ {file = "rpds_py-0.19.0-cp310-none-win_amd64.whl", hash = "sha256:75a6076289b2df6c8ecb9d13ff79ae0cad1d5fb40af377a5021016d58cd691ec"},
+ {file = "rpds_py-0.19.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6d45080095e585f8c5097897313def60caa2046da202cdb17a01f147fb263b81"},
+ {file = "rpds_py-0.19.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5c9581019c96f865483d031691a5ff1cc455feb4d84fc6920a5ffc48a794d8a"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1540d807364c84516417115c38f0119dfec5ea5c0dd9a25332dea60b1d26fc4d"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e65489222b410f79711dc3d2d5003d2757e30874096b2008d50329ea4d0f88c"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da6f400eeb8c36f72ef6646ea530d6d175a4f77ff2ed8dfd6352842274c1d8b"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37f46bb11858717e0efa7893c0f7055c43b44c103e40e69442db5061cb26ed34"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071d4adc734de562bd11d43bd134330fb6249769b2f66b9310dab7460f4bf714"},
+ {file = "rpds_py-0.19.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9625367c8955e4319049113ea4f8fee0c6c1145192d57946c6ffcd8fe8bf48dd"},
+ {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e19509145275d46bc4d1e16af0b57a12d227c8253655a46bbd5ec317e941279d"},
+ {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d438e4c020d8c39961deaf58f6913b1bf8832d9b6f62ec35bd93e97807e9cbc"},
+ {file = "rpds_py-0.19.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90bf55d9d139e5d127193170f38c584ed3c79e16638890d2e36f23aa1630b952"},
+ {file = "rpds_py-0.19.0-cp311-none-win32.whl", hash = "sha256:8d6ad132b1bc13d05ffe5b85e7a01a3998bf3a6302ba594b28d61b8c2cf13aaf"},
+ {file = "rpds_py-0.19.0-cp311-none-win_amd64.whl", hash = "sha256:7ec72df7354e6b7f6eb2a17fa6901350018c3a9ad78e48d7b2b54d0412539a67"},
+ {file = "rpds_py-0.19.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:5095a7c838a8647c32aa37c3a460d2c48debff7fc26e1136aee60100a8cd8f68"},
+ {file = "rpds_py-0.19.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f2f78ef14077e08856e788fa482107aa602636c16c25bdf59c22ea525a785e9"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cc6cb44f8636fbf4a934ca72f3e786ba3c9f9ba4f4d74611e7da80684e48d2"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf902878b4af334a09de7a45badbff0389e7cf8dc2e4dcf5f07125d0b7c2656d"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:688aa6b8aa724db1596514751ffb767766e02e5c4a87486ab36b8e1ebc1aedac"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57dbc9167d48e355e2569346b5aa4077f29bf86389c924df25c0a8b9124461fb"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4cf5a9497874822341c2ebe0d5850fed392034caadc0bad134ab6822c0925b"},
+ {file = "rpds_py-0.19.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8a790d235b9d39c70a466200d506bb33a98e2ee374a9b4eec7a8ac64c2c261fa"},
+ {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1d16089dfa58719c98a1c06f2daceba6d8e3fb9b5d7931af4a990a3c486241cb"},
+ {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bc9128e74fe94650367fe23f37074f121b9f796cabbd2f928f13e9661837296d"},
+ {file = "rpds_py-0.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c8f77e661ffd96ff104bebf7d0f3255b02aa5d5b28326f5408d6284c4a8b3248"},
+ {file = "rpds_py-0.19.0-cp312-none-win32.whl", hash = "sha256:5f83689a38e76969327e9b682be5521d87a0c9e5a2e187d2bc6be4765f0d4600"},
+ {file = "rpds_py-0.19.0-cp312-none-win_amd64.whl", hash = "sha256:06925c50f86da0596b9c3c64c3837b2481337b83ef3519e5db2701df695453a4"},
+ {file = "rpds_py-0.19.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:52e466bea6f8f3a44b1234570244b1cff45150f59a4acae3fcc5fd700c2993ca"},
+ {file = "rpds_py-0.19.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e21cc693045fda7f745c790cb687958161ce172ffe3c5719ca1764e752237d16"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b31f059878eb1f5da8b2fd82480cc18bed8dcd7fb8fe68370e2e6285fa86da6"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dd46f309e953927dd018567d6a9e2fb84783963650171f6c5fe7e5c41fd5666"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a01a4490e170376cd79258b7f755fa13b1a6c3667e872c8e35051ae857a92b"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcf426a8c38eb57f7bf28932e68425ba86def6e756a5b8cb4731d8e62e4e0223"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68eea5df6347d3f1378ce992d86b2af16ad7ff4dcb4a19ccdc23dea901b87fb"},
+ {file = "rpds_py-0.19.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dab8d921b55a28287733263c0e4c7db11b3ee22aee158a4de09f13c93283c62d"},
+ {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6fe87efd7f47266dfc42fe76dae89060038f1d9cb911f89ae7e5084148d1cc08"},
+ {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:535d4b52524a961d220875688159277f0e9eeeda0ac45e766092bfb54437543f"},
+ {file = "rpds_py-0.19.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8b1a94b8afc154fbe36978a511a1f155f9bd97664e4f1f7a374d72e180ceb0ae"},
+ {file = "rpds_py-0.19.0-cp38-none-win32.whl", hash = "sha256:7c98298a15d6b90c8f6e3caa6457f4f022423caa5fa1a1ca7a5e9e512bdb77a4"},
+ {file = "rpds_py-0.19.0-cp38-none-win_amd64.whl", hash = "sha256:b0da31853ab6e58a11db3205729133ce0df26e6804e93079dee095be3d681dc1"},
+ {file = "rpds_py-0.19.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5039e3cef7b3e7a060de468a4a60a60a1f31786da94c6cb054e7a3c75906111c"},
+ {file = "rpds_py-0.19.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab1932ca6cb8c7499a4d87cb21ccc0d3326f172cfb6a64021a889b591bb3045c"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2afd2164a1e85226fcb6a1da77a5c8896c18bfe08e82e8ceced5181c42d2179"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b1c30841f5040de47a0046c243fc1b44ddc87d1b12435a43b8edff7e7cb1e0d0"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f757f359f30ec7dcebca662a6bd46d1098f8b9fb1fcd661a9e13f2e8ce343ba1"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15e65395a59d2e0e96caf8ee5389ffb4604e980479c32742936ddd7ade914b22"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb0f6eb3a320f24b94d177e62f4074ff438f2ad9d27e75a46221904ef21a7b05"},
+ {file = "rpds_py-0.19.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b228e693a2559888790936e20f5f88b6e9f8162c681830eda303bad7517b4d5a"},
+ {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2575efaa5d949c9f4e2cdbe7d805d02122c16065bfb8d95c129372d65a291a0b"},
+ {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5c872814b77a4e84afa293a1bee08c14daed1068b2bb1cc312edbf020bbbca2b"},
+ {file = "rpds_py-0.19.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:850720e1b383df199b8433a20e02b25b72f0fded28bc03c5bd79e2ce7ef050be"},
+ {file = "rpds_py-0.19.0-cp39-none-win32.whl", hash = "sha256:ce84a7efa5af9f54c0aa7692c45861c1667080814286cacb9958c07fc50294fb"},
+ {file = "rpds_py-0.19.0-cp39-none-win_amd64.whl", hash = "sha256:1c26da90b8d06227d7769f34915913911222d24ce08c0ab2d60b354e2d9c7aff"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:75969cf900d7be665ccb1622a9aba225cf386bbc9c3bcfeeab9f62b5048f4a07"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8445f23f13339da640d1be8e44e5baf4af97e396882ebbf1692aecd67f67c479"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5a7c1062ef8aea3eda149f08120f10795835fc1c8bc6ad948fb9652a113ca55"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:462b0c18fbb48fdbf980914a02ee38c423a25fcc4cf40f66bacc95a2d2d73bc8"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3208f9aea18991ac7f2b39721e947bbd752a1abbe79ad90d9b6a84a74d44409b"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3444fe52b82f122d8a99bf66777aed6b858d392b12f4c317da19f8234db4533"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88cb4bac7185a9f0168d38c01d7a00addece9822a52870eee26b8d5b61409213"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b130bd4163c93798a6b9bb96be64a7c43e1cec81126ffa7ffaa106e1fc5cef5"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:a707b158b4410aefb6b054715545bbb21aaa5d5d0080217290131c49c2124a6e"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dc9ac4659456bde7c567107556ab065801622396b435a3ff213daef27b495388"},
+ {file = "rpds_py-0.19.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:81ea573aa46d3b6b3d890cd3c0ad82105985e6058a4baed03cf92518081eec8c"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3f148c3f47f7f29a79c38cc5d020edcb5ca780020fab94dbc21f9af95c463581"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0906357f90784a66e89ae3eadc2654f36c580a7d65cf63e6a616e4aec3a81be"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f629ecc2db6a4736b5ba95a8347b0089240d69ad14ac364f557d52ad68cf94b0"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6feacd1d178c30e5bc37184526e56740342fd2aa6371a28367bad7908d454fc"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b6068ee374fdfab63689be0963333aa83b0815ead5d8648389a8ded593378"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d57546bad81e0da13263e4c9ce30e96dcbe720dbff5ada08d2600a3502e526"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b6683a37338818646af718c9ca2a07f89787551057fae57c4ec0446dc6224b"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e8481b946792415adc07410420d6fc65a352b45d347b78fec45d8f8f0d7496f0"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bec35eb20792ea64c3c57891bc3ca0bedb2884fbac2c8249d9b731447ecde4fa"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:aa5476c3e3a402c37779e95f7b4048db2cb5b0ed0b9d006983965e93f40fe05a"},
+ {file = "rpds_py-0.19.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:19d02c45f2507b489fd4df7b827940f1420480b3e2e471e952af4d44a1ea8e34"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3e2fd14c5d49ee1da322672375963f19f32b3d5953f0615b175ff7b9d38daed"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:93a91c2640645303e874eada51f4f33351b84b351a689d470f8108d0e0694210"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b9fc03bf76a94065299d4a2ecd8dfbae4ae8e2e8098bbfa6ab6413ca267709"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a4b07cdf3f84310c08c1de2c12ddadbb7a77568bcb16e95489f9c81074322ed"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba0ed0dc6763d8bd6e5de5cf0d746d28e706a10b615ea382ac0ab17bb7388633"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:474bc83233abdcf2124ed3f66230a1c8435896046caa4b0b5ab6013c640803cc"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329c719d31362355a96b435f4653e3b4b061fcc9eba9f91dd40804ca637d914e"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef9101f3f7b59043a34f1dccbb385ca760467590951952d6701df0da9893ca0c"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0121803b0f424ee2109d6e1f27db45b166ebaa4b32ff47d6aa225642636cd834"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8344127403dea42f5970adccf6c5957a71a47f522171fafaf4c6ddb41b61703a"},
+ {file = "rpds_py-0.19.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:443cec402ddd650bb2b885113e1dcedb22b1175c6be223b14246a714b61cd521"},
+ {file = "rpds_py-0.19.0.tar.gz", hash = "sha256:4fdc9afadbeb393b4bbbad75481e0ea78e4469f2e1d713a90811700830b553a9"},
]
[[package]]
@@ -3999,13 +3999,13 @@ win32 = ["pywin32"]
[[package]]
name = "setuptools"
-version = "70.2.0"
+version = "70.3.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
- {file = "setuptools-70.2.0-py3-none-any.whl", hash = "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05"},
- {file = "setuptools-70.2.0.tar.gz", hash = "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1"},
+ {file = "setuptools-70.3.0-py3-none-any.whl", hash = "sha256:fe384da74336c398e0d956d1cae0669bc02eed936cdb1d49b57de1990dc11ffc"},
+ {file = "setuptools-70.3.0.tar.gz", hash = "sha256:f171bab1dfbc86b132997f26a119f6056a57950d058587841a0082e8830f9dc5"},
]
[package.extras]
@@ -4334,17 +4334,20 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
[[package]]
name = "sympy"
-version = "1.12.1"
+version = "1.13.0"
description = "Computer algebra system (CAS) in Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "sympy-1.12.1-py3-none-any.whl", hash = "sha256:9b2cbc7f1a640289430e13d2a56f02f867a1da0190f2f99d8968c2f74da0e515"},
- {file = "sympy-1.12.1.tar.gz", hash = "sha256:2877b03f998cd8c08f07cd0de5b767119cd3ef40d09f41c30d722f6686b0fb88"},
+ {file = "sympy-1.13.0-py3-none-any.whl", hash = "sha256:6b0b32a4673fb91bd3cac3b55406c8e01d53ae22780be467301cc452f6680c92"},
+ {file = "sympy-1.13.0.tar.gz", hash = "sha256:3b6af8f4d008b9a1a6a4268b335b984b23835f26d1d60b0526ebc71d48a25f57"},
]
[package.dependencies]
-mpmath = ">=1.1.0,<1.4.0"
+mpmath = ">=1.1.0,<1.4"
+
+[package.extras]
+dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"]
[[package]]
name = "tbb"
@@ -4893,4 +4896,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = ">=3.11, <4.0"
-content-hash = "cf8c1a48af459ea3686195ef02b1183f46c6328d907f524a3c59c2736fc5c119"
+content-hash = "c37f91cb9a72abd5d4d561cec7b938e75979dcafb7afdc753837caaae841fbd5"
diff --git a/pyproject.toml b/pyproject.toml
index 9e739301..2a1a6f53 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,11 +9,11 @@ packages = [{ from = "_lightrag", include = "lightrag" }] # empty packa
[tool.poetry.dependencies]
python = ">=3.11, <4.0"
-# lightrag = { path = "lightrag", develop = true }
+lightrag = { path = "lightrag", develop = true }
torch = "^2.3.1"
openai = "^1.34.0"
# lightrag = {path = "lightrag/dist/lightrag-0.0.0a11-py3-none-any.whl"}
-lightrag = "^0.0.0a13"
+# lightrag = "^0.0.0a13"
[tool.poetry.group.dev.dependencies]
From 031593ab1085bfae7967ba8027f763ed9a50159a Mon Sep 17 00:00:00 2001
From: Li Yin
Date: Thu, 11 Jul 2024 22:09:46 -0700
Subject: [PATCH 8/8] half way done retriever editing
---
docs/source/tutorials/retriever.rst | 110 ++++++++++++++++------------
1 file changed, 65 insertions(+), 45 deletions(-)
diff --git a/docs/source/tutorials/retriever.rst b/docs/source/tutorials/retriever.rst
index 1b131463..6fe4e99b 100644
--- a/docs/source/tutorials/retriever.rst
+++ b/docs/source/tutorials/retriever.rst
@@ -14,20 +14,21 @@ Retriever
.. **Why Retriever for LLM?**
-LLMs halluciate and also has knowledge cut-off. External and relevant context is needed to increase the factuality, relevancy, and freshness on the LLM answers.
-Due to LLM's context window limit(can only take so much tokens each time), the ``lost-in-the-middle`` problem [6]_, and the high cost on speed and resources using large context,
-it is practical to use a retriever to retrieve the most relevant information to get the best performance. Retrieval Augemented Generation (RAG) [7]_ applications become one of main applications in LLMs.
+LLMs halluciate and also have a knowledge cut-off.
+External and relevant context is needed to increase the factuality, relevancy, and freshness of the LLM answers.
+Due to the LLM's context window limit (it can only take so many tokens at a time), the ``lost-in-the-middle`` problem [6]_, and the high cost in speed and resources using large context,
+it is practical to use a retriever to retrieve the most relevant information for the best performance. Retrieval Augemented Generation (RAG) [7]_ applications have become one of main applications in LLMs.
.. It is easy to build a demo, but hard to excel due to the many different parts in the pipeline that made it difficult to evaluate and to optimize.
**What is a retriever?**
-Though the definition is simple - "Retrieve relevant information for a given query from a given database", retriever can go as wide as the entire search and information retriever field.
-No doubt the retriever part is the one of the most diversity and have the longest history in LLM application landscapes.
+Though the definition is simple-"Retrieve relevant information for a given query from a given database"-the scope of a retriever can extend as wide as the entire search and information retrieval field.
+Numerous search techniques existed long before vector/semantic search and reranking models, such as keyword search, fuzzy search, proximity search, phrase search, boolean search, facet search, full-text search.
+These techniques can be applied to various data types, including text, time-sensitive data, locations, sensor data, images, videos, and audio.
+Additionally, they can be stored in various types of databases, such as relational databases, NoSQL databases, vector databases, and graph databases.
-There are numerous search techniques long existing before the vector/semantic search and reranking models, such as keyword search, fuzzy search, proximity search, phrase search, boolean search, facet search, full-text search,
-and can be applied on various data types, such as text, time-sensitive data, locations, sensor data, and images, videos, audios, etc, and stored in various types of databases, such as relational databases, NoSQL databases, and vector databases.
.. In LightRAG
.. There are also dense and sparse retrieval methods.
@@ -45,16 +46,18 @@ and can be applied on various data types, such as text, time-sensitive data, loc
**Retrieval in Production**
-In real production, retrieval is often of multiple-stages, from the cheapest to the most expensive and most accurate, from millions of candidates to a few hundreds or even less.
-For example, when you want to search for candidates from a pool of profiles stored in realtional db say Postgres, you can search by name simply using keyword, or check if the name equals to the query.
-You also want to search by their profession, which you have already categorized, either by model or human labeling, this makes it a filter search.
-Or if the search query requires more semantic understanding, we will leverage semantic search using embedding models.
-If we want it to be more accurate, we move up to more expensive and more accurate methods such as reranking models and LLM-based retrieval methods.
+In real production, retrieval is often a multiple-stage process, progressing from the cheapest to the most expensive and accurate methods, narrowing down from millions of candidates to a few hundred or even less.
+For example, when you want to search for candidates from a pool of profiles stored in a realtional database like Postgres, you can start with a simple keyword search or check if the name equals the query.
+You may also want to search by profession, which has already been categorized either by a model or human labeling, making it a filter search.
+If the search query requires more semantic understanding, we will leverage semantic search using embedding models.
+If we want it to be even more accurate, we can move up to more expensive and accurate methods such as reranking models and LLM-based retrieval methods.
-Design pattern
+
+
+Design
------------------
.. figure:: /_static/images/retriever.png
@@ -62,42 +65,59 @@ Design pattern
:alt: Retriever design
:width: 620px
- LightRAG retriever covers high-precision retriever methods and make them work locally and in-memory, this will help researchers and developers build and test.
- We also showcase how it is like to work with cloud database for **large-scale data** along with its built-in search& filter methods.
+ LightRAG retriever covers (1) high-precision retrieval methods and enables them to work locally and in-memory, and (2) how to work with cloud databases for large-scale data, utilizing their built-in search and filter methods.
+
+
+ .. LightRAG retriever covers high-precision retrieval methods and enables them to work locally and in-memory, this will help researchers and developers build and test.
+ .. We also showcase how it is like to work with cloud database for **large-scale data** along with its built-in search& filter methods.
+
+
+Scope and Design Goals
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LightRAG library does not prioritize the coverage of integration, the reasons are:
+LightRAG library does not prioritize the coverage of integration for the following reasons:
1. It is literally too-wide to cover them all.
2. The challenges with RAG application lies more in evaluation and optimization due to many different moving parts and many hyperparmeters, and less in implementing or integrating a 3rd party retriever.
-We instead want to provide a design pattern where users can
+Instead, our design goals are:
+
+1. Representative and valable coverage:
+
+ a. High-precision retrieval methods and enabling them to work locally and in-memory so that researchers and developers can build and test more efficiently.
+ b. Showcase how to work with cloud databases for large-scale data, utilizing their built-in search and filter methods.
+
+2. Provide a clear design pattern so that users can:
+
+ a. Easily integrate their own retriever and make it work seamlessly with the remaining part of the LLM task pipeline.
+ b. Easily combine different retriever methods to form a multiple-stage retrieval pipeline.
+
+Here are current coverage on retriever methods:
-1. Learn our existing coverage and implementation and use them out-of-the-box as building blocks.
-2. Easily integrate their own retriever and make them work seamlessly with the remaining part of the LLM application so that they can evaluate and optimize the whole task pipeline.
-3. Easily combine different retriever methods to form a multiple-stage retrieval pipeline.
+1. LLMAsRetriever
+2. Reranker (Cross-encoder)
+3. Semantic Search (Bi-encoder)
+4. BM25
+5. Database's built-in search such as full-text search/SQL-based search using Postgres and semantic search using ``PgVector``.
-A retriever will work hand in hand with the ``database`` and the ``data model``.
-We will have a local database :class:`core.db.LocalDB` and a cloud sql-based database (using ``SQLAlchemy``) that can work with any data class, and espeically with the :class:`core.types.Document` and :class:`core.types.DialogTurn`
-which provides ``context`` and ``conversation_history`` and is key to the LLM application.
-As for the retriever methods, we cover the most representative methods: LLMAsRetriever, Reranker(Cross-encoder), Semantic Search(Bi-encoder), BM25, database's built-in search such as the full-text search/sql based search using Postgres and the semantic search using ``PgVector``.
-.. so that users can clearly and easily integrate their own retriever, either to work withh local files or to work with cloud databases with the remaining part of an LLM application.
-.. Our goal is for doing so, users get to better evaluate and optimize the whole task pipeline as a whole.
+With Database
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. A retriever in our library is a component that potentially retrieves relevant ``context`` and pass it to the ``prompt`` of a ``generator``.
-.. If your data is big, we assume it is users' responsibility to do fuzzy and cheap filter and search that gives high recall even though low precision till to have a manageable set of candidates (fit into local memory or a latency limit) to optimize for high precision.
-.. To optimize recall, often BM25, TF-IDF, and semantic search using embedding models are used. And lastly, reranking models are used for the final precision optimization.
-.. As the layer close to deliver the final user experience, we try to provide a great design pattern so that:
+.. A retriever will work hand in hand with the ``database`` and the ``data model``.
+.. We will have a :class:`LocalDB` and a cloud SQL-based database (using ``SQLAlchemy``) that can work with any data class, and especially with the :class:`core.types.Document` and :class:`core.types.DialogTurn`, which provide ``context`` and ``conversation_history`` and are key to the LLM application.
+.. As for the retriever methods, we cover the most representative methods:
-.. A retriever will work hand in hand with a ``database``: the retriever will be responsible for building and querying the index and work with a database, either local or cloud to save and load index.
+A retriever will work hand in hand with ``database``.
+We will provide a :class:`LocalDB` and a cloud SQL-based database (using ``SQLAlchemy``) that can work with any data class/model, espeically with the :class:`Document` for data processing and :class:`DialogTurn` for conversational data.
+``Document`` combined with text splitter and embedding models will provide the ``context`` in RAG.
+Working with ``DialogTurn`` can help manage ``conversation_history``, especiall for the lifelong memeory of a chatbot.
-.. A retriever will retrieve the `ids` of the ``top_k`` most relevant documents given a query. The user can then use these `ids` to retrieve the actual documents from the database.
-.. The most effective approch would be ``LLMasRetriever``, ``Reranker``, ``Embedding`` + ``BM25``.
Retriever Data Types
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -147,7 +167,7 @@ Here is our output format:
RetrieverOutputType = List[RetrieverOutput] # so to support multiple queries at once
-You can find the types in :ref:`core.types`. The list of queries and `RetrieverOutput` can be helpful for:
+You can find the types in :ref:`types`. The list of queries and `RetrieverOutput` can be helpful for:
(1) Batch-processing: especially for semantic search where multiple queries can be represented as numpy array and be computed all at once with faster speed than doing one by one.
(2) For `query expansion` where to increase the recall, users often generate multiple queries from the original query.
@@ -186,12 +206,12 @@ Please refer to :doc:`text_splitter` and our provided notebook on how to use it.
Retriever Base Class
^^^^^^^^^^^^^^^^^^^^^^^^
-Functionally, the base retriever :class:`core.retriever.Retriever` defines another required method ``build_index_from_documents`` where the subclass will prepare the retriever for the actual retrieval calls.
+Functionally, the base retriever :class:`Retriever` defines another required method ``build_index_from_documents`` where the subclass will prepare the retriever for the actual retrieval calls.
Optionally, the subclass can implement ``save_to_file`` and ``load_from_file`` to save and load the retriever to/from disk.
As the retriever is a subclass of component, you already inherited powerful serialization and deserialization methods such as ``to_dict``, ``from_dict``, and ``from_config`` to help
with the saving and loading process. As for helper attributes, we have ``indexed`` and ``index_keys`` to differentiate if the retriever is ready for retrieval and the attributes that are key to restore the functionality/states of the retriever.
It is up the subclass to decide how to decide the storage of the index, it can be in-memory, local disk, or cloud storage, or save as json or pickle file or even a db table.
-As an example, :class:`components.retriever.bm25_retriever.BM25Retriever` has the following key attributes to index.
+As an example, :class:`BM25Retriever` has the following key attributes to index.
.. code:: python
@@ -202,7 +222,7 @@ Retriever in Action
--------------------
All of our retrievers are subclassed from the base retriever, and they are located in the ``components.retriever`` module.
You can skim through their implementations here: :ref:`retriever`.
-Currently only :class:`components.retriever.faiss_retriever.BM25Retriever` needs to have its own ``save_to_file`` and ``load_from_file`` to avoid recomputation again.
+Currently only :class:`BM25Retriever` needs to have its own ``save_to_file`` and ``load_from_file`` to avoid recomputation again.
The ``FAISSRetriever`` will work with a database instead to store the embeddings and it alleviates the need for the retriever to deal with states saving.
In this note, we will use the following documents and queries for demonstration:
@@ -233,9 +253,9 @@ In this note, we will use the following documents and queries for demonstration:
The first query should retrieve the first and the last document, and the second query should retrieve the second and the third document.
-In-memory FAISSRetriever
+FAISSRetriever
^^^^^^^^^^^^^^^^^^^^^^^^
-First, let's do semantic search, here we will use in-memory :class:`components.retriever.faiss_retriever.InMemoryFAISSRetriever`.
+First, let's do semantic search, here we will use in-memory :class:`FAISSRetriever`.
FAISS retriever takes embeddings which can be ``List[float]`` or ``np.ndarray`` and build an index using FAISS library.
The query can take both embeddings and str formats.
@@ -283,7 +303,7 @@ The printout:
)
)
-We can also pass the documents using :meth:`components.retriever.faiss_retriever.InMemoryFAISSRetriever.build_index_from_documents` method after the initialization.
+We can also pass the documents using :meth:`build_index_from_documents` method after the initialization.
This is helpful when your retriever would need to work with different pool of documents each time.
.. code-block:: python
@@ -315,7 +335,7 @@ You can check the retriever for more type of scores.
BM25Retriever
^^^^^^^^^^^^^^^^^^^^^^^^
-So the semantic search works pretty well. We will see how :class:`components.retriever.bm25_retriever.BM25Retriever` works in comparison.
+So the semantic search works pretty well. We will see how :class:`BM25Retriever` works in comparison.
We reimplemented the code in [9]_ with one improvement: instead of using ``text.split(" ")``, we use tokenizer to split the text. Here is a comparison of how they different:
.. code-block:: python
@@ -391,7 +411,7 @@ Reranker as Retriever
^^^^^^^^^^^^^^^^^^^^^^^^
Semantic search works well, and reranker basd on mostly `cross-encoder` model is supposed to work even better.
We have integrated two rerankers: ``BAAI/bge-reranker-base`` [10]_ hosted on ``transformers`` and rerankers provided by ``Cohere`` [11]_.
-These models follow the ``ModelClient`` protocol and are directly accessible as retriever from :class:`components.retriever.reranker_retriever.RerankerRetriever`.
+These models follow the ``ModelClient`` protocol and are directly accessible as retriever from :class:`RerankerRetriever`.
@@ -400,8 +420,8 @@ These models follow the ``ModelClient`` protocol and are directly accessible as
A reranker will take ``ModelType.RERANKER`` and the standard LightRAG library requires it to have four arguments in the ``model_kwargs``:
``['model', 'top_k', 'documents', 'query']``. It is in the ModelClient which converts LightRAG's standard arguments to the model's specific arguments.
-If you want to intergrate your reranker, either locally or using APIs, check out :class:`components.model_client.transformers_client.TransformersClient` and
-:class:`components.model_client.cohere_client.CohereAPIClient` for how to do it.
+If you want to intergrate your reranker, either locally or using APIs, check out :class:`TransformersClient` and
+:class:`CohereAPIClient` for how to do it.
To use it from the ``RerankerRetriever``, we only need to pass the ``model`` along with other arguments who does not
@@ -594,7 +614,7 @@ When the scale of data is large, we will use a database to store the computed em
With LocalDB
^^^^^^^^^^^^^^^^^^^^^^^^
-We have previously computed embeddings, now let us :class:`core.db.LocalDB` to help with the persistence.
+We have previously computed embeddings, now let us :class:`LocalDB` to help with the persistence.
(Although you can totally persist them yourself such as using pickle).
Additionally, ``LocalDB`` help us keep track of our initial documents and its transformed documents.