langroid 0.39.2__py3-none-any.whl → 0.39.4__py3-none-any.whl
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/agent/special/doc_chat_agent.py +4 -12
- langroid/language_models/model_info.py +18 -0
- langroid/language_models/openai_gpt.py +31 -3
- langroid/parsing/urls.py +7 -2
- langroid/utils/output/citations.py +31 -1
- langroid/utils/system.py +1 -5
- langroid/vector_store/weaviatedb.py +25 -12
- {langroid-0.39.2.dist-info → langroid-0.39.4.dist-info}/METADATA +2 -2
- {langroid-0.39.2.dist-info → langroid-0.39.4.dist-info}/RECORD +11 -11
- {langroid-0.39.2.dist-info → langroid-0.39.4.dist-info}/WHEEL +0 -0
- {langroid-0.39.2.dist-info → langroid-0.39.4.dist-info}/licenses/LICENSE +0 -0
@@ -58,7 +58,7 @@ from langroid.utils.object_registry import ObjectRegistry
|
|
58
58
|
from langroid.utils.output import show_if_debug, status
|
59
59
|
from langroid.utils.output.citations import (
|
60
60
|
extract_markdown_references,
|
61
|
-
|
61
|
+
format_cited_references,
|
62
62
|
)
|
63
63
|
from langroid.utils.pydantic_utils import dataframe_to_documents, extract_fields
|
64
64
|
from langroid.vector_store.base import VectorStore, VectorStoreConfig
|
@@ -859,18 +859,10 @@ class DocChatAgent(ChatAgent):
|
|
859
859
|
final_answer = answer_doc.content.strip()
|
860
860
|
show_if_debug(final_answer, "SUMMARIZE_RESPONSE= ")
|
861
861
|
|
862
|
+
# extract references like [^2], [^3], etc. from the final answer
|
862
863
|
citations = extract_markdown_references(final_answer)
|
863
|
-
|
864
|
-
citations_str =
|
865
|
-
if len(citations) > 0:
|
866
|
-
# append [i] source, content for each citation
|
867
|
-
citations_str = "\n".join(
|
868
|
-
[
|
869
|
-
f"[^{c}] {passages[c-1].metadata.source}"
|
870
|
-
f"\n{format_footnote_text(passages[c-1].content)}"
|
871
|
-
for c in citations
|
872
|
-
]
|
873
|
-
)
|
864
|
+
# format the cited references as a string suitable for markdown footnote
|
865
|
+
citations_str = format_cited_references(citations, passages)
|
874
866
|
|
875
867
|
return ChatDocument(
|
876
868
|
content=final_answer, # does not contain citations
|
@@ -54,6 +54,7 @@ class DeepSeekModel(ModelName):
|
|
54
54
|
|
55
55
|
DEEPSEEK = "deepseek/deepseek-chat"
|
56
56
|
DEEPSEEK_R1 = "deepseek/deepseek-reasoner"
|
57
|
+
OPENROUTER_DEEPSEEK_R1 = "openrouter/deepseek/deepseek-r1"
|
57
58
|
|
58
59
|
|
59
60
|
class GeminiModel(ModelName):
|
@@ -66,6 +67,23 @@ class GeminiModel(ModelName):
|
|
66
67
|
GEMINI_2_FLASH_THINKING = "gemini/gemini-2.0-flash-thinking-exp"
|
67
68
|
|
68
69
|
|
70
|
+
class OpenAI_API_ParamInfo(BaseModel):
|
71
|
+
"""
|
72
|
+
Parameters exclusive to some models, when using OpenAI API
|
73
|
+
"""
|
74
|
+
|
75
|
+
params: Dict[str, List[str]] = dict(
|
76
|
+
reasoning_effort=[
|
77
|
+
OpenAIChatModel.O3_MINI.value,
|
78
|
+
],
|
79
|
+
)
|
80
|
+
extra_parameters: Dict[str, List[str]] = dict(
|
81
|
+
include_reasoning=[
|
82
|
+
DeepSeekModel.OPENROUTER_DEEPSEEK_R1.value,
|
83
|
+
]
|
84
|
+
)
|
85
|
+
|
86
|
+
|
69
87
|
class ModelInfo(BaseModel):
|
70
88
|
"""
|
71
89
|
Consolidated information about LLM, related to capacity, cost and API
|
@@ -49,6 +49,7 @@ from langroid.language_models.config import HFPromptFormatterConfig
|
|
49
49
|
from langroid.language_models.model_info import (
|
50
50
|
DeepSeekModel,
|
51
51
|
GeminiModel,
|
52
|
+
OpenAI_API_ParamInfo,
|
52
53
|
get_model_info,
|
53
54
|
)
|
54
55
|
from langroid.language_models.model_info import (
|
@@ -203,6 +204,7 @@ class OpenAICallParams(BaseModel):
|
|
203
204
|
stop: str | List[str] | None = None # (list of) stop sequence(s)
|
204
205
|
seed: int | None = 42
|
205
206
|
user: str | None = None # user id for tracking
|
207
|
+
extra_body: Dict[str, Any] | None = None # additional params for API request body
|
206
208
|
|
207
209
|
def to_dict_exclude_none(self) -> Dict[str, Any]:
|
208
210
|
return {k: v for k, v in self.dict().items() if v is not None}
|
@@ -642,7 +644,15 @@ class OpenAIGPT(LanguageModel):
|
|
642
644
|
"""
|
643
645
|
List of params that are not supported by the current model
|
644
646
|
"""
|
645
|
-
|
647
|
+
model_info = get_model_info(self.config.chat_model)
|
648
|
+
unsupported = set(model_info.unsupported_params)
|
649
|
+
for param, model_list in OpenAI_API_ParamInfo().params.items():
|
650
|
+
if (
|
651
|
+
self.config.chat_model not in model_list
|
652
|
+
and self.chat_model_orig not in model_list
|
653
|
+
):
|
654
|
+
unsupported.add(param)
|
655
|
+
return list(unsupported)
|
646
656
|
|
647
657
|
def rename_params(self) -> Dict[str, str]:
|
648
658
|
"""
|
@@ -739,7 +749,10 @@ class OpenAIGPT(LanguageModel):
|
|
739
749
|
delta = choices[0].get("delta", {})
|
740
750
|
# capture both content and reasoning_content
|
741
751
|
event_text = delta.get("content", "")
|
742
|
-
event_reasoning = delta.get(
|
752
|
+
event_reasoning = delta.get(
|
753
|
+
"reasoning_content",
|
754
|
+
delta.get("reasoning", ""),
|
755
|
+
)
|
743
756
|
if "function_call" in delta and delta["function_call"] is not None:
|
744
757
|
if "name" in delta["function_call"]:
|
745
758
|
event_fn_name = delta["function_call"]["name"]
|
@@ -861,7 +874,10 @@ class OpenAIGPT(LanguageModel):
|
|
861
874
|
if chat:
|
862
875
|
delta = choices[0].get("delta", {})
|
863
876
|
event_text = delta.get("content", "")
|
864
|
-
event_reasoning = delta.get(
|
877
|
+
event_reasoning = delta.get(
|
878
|
+
"reasoning_content",
|
879
|
+
delta.get("reasoning", ""),
|
880
|
+
)
|
865
881
|
if "function_call" in delta and delta["function_call"] is not None:
|
866
882
|
if "name" in delta["function_call"]:
|
867
883
|
event_fn_name = delta["function_call"]["name"]
|
@@ -1757,6 +1773,18 @@ class OpenAIGPT(LanguageModel):
|
|
1757
1773
|
for old_param, new_param in param_rename_map.items():
|
1758
1774
|
if old_param in args:
|
1759
1775
|
args[new_param] = args.pop(old_param)
|
1776
|
+
|
1777
|
+
# finally, get rid of extra_body params exclusive to certain models
|
1778
|
+
extra_params = args.get("extra_body", {})
|
1779
|
+
if extra_params:
|
1780
|
+
for param, model_list in OpenAI_API_ParamInfo().extra_parameters.items():
|
1781
|
+
if (
|
1782
|
+
self.config.chat_model not in model_list
|
1783
|
+
and self.chat_model_orig not in model_list
|
1784
|
+
):
|
1785
|
+
extra_params.pop(param, None)
|
1786
|
+
if extra_params:
|
1787
|
+
args["extra_body"] = extra_params
|
1760
1788
|
return args
|
1761
1789
|
|
1762
1790
|
def _process_chat_completion_response(
|
langroid/parsing/urls.py
CHANGED
@@ -221,10 +221,15 @@ def find_urls(
|
|
221
221
|
response = requests.get(url, timeout=5)
|
222
222
|
response.raise_for_status()
|
223
223
|
soup = BeautifulSoup(response.text, "html.parser")
|
224
|
-
links = [
|
224
|
+
links = [
|
225
|
+
urljoin(url, a["href"]) # type: ignore
|
226
|
+
for a in soup.find_all("a", href=True)
|
227
|
+
]
|
225
228
|
|
226
229
|
# Defrag links: discard links that are to portions of same page
|
227
|
-
defragged_links = list(
|
230
|
+
defragged_links = list(
|
231
|
+
set(urldefrag(link).url for link in links) # type: ignore
|
232
|
+
)
|
228
233
|
|
229
234
|
# Filter links based on domain matching requirement
|
230
235
|
domain_matching_links = [
|
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
from typing import List
|
2
|
+
|
3
|
+
from langroid.mytypes import Document
|
4
|
+
|
5
|
+
|
6
|
+
def extract_markdown_references(md_string: str) -> List[int]:
|
2
7
|
"""
|
3
8
|
Extracts markdown references (e.g., [^1], [^2]) from a string and returns
|
4
9
|
them as a sorted list of integers.
|
@@ -59,3 +64,28 @@ def format_footnote_text(content: str, width: int = 0) -> str:
|
|
59
64
|
|
60
65
|
# Join them with newline so we preserve the paragraph/blank line structure
|
61
66
|
return "\n".join(output_lines)
|
67
|
+
|
68
|
+
|
69
|
+
def format_cited_references(citations: List[int], passages: list[Document]) -> str:
|
70
|
+
"""
|
71
|
+
Given a list of (integer) citations, and a list of passages, return a string
|
72
|
+
that can be added as a footer to the main text, to show sources cited.
|
73
|
+
|
74
|
+
Args:
|
75
|
+
citations (list[int]): list of citations, presumably from main text
|
76
|
+
passages (list[Document]): list of passages (Document objects)
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
str: formatted string of citations for footnote in markdown
|
80
|
+
"""
|
81
|
+
citations_str = ""
|
82
|
+
if len(citations) > 0:
|
83
|
+
# append [i] source, content for each citation
|
84
|
+
citations_str = "\n".join(
|
85
|
+
[
|
86
|
+
f"[^{c}] {passages[c-1].metadata.source}"
|
87
|
+
f"\n{format_footnote_text(passages[c-1].content)}"
|
88
|
+
for c in citations
|
89
|
+
]
|
90
|
+
)
|
91
|
+
return citations_str
|
langroid/utils/system.py
CHANGED
@@ -14,11 +14,7 @@ from typing import Any, Literal
|
|
14
14
|
|
15
15
|
logger = logging.getLogger(__name__)
|
16
16
|
|
17
|
-
DELETION_ALLOWED_PATHS = [
|
18
|
-
".qdrant",
|
19
|
-
".chroma",
|
20
|
-
".lancedb",
|
21
|
-
]
|
17
|
+
DELETION_ALLOWED_PATHS = [".qdrant", ".chroma", ".lancedb", ".weaviate"]
|
22
18
|
|
23
19
|
|
24
20
|
def pydantic_major_version() -> int:
|
@@ -32,6 +32,8 @@ class WeaviateDBConfig(VectorStoreConfig):
|
|
32
32
|
collection_name: str | None = "temp"
|
33
33
|
embedding: EmbeddingModelsConfig = OpenAIEmbeddingsConfig()
|
34
34
|
distance: str = VectorDistances.COSINE
|
35
|
+
cloud: bool = False
|
36
|
+
storage_path: str = ".weaviate_embedded/data"
|
35
37
|
|
36
38
|
|
37
39
|
class WeaviateDB(VectorStore):
|
@@ -39,19 +41,25 @@ class WeaviateDB(VectorStore):
|
|
39
41
|
super().__init__(config)
|
40
42
|
self.config: WeaviateDBConfig = config
|
41
43
|
load_dotenv()
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
raise ValueError(
|
46
|
-
"""WEAVIATE_API_KEY, WEAVIATE_API_URL env variable must be set to use
|
47
|
-
WeaviateDB in cloud mode. Please set these values
|
48
|
-
in your .env file.
|
49
|
-
"""
|
44
|
+
if not self.config.cloud:
|
45
|
+
self.client = weaviate.connect_to_embedded(
|
46
|
+
version="latest", persistence_data_path=self.config.storage_path
|
50
47
|
)
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
else: # Cloud mode
|
49
|
+
key = os.getenv("WEAVIATE_API_KEY")
|
50
|
+
url = os.getenv("WEAVIATE_API_URL")
|
51
|
+
if url is None or key is None:
|
52
|
+
raise ValueError(
|
53
|
+
"""WEAVIATE_API_KEY, WEAVIATE_API_URL env variables must be set to
|
54
|
+
use WeaviateDB in cloud mode. Please set these values
|
55
|
+
in your .env file.
|
56
|
+
"""
|
57
|
+
)
|
58
|
+
self.client = weaviate.connect_to_weaviate_cloud(
|
59
|
+
cluster_url=url,
|
60
|
+
auth_credentials=Auth.api_key(key),
|
61
|
+
)
|
62
|
+
|
55
63
|
if config.collection_name is not None:
|
56
64
|
WeaviateDB.validate_and_format_collection_name(config.collection_name)
|
57
65
|
|
@@ -267,3 +275,8 @@ class WeaviateDB(VectorStore):
|
|
267
275
|
)
|
268
276
|
|
269
277
|
return formatted_name
|
278
|
+
|
279
|
+
def __del__(self) -> None:
|
280
|
+
# Gracefully close the connection with local client
|
281
|
+
if not self.config.cloud:
|
282
|
+
self.client.close()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.39.
|
3
|
+
Version: 0.39.4
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
Author-email: Prasad Chalasani <pchalasani@gmail.com>
|
6
6
|
License: MIT
|
@@ -30,7 +30,7 @@ Requires-Dist: lxml<5.0.0,>=4.9.3
|
|
30
30
|
Requires-Dist: nest-asyncio<2.0.0,>=1.6.0
|
31
31
|
Requires-Dist: nltk<4.0.0,>=3.8.2
|
32
32
|
Requires-Dist: onnxruntime<2.0.0,>=1.16.1
|
33
|
-
Requires-Dist: openai<2.0.0,>=1.
|
33
|
+
Requires-Dist: openai<2.0.0,>=1.61.1
|
34
34
|
Requires-Dist: pandas<3.0.0,>=2.0.3
|
35
35
|
Requires-Dist: prettytable<4.0.0,>=3.8.0
|
36
36
|
Requires-Dist: pydantic<3.0.0,>=1
|
@@ -14,7 +14,7 @@ langroid/agent/xml_tool_message.py,sha256=6SshYZJKIfi4mkE-gIoSwjkEYekQ8GwcSiCv7a
|
|
14
14
|
langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
langroid/agent/callbacks/chainlit.py,sha256=RH8qUXaZE5o2WQz3WJQ1SdFtASGlxWCA6_HYz_3meDQ,20822
|
16
16
|
langroid/agent/special/__init__.py,sha256=gik_Xtm_zV7U9s30Mn8UX3Gyuy4jTjQe9zjiE3HWmEo,1273
|
17
|
-
langroid/agent/special/doc_chat_agent.py,sha256=
|
17
|
+
langroid/agent/special/doc_chat_agent.py,sha256=Q16HOg6MXa26szTO29OOIv1kv8QfuUjxLlLOP3eqZvA,64539
|
18
18
|
langroid/agent/special/lance_doc_chat_agent.py,sha256=s8xoRs0gGaFtDYFUSIRchsgDVbS5Q3C2b2mr3V1Fd-Q,10419
|
19
19
|
langroid/agent/special/lance_tools.py,sha256=qS8x4wi8mrqfbYV2ztFzrcxyhHQ0ZWOc-zkYiH7awj0,2105
|
20
20
|
langroid/agent/special/relevance_extractor_agent.py,sha256=zIx8GUdVo1aGW6ASla0NPQjYYIpmriK_TYMijqAx3F8,4796
|
@@ -69,8 +69,8 @@ langroid/language_models/azure_openai.py,sha256=zNQzzsERxNestq-hFfQZbvTzK43G2vjR
|
|
69
69
|
langroid/language_models/base.py,sha256=mN6HAjLgF2xpHObz5uPZ3JDID7jdTiRLEkoGgGrqLM8,25177
|
70
70
|
langroid/language_models/config.py,sha256=9Q8wk5a7RQr8LGMT_0WkpjY8S4ywK06SalVRjXlfCiI,378
|
71
71
|
langroid/language_models/mock_lm.py,sha256=5BgHKDVRWFbUwDT_PFgTZXz9-k8wJSA2e3PZmyDgQ1k,4022
|
72
|
-
langroid/language_models/model_info.py,sha256=
|
73
|
-
langroid/language_models/openai_gpt.py,sha256=
|
72
|
+
langroid/language_models/model_info.py,sha256=6B8Cey0eX8vR6wAc8-Cb1Gj7pazN01A-FjWTYpG0QFg,11111
|
73
|
+
langroid/language_models/openai_gpt.py,sha256=3_kC1o4eY-VnCPAgP8JoIm-fOUnCzHEATymV8WG_ecw,77876
|
74
74
|
langroid/language_models/utils.py,sha256=L4_CbihDMTGcsg0TOG1Yd5JFEto46--h7CX_14m89sQ,5016
|
75
75
|
langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
|
76
76
|
langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
|
@@ -90,7 +90,7 @@ langroid/parsing/search.py,sha256=M1swZfZEMEsalmTwVCkql3DzBNBemky7pWt0PrcwGdQ,97
|
|
90
90
|
langroid/parsing/spider.py,sha256=hAVM6wxh1pQ0EN4tI5wMBtAjIk0T-xnpi-ZUzWybhos,3258
|
91
91
|
langroid/parsing/table_loader.py,sha256=qNM4obT_0Y4tjrxNBCNUYjKQ9oETCZ7FbolKBTcz-GM,3410
|
92
92
|
langroid/parsing/url_loader.py,sha256=JK48KktLRDBfjrt4nsUfy92M6yGdEeicAqOum2MdULM,4656
|
93
|
-
langroid/parsing/urls.py,sha256=
|
93
|
+
langroid/parsing/urls.py,sha256=86omykgxo4hg2jyF10Ef-FJa9n6MgXdSXy2mImqgo5c,8076
|
94
94
|
langroid/parsing/utils.py,sha256=YrV2GNL4EOBGknA4AClPGdJ4S5B31radrt-Ou8OAKoU,12749
|
95
95
|
langroid/parsing/web_search.py,sha256=8rW8EI3tyHITaB2l9MT_6yLMeQfo8y-Ih-8N2v2uMpk,4931
|
96
96
|
langroid/prompts/__init__.py,sha256=RW11vK6jiLPuaUh4GpeFvstti73gkm8_rDMtrbo2YsU,142
|
@@ -108,12 +108,12 @@ langroid/utils/logging.py,sha256=mwxHimq1wtVQ64PvDyfJJ7Upj-rjHLNHgx8EC2wClvo,402
|
|
108
108
|
langroid/utils/object_registry.py,sha256=iPz9GHzvmCeVoidB3JdAMEKcxJEqTdUr0otQEexDZ5s,2100
|
109
109
|
langroid/utils/pandas_utils.py,sha256=UctS986Jtl_MvU5rA7-GfrjEHXP7MNu8ePhepv0bTn0,755
|
110
110
|
langroid/utils/pydantic_utils.py,sha256=R7Ps8VP56-eSo-LYHWllFo-SJ2zDmdItuuYpUq2gGJ8,20854
|
111
|
-
langroid/utils/system.py,sha256=
|
111
|
+
langroid/utils/system.py,sha256=cJqDgOf9mM82l1GyUeQQdEYAwepYXQwtpJU8Xrz0-MA,8453
|
112
112
|
langroid/utils/types.py,sha256=4GrOnU3HLWh-UwaUPp7LlB3V413q3K5OSzc0ggDoQ6A,2510
|
113
113
|
langroid/utils/algorithms/__init__.py,sha256=WylYoZymA0fnzpB4vrsH_0n7WsoLhmuZq8qxsOCjUpM,41
|
114
114
|
langroid/utils/algorithms/graph.py,sha256=JbdpPnUOhw4-D6O7ou101JLA3xPCD0Lr3qaPoFCaRfo,2866
|
115
115
|
langroid/utils/output/__init__.py,sha256=7P0f--4IZneNsTxXY5fd6d6iW-CeVe-KSsl-87sbBPc,340
|
116
|
-
langroid/utils/output/citations.py,sha256=
|
116
|
+
langroid/utils/output/citations.py,sha256=9T69O_N6mxPQjQ-qC1vKS8_kyg1z5hDQXMhBsA45xkk,3147
|
117
117
|
langroid/utils/output/printing.py,sha256=yzPJZN-8_jyOJmI9N_oLwEDfjMwVgk3IDiwnZ4eK_AE,2962
|
118
118
|
langroid/utils/output/status.py,sha256=rzbE7mDJcgNNvdtylCseQcPGCGghtJvVq3lB-OPJ49E,1049
|
119
119
|
langroid/vector_store/__init__.py,sha256=BcoOm1tG3y0EqjkIGmMOHkY9iTUhDHgyruknWDKgqIg,1214
|
@@ -123,8 +123,8 @@ langroid/vector_store/lancedb.py,sha256=Qd20gKjWozPWfW5-D66J6U8dSrJo1yl-maj6s1lb
|
|
123
123
|
langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3HmhHQICXLs,11663
|
124
124
|
langroid/vector_store/momento.py,sha256=xOaU7Hlyyn_5ihb0ARS5JHtmrKrTCt2IdRA-ioMM5ek,10307
|
125
125
|
langroid/vector_store/qdrantdb.py,sha256=v7TAsIoj_vxeKDYS9tpwJLBZA8fuTweTYxHo0X_uawM,17949
|
126
|
-
langroid/vector_store/weaviatedb.py,sha256=
|
127
|
-
langroid-0.39.
|
128
|
-
langroid-0.39.
|
129
|
-
langroid-0.39.
|
130
|
-
langroid-0.39.
|
126
|
+
langroid/vector_store/weaviatedb.py,sha256=cMg9kqJXlD1WURs6QivHvwausCyLYGr4mOK2v9uYkhw,11105
|
127
|
+
langroid-0.39.4.dist-info/METADATA,sha256=kmZh0J5DvAdv2oNUiCAa3e1SfQ7Le0-egld9zjhVMAw,60634
|
128
|
+
langroid-0.39.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
129
|
+
langroid-0.39.4.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
130
|
+
langroid-0.39.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|