langroid 0.49.0__py3-none-any.whl → 0.49.1__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/language_models/openai_gpt.py +56 -7
- langroid/mytypes.py +25 -1
- langroid/utils/output/citations.py +2 -2
- {langroid-0.49.0.dist-info → langroid-0.49.1.dist-info}/METADATA +1 -1
- {langroid-0.49.0.dist-info → langroid-0.49.1.dist-info}/RECORD +7 -7
- {langroid-0.49.0.dist-info → langroid-0.49.1.dist-info}/WHEEL +0 -0
- {langroid-0.49.0.dist-info → langroid-0.49.1.dist-info}/licenses/LICENSE +0 -0
@@ -1059,8 +1059,8 @@ class OpenAIGPT(LanguageModel):
|
|
1059
1059
|
)
|
1060
1060
|
if is_break:
|
1061
1061
|
break
|
1062
|
-
except Exception:
|
1063
|
-
|
1062
|
+
except Exception as e:
|
1063
|
+
logging.warning("Error while processing stream response: %s", str(e))
|
1064
1064
|
|
1065
1065
|
print("")
|
1066
1066
|
# TODO- get usage info in stream mode (?)
|
@@ -1121,8 +1121,8 @@ class OpenAIGPT(LanguageModel):
|
|
1121
1121
|
)
|
1122
1122
|
if is_break:
|
1123
1123
|
break
|
1124
|
-
except Exception:
|
1125
|
-
|
1124
|
+
except Exception as e:
|
1125
|
+
logging.warning("Error while processing stream response: %s", str(e))
|
1126
1126
|
|
1127
1127
|
print("")
|
1128
1128
|
# TODO- get usage info in stream mode (?)
|
@@ -1703,11 +1703,32 @@ class OpenAIGPT(LanguageModel):
|
|
1703
1703
|
if self.config.litellm and settings.debug:
|
1704
1704
|
kwargs["logger_fn"] = litellm_logging_fn
|
1705
1705
|
result = completion_call(**kwargs)
|
1706
|
-
|
1707
|
-
|
1706
|
+
|
1707
|
+
if self.get_stream():
|
1708
|
+
# If streaming, cannot cache result
|
1708
1709
|
# since it is a generator. Instead,
|
1709
1710
|
# we hold on to the hashed_key and
|
1710
1711
|
# cache the result later
|
1712
|
+
|
1713
|
+
# Test if this is a stream with an exception by
|
1714
|
+
# trying to get first chunk: Some providers like LiteLLM
|
1715
|
+
# produce a valid stream object `result` instead of throwing a
|
1716
|
+
# rate-limit error, and if we don't catch it here,
|
1717
|
+
# we end up returning an empty response and not
|
1718
|
+
# using the retry mechanism in the decorator.
|
1719
|
+
try:
|
1720
|
+
# try to get the first chunk to check for errors
|
1721
|
+
test_iter = iter(result)
|
1722
|
+
first_chunk = next(test_iter)
|
1723
|
+
# If we get here without error, recreate the stream
|
1724
|
+
result = chain([first_chunk], test_iter)
|
1725
|
+
except StopIteration:
|
1726
|
+
# Empty stream is fine
|
1727
|
+
pass
|
1728
|
+
except Exception as e:
|
1729
|
+
# Propagate any errors in the stream
|
1730
|
+
raise e
|
1731
|
+
else:
|
1711
1732
|
self._cache_store(hashed_key, result.model_dump())
|
1712
1733
|
return cached, hashed_key, result
|
1713
1734
|
|
@@ -1734,7 +1755,35 @@ class OpenAIGPT(LanguageModel):
|
|
1734
1755
|
kwargs["logger_fn"] = litellm_logging_fn
|
1735
1756
|
# If it's not in the cache, call the API
|
1736
1757
|
result = await acompletion_call(**kwargs)
|
1737
|
-
if
|
1758
|
+
if self.get_stream():
|
1759
|
+
try:
|
1760
|
+
# Try to peek at the first chunk to immediately catch any errors
|
1761
|
+
# Store the original result (the stream)
|
1762
|
+
original_stream = result
|
1763
|
+
|
1764
|
+
# Manually create and advance the iterator to check for errors
|
1765
|
+
stream_iter = original_stream.__aiter__()
|
1766
|
+
try:
|
1767
|
+
# This will raise an exception if the stream is invalid
|
1768
|
+
first_chunk = await anext(stream_iter)
|
1769
|
+
|
1770
|
+
# If we reach here, the stream started successfully
|
1771
|
+
# Now recreate a fresh stream from the original API result
|
1772
|
+
# Otherwise, return a new stream that yields the first chunk
|
1773
|
+
# and remaining items
|
1774
|
+
async def combined_stream(): # type: ignore
|
1775
|
+
yield first_chunk
|
1776
|
+
async for chunk in stream_iter:
|
1777
|
+
yield chunk
|
1778
|
+
|
1779
|
+
result = combined_stream() # type: ignore
|
1780
|
+
except StopAsyncIteration:
|
1781
|
+
# Empty stream is normal - nothing to do
|
1782
|
+
pass
|
1783
|
+
except Exception as e:
|
1784
|
+
# Any exception here should be raised to trigger the retry mechanism
|
1785
|
+
raise e
|
1786
|
+
else:
|
1738
1787
|
self._cache_store(hashed_key, result.model_dump())
|
1739
1788
|
return cached, hashed_key, result
|
1740
1789
|
|
langroid/mytypes.py
CHANGED
@@ -65,6 +65,30 @@ class DocMetaData(BaseModel):
|
|
65
65
|
|
66
66
|
return original_dict
|
67
67
|
|
68
|
+
def __str__(self) -> str:
|
69
|
+
title_str = (
|
70
|
+
""
|
71
|
+
if "unknown" in self.title.lower() or self.title.strip() == ""
|
72
|
+
else f"Title: {self.title}"
|
73
|
+
)
|
74
|
+
date_str = ""
|
75
|
+
if (
|
76
|
+
"unknown" not in self.published_date.lower()
|
77
|
+
and self.published_date.strip() != ""
|
78
|
+
):
|
79
|
+
try:
|
80
|
+
from dateutil import parser
|
81
|
+
|
82
|
+
# Try to parse the date string
|
83
|
+
date_obj = parser.parse(self.published_date)
|
84
|
+
# Format to include only the date part (year-month-day)
|
85
|
+
date_only = date_obj.strftime("%Y-%m-%d")
|
86
|
+
date_str = f"Date: {date_only}"
|
87
|
+
except (ValueError, ImportError, TypeError):
|
88
|
+
# If parsing fails, just use the original date
|
89
|
+
date_str = f"Date: {self.published_date}"
|
90
|
+
return f"{self.source} {title_str} {date_str}".strip()
|
91
|
+
|
68
92
|
class Config:
|
69
93
|
extra = Extra.allow
|
70
94
|
|
@@ -93,7 +117,7 @@ class Document(BaseModel):
|
|
93
117
|
return dedent(
|
94
118
|
f"""
|
95
119
|
CONTENT: {self.content}
|
96
|
-
SOURCE:{self.metadata
|
120
|
+
SOURCE:{str(self.metadata)}
|
97
121
|
"""
|
98
122
|
)
|
99
123
|
|
@@ -97,7 +97,7 @@ def format_cited_references(
|
|
97
97
|
# source and content for each citation
|
98
98
|
full_citations_str = "\n".join(
|
99
99
|
[
|
100
|
-
f"[^{c}] {passages[c-1].metadata
|
100
|
+
f"[^{c}] {str(passages[c-1].metadata)}"
|
101
101
|
f"\n{format_footnote_text(passages[c-1].content)}"
|
102
102
|
for c in good_citations
|
103
103
|
]
|
@@ -105,6 +105,6 @@ def format_cited_references(
|
|
105
105
|
|
106
106
|
# source for each citation
|
107
107
|
citations_str = "\n".join(
|
108
|
-
[f"[^{c}] {passages[c-1].metadata
|
108
|
+
[f"[^{c}] {str(passages[c-1].metadata)}" for c in good_citations]
|
109
109
|
)
|
110
110
|
return full_citations_str, citations_str
|
@@ -1,6 +1,6 @@
|
|
1
1
|
langroid/__init__.py,sha256=z_fCOLQJPOw3LLRPBlFB5-2HyCjpPgQa4m4iY5Fvb8Y,1800
|
2
2
|
langroid/exceptions.py,sha256=OPjece_8cwg94DLPcOGA1ddzy5bGh65pxzcHMnssTz8,2995
|
3
|
-
langroid/mytypes.py,sha256=
|
3
|
+
langroid/mytypes.py,sha256=ezj_6FFDkJZiVx1SS9eJvh23dH76Ti7mJbePi8ldkAI,3919
|
4
4
|
langroid/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,786
|
6
6
|
langroid/agent/base.py,sha256=U-UjdpxIFqkzRIB5-LYwHrhMSNI3sDbfnNRqIhrtsyI,79568
|
@@ -72,7 +72,7 @@ langroid/language_models/base.py,sha256=mDYmFCBCLdq8_Uvws4MiewwEgcOCP8Qb0e5yUXr3
|
|
72
72
|
langroid/language_models/config.py,sha256=9Q8wk5a7RQr8LGMT_0WkpjY8S4ywK06SalVRjXlfCiI,378
|
73
73
|
langroid/language_models/mock_lm.py,sha256=5BgHKDVRWFbUwDT_PFgTZXz9-k8wJSA2e3PZmyDgQ1k,4022
|
74
74
|
langroid/language_models/model_info.py,sha256=tfBBxL0iUf2mVN6CjcvqflzFUVg2oZqOJZexZ8jHTYA,12216
|
75
|
-
langroid/language_models/openai_gpt.py,sha256=
|
75
|
+
langroid/language_models/openai_gpt.py,sha256=M_jp97Ksp5r3U-d0jCLPLjVmn7IK1mC8Ry4t7k6A5tc,82906
|
76
76
|
langroid/language_models/utils.py,sha256=L4_CbihDMTGcsg0TOG1Yd5JFEto46--h7CX_14m89sQ,5016
|
77
77
|
langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
|
78
78
|
langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
|
@@ -115,7 +115,7 @@ langroid/utils/types.py,sha256=-BvyIf_LmAJ5jR9NC7S4CSVNEr3XayAaxJ5o0TiIej0,2992
|
|
115
115
|
langroid/utils/algorithms/__init__.py,sha256=WylYoZymA0fnzpB4vrsH_0n7WsoLhmuZq8qxsOCjUpM,41
|
116
116
|
langroid/utils/algorithms/graph.py,sha256=JbdpPnUOhw4-D6O7ou101JLA3xPCD0Lr3qaPoFCaRfo,2866
|
117
117
|
langroid/utils/output/__init__.py,sha256=7P0f--4IZneNsTxXY5fd6d6iW-CeVe-KSsl-87sbBPc,340
|
118
|
-
langroid/utils/output/citations.py,sha256=
|
118
|
+
langroid/utils/output/citations.py,sha256=cEiqSH7DJ5q4M2z_6eFjCj9Ohnf68i6sivjeRFuFAtk,3862
|
119
119
|
langroid/utils/output/printing.py,sha256=yzPJZN-8_jyOJmI9N_oLwEDfjMwVgk3IDiwnZ4eK_AE,2962
|
120
120
|
langroid/utils/output/status.py,sha256=rzbE7mDJcgNNvdtylCseQcPGCGghtJvVq3lB-OPJ49E,1049
|
121
121
|
langroid/vector_store/__init__.py,sha256=8ktJUVsVUoc7FMmkUFpFBZu7VMWUqQY9zpm4kEJ8yTs,1537
|
@@ -127,7 +127,7 @@ langroid/vector_store/pineconedb.py,sha256=otxXZNaBKb9f_H75HTaU3lMHiaR2NUp5MqwLZ
|
|
127
127
|
langroid/vector_store/postgres.py,sha256=wHPtIi2qM4fhO4pMQr95pz1ZCe7dTb2hxl4VYspGZoA,16104
|
128
128
|
langroid/vector_store/qdrantdb.py,sha256=O6dSBoDZ0jzfeVBd7LLvsXu083xs2fxXtPa9gGX3JX4,18443
|
129
129
|
langroid/vector_store/weaviatedb.py,sha256=Yn8pg139gOy3zkaPfoTbMXEEBCiLiYa1MU5d_3UA1K4,11847
|
130
|
-
langroid-0.49.
|
131
|
-
langroid-0.49.
|
132
|
-
langroid-0.49.
|
133
|
-
langroid-0.49.
|
130
|
+
langroid-0.49.1.dist-info/METADATA,sha256=a2cArSN5YfRq4GRH37MkO6h-fvXbXEFkoo-qDMyVTzA,63606
|
131
|
+
langroid-0.49.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
132
|
+
langroid-0.49.1.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
133
|
+
langroid-0.49.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|