langroid 0.40.0__tar.gz → 0.41.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {langroid-0.40.0 → langroid-0.41.1}/PKG-INFO +10 -1
- langroid-0.41.1/langroid/agent/tools/exa_search_tool.py +68 -0
- langroid-0.41.1/langroid/agent/tools/tavily_search_tool.py +50 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/model_info.py +10 -3
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/openai_gpt.py +32 -7
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/search.py +1 -1
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/utils.py +4 -3
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/web_search.py +91 -7
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/__init__.py +9 -11
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/base.py +3 -0
- langroid-0.41.1/langroid/vector_store/pineconedb.py +427 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/postgres.py +23 -15
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/weaviatedb.py +16 -2
- {langroid-0.40.0 → langroid-0.41.1}/pyproject.toml +17 -2
- {langroid-0.40.0 → langroid-0.41.1}/.gitignore +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/LICENSE +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/README.md +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/base.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/batch.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/callbacks/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/callbacks/chainlit.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/chat_document.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/openai_assistant.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/arangodb/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/arangodb/arangodb_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/arangodb/system_messages.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/arangodb/tools.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/arangodb/utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/doc_chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_rag/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/lance_tools.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/neo4j/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/neo4j/system_messages.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/neo4j/tools.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/relevance_extractor_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/retriever_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/utils/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/utils/system_message.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/sql/utils/tools.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/special/table_chat_agent.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/task.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tool_message.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/file_tools.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/google_search_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/metaphor_search_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/orchestration.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/recipient_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/retrieval_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/rewind_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/tools/segment_extract_tool.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/agent/xml_tool_message.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/cachedb/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/cachedb/base.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/cachedb/momento_cachedb.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/cachedb/redis_cachedb.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/base.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/models.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/protoc/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/protoc/embeddings.proto +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/embedding_models/remote_embeds.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/exceptions.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/azure_openai.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/base.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/config.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/mock_lm.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/prompt_formatter/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/prompt_formatter/base.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/language_models/utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/mytypes.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/agent_chats.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/code_parser.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/document_parser.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/para_sentence_split.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/parse_json.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/parser.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/pdf_utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/repo_loader.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/routing.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/spider.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/table_loader.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/url_loader.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/parsing/urls.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/prompts/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/prompts/dialog.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/prompts/prompts_config.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/prompts/templates.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/py.typed +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/pydantic_v1/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/pydantic_v1/main.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/algorithms/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/algorithms/graph.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/configuration.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/constants.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/git_utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/globals.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/logging.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/object_registry.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/output/__init__.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/output/citations.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/output/printing.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/output/status.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/pandas_utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/pydantic_utils.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/system.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/utils/types.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/chromadb.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/lancedb.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/meilisearch.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/momento.py +0 -0
- {langroid-0.40.0 → langroid-0.41.1}/langroid/vector_store/qdrantdb.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.41.1
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
Author-email: Prasad Chalasani <pchalasani@gmail.com>
|
6
6
|
License: MIT
|
@@ -15,6 +15,7 @@ Requires-Dist: colorlog<7.0.0,>=6.7.0
|
|
15
15
|
Requires-Dist: docling<3.0.0,>=2.16.0
|
16
16
|
Requires-Dist: docstring-parser<1.0,>=0.16
|
17
17
|
Requires-Dist: duckduckgo-search<7.0.0,>=6.0.0
|
18
|
+
Requires-Dist: exa-py>=1.8.7
|
18
19
|
Requires-Dist: faker<19.0.0,>=18.9.0
|
19
20
|
Requires-Dist: fakeredis<3.0.0,>=2.12.1
|
20
21
|
Requires-Dist: fire<1.0.0,>=0.5.0
|
@@ -48,6 +49,7 @@ Requires-Dist: redis<6.0.0,>=5.0.1
|
|
48
49
|
Requires-Dist: requests-oauthlib<2.0.0,>=1.3.1
|
49
50
|
Requires-Dist: requests<3.0.0,>=2.31.0
|
50
51
|
Requires-Dist: rich<14.0.0,>=13.3.4
|
52
|
+
Requires-Dist: tavily-python>=0.5.0
|
51
53
|
Requires-Dist: thefuzz<1.0.0,>=0.20.0
|
52
54
|
Requires-Dist: tiktoken<1.0.0,>=0.7.0
|
53
55
|
Requires-Dist: trafilatura<2.0.0,>=1.5.0
|
@@ -106,6 +108,8 @@ Provides-Extra: docling
|
|
106
108
|
Requires-Dist: docling<3.0.0,>=2.16.0; extra == 'docling'
|
107
109
|
Provides-Extra: docx
|
108
110
|
Requires-Dist: python-docx<2.0.0,>=1.1.0; extra == 'docx'
|
111
|
+
Provides-Extra: exa
|
112
|
+
Requires-Dist: exa-py>=1.8.7; extra == 'exa'
|
109
113
|
Provides-Extra: fastembed
|
110
114
|
Requires-Dist: fastembed<0.4.0,>=0.3.1; extra == 'fastembed'
|
111
115
|
Provides-Extra: google-generativeai
|
@@ -141,6 +145,8 @@ Requires-Dist: pymupdf4llm<0.1.0,>=0.0.17; extra == 'pdf-parsers'
|
|
141
145
|
Requires-Dist: pymupdf<2.0.0,>=1.23.3; extra == 'pdf-parsers'
|
142
146
|
Requires-Dist: pypdf>=5.1.0; extra == 'pdf-parsers'
|
143
147
|
Requires-Dist: pytesseract<0.4.0,>=0.3.10; extra == 'pdf-parsers'
|
148
|
+
Provides-Extra: pinecone
|
149
|
+
Requires-Dist: pinecone-client>=5.0.1; extra == 'pinecone'
|
144
150
|
Provides-Extra: postgres
|
145
151
|
Requires-Dist: pgvector>=0.3.6; extra == 'postgres'
|
146
152
|
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'postgres'
|
@@ -154,6 +160,8 @@ Provides-Extra: sql
|
|
154
160
|
Requires-Dist: psycopg2<3.0.0,>=2.9.7; extra == 'sql'
|
155
161
|
Requires-Dist: pymysql<2.0.0,>=1.1.0; extra == 'sql'
|
156
162
|
Requires-Dist: sqlalchemy<3.0.0,>=2.0.19; extra == 'sql'
|
163
|
+
Provides-Extra: tavily
|
164
|
+
Requires-Dist: tavily-python>=0.5.0; extra == 'tavily'
|
157
165
|
Provides-Extra: transformers
|
158
166
|
Requires-Dist: huggingface-hub<1.0.0,>=0.21.2; extra == 'transformers'
|
159
167
|
Requires-Dist: torch<3.0.0,>=2.0.0; extra == 'transformers'
|
@@ -163,6 +171,7 @@ Requires-Dist: unstructured[docx,pdf,pptx]<1.0.0,>=0.16.15; extra == 'unstructur
|
|
163
171
|
Provides-Extra: vecdbs
|
164
172
|
Requires-Dist: chromadb<=0.4.23,>=0.4.21; extra == 'vecdbs'
|
165
173
|
Requires-Dist: lancedb<0.9.0,>=0.8.2; extra == 'vecdbs'
|
174
|
+
Requires-Dist: pinecone-client>=5.0.1; extra == 'vecdbs'
|
166
175
|
Requires-Dist: pyarrow<16.0.0,>=15.0.0; extra == 'vecdbs'
|
167
176
|
Requires-Dist: tantivy<0.22.0,>=0.21.0; extra == 'vecdbs'
|
168
177
|
Requires-Dist: weaviate-client>=4.9.6; extra == 'vecdbs'
|
@@ -0,0 +1,68 @@
|
|
1
|
+
"""
|
2
|
+
A tool to trigger a Exa search for a given query,
|
3
|
+
(https://docs.exa.ai/reference/getting-started)
|
4
|
+
and return the top results with their titles, links, summaries.
|
5
|
+
Since the tool is stateless (i.e. does not need
|
6
|
+
access to agent state), it can be enabled for any agent, without having to define a
|
7
|
+
special method inside the agent: `agent.enable_message(ExaSearchTool)`
|
8
|
+
|
9
|
+
NOTE: To use this tool, you need to:
|
10
|
+
|
11
|
+
* set the EXA_API_KEY environment variables in
|
12
|
+
your `.env` file, e.g. `EXA_API_KEY=your_api_key_here`
|
13
|
+
(Note as of 28 Jan 2023, Metaphor renamed to Exa, so you can also use
|
14
|
+
`EXA_API_KEY=your_api_key_here`)
|
15
|
+
|
16
|
+
* install langroid with the `exa-py` extra, e.g.
|
17
|
+
`pip install langroid[exa]` or `uv pip install langroid[exa]`
|
18
|
+
or `poetry add langroid[exa]` or `uv add langroid[exa]`
|
19
|
+
(it installs the `exa_py` package from pypi).
|
20
|
+
|
21
|
+
For more information, please refer to the official docs:
|
22
|
+
https://exa.ai/
|
23
|
+
"""
|
24
|
+
|
25
|
+
from typing import List, Tuple
|
26
|
+
|
27
|
+
from langroid.agent.tool_message import ToolMessage
|
28
|
+
from langroid.parsing.web_search import exa_search
|
29
|
+
|
30
|
+
|
31
|
+
class ExaSearchTool(ToolMessage):
|
32
|
+
request: str = "exa_search"
|
33
|
+
purpose: str = """
|
34
|
+
To search the web and return up to <num_results>
|
35
|
+
links relevant to the given <query>. When using this tool,
|
36
|
+
ONLY show the required JSON, DO NOT SAY ANYTHING ELSE.
|
37
|
+
Wait for the results of the web search, and then use them to
|
38
|
+
compose your response.
|
39
|
+
"""
|
40
|
+
query: str
|
41
|
+
num_results: int
|
42
|
+
|
43
|
+
def handle(self) -> str:
|
44
|
+
"""
|
45
|
+
Conducts a search using the exa API based on the provided query
|
46
|
+
and number of results by triggering a exa_search.
|
47
|
+
|
48
|
+
Returns:
|
49
|
+
str: A formatted string containing the titles, links, and
|
50
|
+
summaries of each search result, separated by two newlines.
|
51
|
+
"""
|
52
|
+
|
53
|
+
search_results = exa_search(self.query, self.num_results)
|
54
|
+
# return Title, Link, Summary of each result, separated by two newlines
|
55
|
+
results_str = "\n\n".join(str(result) for result in search_results)
|
56
|
+
return f"""
|
57
|
+
BELOW ARE THE RESULTS FROM THE WEB SEARCH. USE THESE TO COMPOSE YOUR RESPONSE:
|
58
|
+
{results_str}
|
59
|
+
"""
|
60
|
+
|
61
|
+
@classmethod
|
62
|
+
def examples(cls) -> List["ToolMessage" | Tuple[str, "ToolMessage"]]:
|
63
|
+
return [
|
64
|
+
cls(
|
65
|
+
query="When was the Llama2 Large Language Model (LLM) released?",
|
66
|
+
num_results=3,
|
67
|
+
),
|
68
|
+
]
|
@@ -0,0 +1,50 @@
|
|
1
|
+
"""
|
2
|
+
A tool to trigger a Tavily search for a given query, and return the top results with
|
3
|
+
their titles, links, summaries. Since the tool is stateless (i.e. does not need
|
4
|
+
access to agent state), it can be enabled for any agent, without having to define a
|
5
|
+
special method inside the agent: `agent.enable_message(TavilySearchTool)`
|
6
|
+
"""
|
7
|
+
|
8
|
+
from typing import List, Tuple
|
9
|
+
|
10
|
+
from langroid.agent.tool_message import ToolMessage
|
11
|
+
from langroid.parsing.web_search import tavily_search
|
12
|
+
|
13
|
+
|
14
|
+
class TavilySearchTool(ToolMessage):
|
15
|
+
request: str = "tavily_search"
|
16
|
+
purpose: str = """
|
17
|
+
To search the web and return up to <num_results>
|
18
|
+
links relevant to the given <query>. When using this tool,
|
19
|
+
ONLY show the required JSON, DO NOT SAY ANYTHING ELSE.
|
20
|
+
Wait for the results of the web search, and then use them to
|
21
|
+
compose your response.
|
22
|
+
"""
|
23
|
+
query: str
|
24
|
+
num_results: int
|
25
|
+
|
26
|
+
def handle(self) -> str:
|
27
|
+
"""
|
28
|
+
Conducts a search using Tavily based on the provided query
|
29
|
+
and number of results by triggering a tavily_search.
|
30
|
+
|
31
|
+
Returns:
|
32
|
+
str: A formatted string containing the titles, links, and
|
33
|
+
summaries of each search result, separated by two newlines.
|
34
|
+
"""
|
35
|
+
search_results = tavily_search(self.query, self.num_results)
|
36
|
+
# return Title, Link, Summary of each result, separated by two newlines
|
37
|
+
results_str = "\n\n".join(str(result) for result in search_results)
|
38
|
+
return f"""
|
39
|
+
BELOW ARE THE RESULTS FROM THE WEB SEARCH. USE THESE TO COMPOSE YOUR RESPONSE:
|
40
|
+
{results_str}
|
41
|
+
"""
|
42
|
+
|
43
|
+
@classmethod
|
44
|
+
def examples(cls) -> List["ToolMessage" | Tuple[str, "ToolMessage"]]:
|
45
|
+
return [
|
46
|
+
cls(
|
47
|
+
query="When was the Llama2 Large Language Model (LLM) released?",
|
48
|
+
num_results=3,
|
49
|
+
),
|
50
|
+
]
|
@@ -320,8 +320,15 @@ MODEL_INFO: Dict[str, ModelInfo] = {
|
|
320
320
|
}
|
321
321
|
|
322
322
|
|
323
|
-
def get_model_info(
|
323
|
+
def get_model_info(
|
324
|
+
model: str | ModelName,
|
325
|
+
fallback_model: str | ModelName = "",
|
326
|
+
) -> ModelInfo:
|
324
327
|
"""Get model information by name or enum value"""
|
328
|
+
return _get_model_info(model) or _get_model_info(fallback_model) or ModelInfo()
|
329
|
+
|
330
|
+
|
331
|
+
def _get_model_info(model: str | ModelName) -> ModelInfo | None:
|
325
332
|
if isinstance(model, str):
|
326
|
-
return MODEL_INFO.get(model)
|
327
|
-
return MODEL_INFO.get(model.value)
|
333
|
+
return MODEL_INFO.get(model)
|
334
|
+
return MODEL_INFO.get(model.value)
|
@@ -468,7 +468,10 @@ class OpenAIGPT(LanguageModel):
|
|
468
468
|
self.supports_strict_tools = self.api_base is None
|
469
469
|
self.supports_json_schema = (
|
470
470
|
self.api_base is None
|
471
|
-
and get_model_info(
|
471
|
+
and get_model_info( # look for family/provider-specific then generic
|
472
|
+
self.chat_model_orig, # e.g. "gemini/gemini-2.0-flash"
|
473
|
+
self.config.chat_model, # e.g. "gemini-2.0-flash"
|
474
|
+
).has_structured_output
|
472
475
|
)
|
473
476
|
|
474
477
|
if settings.chat_model != "":
|
@@ -620,7 +623,10 @@ class OpenAIGPT(LanguageModel):
|
|
620
623
|
def supports_functions_or_tools(self) -> bool:
|
621
624
|
return (
|
622
625
|
self.is_openai_chat_model()
|
623
|
-
and get_model_info(
|
626
|
+
and get_model_info(
|
627
|
+
self.chat_model_orig,
|
628
|
+
self.config.chat_model,
|
629
|
+
).has_tools
|
624
630
|
)
|
625
631
|
|
626
632
|
def is_openai_completion_model(self) -> bool:
|
@@ -644,7 +650,10 @@ class OpenAIGPT(LanguageModel):
|
|
644
650
|
"""
|
645
651
|
List of params that are not supported by the current model
|
646
652
|
"""
|
647
|
-
model_info = get_model_info(
|
653
|
+
model_info = get_model_info(
|
654
|
+
self.chat_model_orig,
|
655
|
+
self.config.chat_model,
|
656
|
+
)
|
648
657
|
unsupported = set(model_info.unsupported_params)
|
649
658
|
for param, model_list in OpenAI_API_ParamInfo().params.items():
|
650
659
|
if (
|
@@ -659,7 +668,10 @@ class OpenAIGPT(LanguageModel):
|
|
659
668
|
Map of param name -> new name for specific models.
|
660
669
|
Currently main troublemaker is o1* series.
|
661
670
|
"""
|
662
|
-
return get_model_info(
|
671
|
+
return get_model_info(
|
672
|
+
self.chat_model_orig,
|
673
|
+
self.config.chat_model,
|
674
|
+
).rename_params
|
663
675
|
|
664
676
|
def chat_context_length(self) -> int:
|
665
677
|
"""
|
@@ -671,7 +683,12 @@ class OpenAIGPT(LanguageModel):
|
|
671
683
|
if self.config.use_completion_for_chat
|
672
684
|
else self.config.chat_model
|
673
685
|
)
|
674
|
-
|
686
|
+
orig_model = (
|
687
|
+
self.config.completion_model
|
688
|
+
if self.config.use_completion_for_chat
|
689
|
+
else self.chat_model_orig
|
690
|
+
)
|
691
|
+
return get_model_info(orig_model, model).context_length
|
675
692
|
|
676
693
|
def completion_context_length(self) -> int:
|
677
694
|
"""
|
@@ -683,7 +700,12 @@ class OpenAIGPT(LanguageModel):
|
|
683
700
|
if self.config.use_chat_for_completion
|
684
701
|
else self.config.completion_model
|
685
702
|
)
|
686
|
-
|
703
|
+
orig_model = (
|
704
|
+
self.chat_model_orig
|
705
|
+
if self.config.use_chat_for_completion
|
706
|
+
else self.config.completion_model
|
707
|
+
)
|
708
|
+
return get_model_info(orig_model, model).context_length
|
687
709
|
|
688
710
|
def chat_cost(self) -> Tuple[float, float]:
|
689
711
|
"""
|
@@ -709,7 +731,10 @@ class OpenAIGPT(LanguageModel):
|
|
709
731
|
return (
|
710
732
|
self.config.stream
|
711
733
|
and settings.stream
|
712
|
-
and get_model_info(
|
734
|
+
and get_model_info(
|
735
|
+
self.chat_model_orig,
|
736
|
+
self.config.chat_model,
|
737
|
+
).allows_streaming
|
713
738
|
and not settings.quiet
|
714
739
|
)
|
715
740
|
|
@@ -118,7 +118,7 @@ def preprocess_text(text: str) -> str:
|
|
118
118
|
str: The preprocessed text.
|
119
119
|
"""
|
120
120
|
# Ensure the NLTK resources are available
|
121
|
-
for resource in ["punkt", "wordnet", "stopwords"]:
|
121
|
+
for resource in ["tokenizers/punkt", "corpora/wordnet", "corpora/stopwords"]:
|
122
122
|
download_nltk_resource(resource)
|
123
123
|
|
124
124
|
# Lowercase the text
|
@@ -28,12 +28,13 @@ def download_nltk_resource(resource: str) -> None:
|
|
28
28
|
try:
|
29
29
|
nltk.data.find(resource)
|
30
30
|
except LookupError:
|
31
|
-
|
31
|
+
model = resource.split("/")[-1]
|
32
|
+
nltk.download(model, quiet=True)
|
32
33
|
|
33
34
|
|
34
35
|
# Download punkt_tab resource at module import
|
35
|
-
download_nltk_resource("punkt_tab")
|
36
|
-
download_nltk_resource("gutenberg")
|
36
|
+
download_nltk_resource("tokenizers/punkt_tab")
|
37
|
+
download_nltk_resource("corpora/gutenberg")
|
37
38
|
|
38
39
|
T = TypeVar("T")
|
39
40
|
|
@@ -16,6 +16,8 @@ from duckduckgo_search import DDGS
|
|
16
16
|
from googleapiclient.discovery import Resource, build
|
17
17
|
from requests.models import Response
|
18
18
|
|
19
|
+
from langroid.exceptions import LangroidImportError
|
20
|
+
|
19
21
|
|
20
22
|
class WebSearchResult:
|
21
23
|
"""
|
@@ -109,13 +111,7 @@ def metaphor_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
|
|
109
111
|
try:
|
110
112
|
from metaphor_python import Metaphor
|
111
113
|
except ImportError:
|
112
|
-
raise
|
113
|
-
"You are attempting to use the `metaphor_python` library;"
|
114
|
-
"To use it, please install langroid with the `metaphor` extra, e.g. "
|
115
|
-
"`pip install langroid[metaphor]` or `poetry add langroid[metaphor]` "
|
116
|
-
"or `uv add langroid[metaphor]`"
|
117
|
-
"(it installs the `metaphor_python` package from pypi)."
|
118
|
-
)
|
114
|
+
raise LangroidImportError("metaphor-python", "metaphor")
|
119
115
|
|
120
116
|
client = Metaphor(api_key=api_key)
|
121
117
|
|
@@ -130,6 +126,53 @@ def metaphor_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
|
|
130
126
|
]
|
131
127
|
|
132
128
|
|
129
|
+
def exa_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
|
130
|
+
"""
|
131
|
+
Method that makes an API call by Exa client that queries
|
132
|
+
the top num_results links that matches the query. Returns a list
|
133
|
+
of WebSearchResult objects.
|
134
|
+
|
135
|
+
Args:
|
136
|
+
query (str): The query body that users wants to make.
|
137
|
+
num_results (int): Number of top matching results that we want
|
138
|
+
to grab
|
139
|
+
"""
|
140
|
+
|
141
|
+
load_dotenv()
|
142
|
+
|
143
|
+
api_key = os.getenv("EXA_API_KEY")
|
144
|
+
if not api_key:
|
145
|
+
raise ValueError(
|
146
|
+
"""
|
147
|
+
EXA_API_KEY environment variables are not set.
|
148
|
+
Please set one of them to your API key, and try again.
|
149
|
+
"""
|
150
|
+
)
|
151
|
+
|
152
|
+
try:
|
153
|
+
from exa_py import Exa
|
154
|
+
except ImportError:
|
155
|
+
raise LangroidImportError("exa-py", "exa")
|
156
|
+
|
157
|
+
client = Exa(api_key=api_key)
|
158
|
+
|
159
|
+
response = client.search(
|
160
|
+
query=query,
|
161
|
+
num_results=num_results,
|
162
|
+
)
|
163
|
+
raw_results = response.results
|
164
|
+
|
165
|
+
return [
|
166
|
+
WebSearchResult(
|
167
|
+
title=result.title or "",
|
168
|
+
link=result.url,
|
169
|
+
max_content_length=3500,
|
170
|
+
max_summary_length=300,
|
171
|
+
)
|
172
|
+
for result in raw_results
|
173
|
+
]
|
174
|
+
|
175
|
+
|
133
176
|
def duckduckgo_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
|
134
177
|
"""
|
135
178
|
Method that makes an API call by DuckDuckGo client that queries
|
@@ -154,3 +197,44 @@ def duckduckgo_search(query: str, num_results: int = 5) -> List[WebSearchResult]
|
|
154
197
|
)
|
155
198
|
for result in search_results
|
156
199
|
]
|
200
|
+
|
201
|
+
|
202
|
+
def tavily_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
|
203
|
+
"""
|
204
|
+
Method that makes an API call to Tavily API that queries
|
205
|
+
the top `num_results` links that match the query. Returns a list
|
206
|
+
of WebSearchResult objects.
|
207
|
+
|
208
|
+
Args:
|
209
|
+
query (str): The query body that users wants to make.
|
210
|
+
num_results (int): Number of top matching results that we want
|
211
|
+
to grab
|
212
|
+
"""
|
213
|
+
|
214
|
+
load_dotenv()
|
215
|
+
|
216
|
+
api_key = os.getenv("TAVILY_API_KEY")
|
217
|
+
if not api_key:
|
218
|
+
raise ValueError(
|
219
|
+
"TAVILY_API_KEY environment variable is not set. "
|
220
|
+
"Please set it to your API key and try again."
|
221
|
+
)
|
222
|
+
|
223
|
+
try:
|
224
|
+
from tavily import TavilyClient
|
225
|
+
except ImportError:
|
226
|
+
raise LangroidImportError("tavily-python", "tavily")
|
227
|
+
|
228
|
+
client = TavilyClient(api_key=api_key)
|
229
|
+
response = client.search(query=query, max_results=num_results)
|
230
|
+
search_results = response["results"]
|
231
|
+
|
232
|
+
return [
|
233
|
+
WebSearchResult(
|
234
|
+
title=result["title"],
|
235
|
+
link=result["url"],
|
236
|
+
max_content_length=3500,
|
237
|
+
max_summary_length=300,
|
238
|
+
)
|
239
|
+
for result in search_results
|
240
|
+
]
|
@@ -23,11 +23,7 @@ try:
|
|
23
23
|
MeiliSearch
|
24
24
|
MeiliSearchConfig
|
25
25
|
__all__.extend(["meilisearch", "MeiliSearch", "MeiliSearchConfig"])
|
26
|
-
except ImportError:
|
27
|
-
pass
|
28
26
|
|
29
|
-
|
30
|
-
try:
|
31
27
|
from . import lancedb
|
32
28
|
from .lancedb import LanceDB, LanceDBConfig
|
33
29
|
|
@@ -35,10 +31,6 @@ try:
|
|
35
31
|
LanceDB
|
36
32
|
LanceDBConfig
|
37
33
|
__all__.extend(["lancedb", "LanceDB", "LanceDBConfig"])
|
38
|
-
except ImportError:
|
39
|
-
pass
|
40
|
-
|
41
|
-
try:
|
42
34
|
from . import chromadb
|
43
35
|
from .chromadb import ChromaDBConfig, ChromaDB
|
44
36
|
|
@@ -46,10 +38,7 @@ try:
|
|
46
38
|
ChromaDB
|
47
39
|
ChromaDBConfig
|
48
40
|
__all__.extend(["chromadb", "ChromaDBConfig", "ChromaDB"])
|
49
|
-
except ImportError:
|
50
|
-
pass
|
51
41
|
|
52
|
-
try:
|
53
42
|
from . import postgres
|
54
43
|
from .postgres import PostgresDB, PostgresDBConfig
|
55
44
|
|
@@ -57,6 +46,7 @@ try:
|
|
57
46
|
PostgresDB
|
58
47
|
PostgresDBConfig
|
59
48
|
__all__.extend(["postgres", "PostgresDB", "PostgresDBConfig"])
|
49
|
+
|
60
50
|
from . import weaviatedb
|
61
51
|
from .weaviatedb import WeaviateDBConfig, WeaviateDB
|
62
52
|
|
@@ -64,5 +54,13 @@ try:
|
|
64
54
|
WeaviateDB
|
65
55
|
WeaviateDBConfig
|
66
56
|
__all__.extend(["weaviatedb", "WeaviateDB", "WeaviateDBConfig"])
|
57
|
+
|
58
|
+
from . import pineconedb
|
59
|
+
from .pineconedb import PineconeDB, PineconeDBConfig
|
60
|
+
|
61
|
+
pineconedb
|
62
|
+
PineconeDB
|
63
|
+
PineconeDBConfig
|
64
|
+
__all__.extend(["pineconedb", "PineconeDB", "PineconeDBConfig"])
|
67
65
|
except ImportError:
|
68
66
|
pass
|
@@ -59,6 +59,7 @@ class VectorStore(ABC):
|
|
59
59
|
from langroid.vector_store.lancedb import LanceDB, LanceDBConfig
|
60
60
|
from langroid.vector_store.meilisearch import MeiliSearch, MeiliSearchConfig
|
61
61
|
from langroid.vector_store.momento import MomentoVI, MomentoVIConfig
|
62
|
+
from langroid.vector_store.pineconedb import PineconeDB, PineconeDBConfig
|
62
63
|
from langroid.vector_store.postgres import PostgresDB, PostgresDBConfig
|
63
64
|
from langroid.vector_store.qdrantdb import QdrantDB, QdrantDBConfig
|
64
65
|
from langroid.vector_store.weaviatedb import WeaviateDB, WeaviateDBConfig
|
@@ -77,6 +78,8 @@ class VectorStore(ABC):
|
|
77
78
|
return PostgresDB(config)
|
78
79
|
elif isinstance(config, WeaviateDBConfig):
|
79
80
|
return WeaviateDB(config)
|
81
|
+
elif isinstance(config, PineconeDBConfig):
|
82
|
+
return PineconeDB(config)
|
80
83
|
|
81
84
|
else:
|
82
85
|
logger.warning(
|