langroid 0.1.24__py3-none-any.whl → 0.1.26__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/cachedb/redis_cachedb.py +6 -6
- langroid/vector_store/qdrantdb.py +12 -10
- {langroid-0.1.24.dist-info → langroid-0.1.26.dist-info}/METADATA +93 -68
- {langroid-0.1.24.dist-info → langroid-0.1.26.dist-info}/RECORD +6 -6
- {langroid-0.1.24.dist-info → langroid-0.1.26.dist-info}/LICENSE +0 -0
- {langroid-0.1.24.dist-info → langroid-0.1.26.dist-info}/WHEEL +0 -0
@@ -17,8 +17,6 @@ class RedisCacheConfig(BaseModel):
|
|
17
17
|
"""Configuration model for RedisCache."""
|
18
18
|
|
19
19
|
fake: bool = False
|
20
|
-
hostname: str = "redis-11524.c251.east-us-mz.azure.cloud.redislabs.com"
|
21
|
-
port: int = 11524
|
22
20
|
|
23
21
|
|
24
22
|
class RedisCache(CacheDB):
|
@@ -38,16 +36,18 @@ class RedisCache(CacheDB):
|
|
38
36
|
self.client = fakeredis.FakeStrictRedis() # type: ignore
|
39
37
|
else:
|
40
38
|
redis_password = os.getenv("REDIS_PASSWORD")
|
41
|
-
|
39
|
+
redis_host = os.getenv("REDIS_HOST")
|
40
|
+
redis_port = os.getenv("REDIS_PORT")
|
41
|
+
if None in [redis_password, redis_host, redis_port]:
|
42
42
|
logger.warning(
|
43
|
-
"""REDIS_PASSWORD not set in .env file,
|
43
|
+
"""REDIS_PASSWORD, REDIS_HOST, REDIS_PORT not set in .env file,
|
44
44
|
using fake redis client"""
|
45
45
|
)
|
46
46
|
self.client = fakeredis.FakeStrictRedis() # type: ignore
|
47
47
|
else:
|
48
48
|
self.client = redis.Redis( # type: ignore
|
49
|
-
host=
|
50
|
-
port=
|
49
|
+
host=redis_host,
|
50
|
+
port=redis_port,
|
51
51
|
password=redis_password,
|
52
52
|
)
|
53
53
|
|
@@ -29,7 +29,6 @@ logger = logging.getLogger(__name__)
|
|
29
29
|
class QdrantDBConfig(VectorStoreConfig):
|
30
30
|
type: str = "qdrant"
|
31
31
|
cloud: bool = True
|
32
|
-
url = "https://644cabc3-4141-4734-91f2-0cc3176514d4.us-east-1-0.aws.cloud.qdrant.io:6333"
|
33
32
|
|
34
33
|
collection_name: str | None = None
|
35
34
|
storage_path: str = ".qdrant/data"
|
@@ -49,17 +48,20 @@ class QdrantDB(VectorStore):
|
|
49
48
|
self.host = config.host
|
50
49
|
self.port = config.port
|
51
50
|
load_dotenv()
|
51
|
+
key = os.getenv("QDRANT_API_KEY")
|
52
|
+
url = os.getenv("QDRANT_API_URL")
|
53
|
+
if config.cloud and None in [key, url]:
|
54
|
+
logger.warning(
|
55
|
+
f"""QDRANT_API_KEY, QDRANT_API_URL env variable must be set to use
|
56
|
+
QdrantDB in cloud mode. Please set these values
|
57
|
+
in your .env file.
|
58
|
+
Switching to local storage at {config.storage_path}
|
59
|
+
"""
|
60
|
+
)
|
61
|
+
config.cloud = False
|
52
62
|
if config.cloud:
|
53
|
-
key = os.getenv("QDRANT_API_KEY")
|
54
|
-
if key is None or key == "":
|
55
|
-
raise ValueError(
|
56
|
-
"""QDRANT_API_KEY env variable must be set to use
|
57
|
-
QdrantDB in cloud mode. Please set the QDRANT_API_KEY value
|
58
|
-
in your .env file.
|
59
|
-
"""
|
60
|
-
)
|
61
63
|
self.client = QdrantClient(
|
62
|
-
url=
|
64
|
+
url=url,
|
63
65
|
api_key=key,
|
64
66
|
timeout=config.timeout,
|
65
67
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: langroid
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.26
|
4
4
|
Summary: Harness LLMs with Multi-Agent Programming
|
5
5
|
License: MIT
|
6
6
|
Author: Prasad Chalasani
|
@@ -57,7 +57,7 @@ Requires-Dist: wget (>=3.2,<4.0)
|
|
57
57
|
Description-Content-Type: text/markdown
|
58
58
|
|
59
59
|
<div align="center">
|
60
|
-
<img src="docs/assets/langroid-card-ossem-rust-
|
60
|
+
<img src="docs/assets/langroid-card-lambda-ossem-rust-1200-630.png" alt="Logo"
|
61
61
|
width="400" align="center">
|
62
62
|
</div>
|
63
63
|
|
@@ -75,47 +75,53 @@ Description-Content-Type: text/markdown
|
|
75
75
|
<a target="_blank"
|
76
76
|
href="https://langroid.github.io/langroid/" rel="dofollow">
|
77
77
|
<strong>Explore the docs</strong></a>
|
78
|
-
|
78
|
+
·
|
79
79
|
<a target="_blank" href="https://github.com/langroid/langroid-examples" rel="dofollow">
|
80
80
|
<strong>Examples Repo</strong></a>
|
81
|
-
|
81
|
+
·
|
82
82
|
<a target="_blank" href="https://discord.gg/g3nAXCbZ" rel="dofollow">
|
83
83
|
<strong>Discord</strong></a>
|
84
|
-
|
84
|
+
·
|
85
85
|
<a target="_blank" href="./CONTRIBUTING.md" rel="dofollow">
|
86
86
|
<strong>Contributing</strong></a>
|
87
87
|
|
88
88
|
<br />
|
89
89
|
</h3>
|
90
90
|
|
91
|
-
`Langroid` is an intuitive, lightweight,
|
92
|
-
Python framework to
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
`Langroid` is an intuitive, lightweight, extensible and principled
|
92
|
+
Python framework to easily build LLM-powered applications.
|
93
|
+
You set up Agents, equip them with optional components (LLM,
|
94
|
+
vector-store and methods), assign them tasks, and have them
|
95
|
+
collaboratively solve a problem by exchanging messages.
|
96
|
+
This Multi-Agent paradigm is inspired by the
|
97
|
+
[Actor Framework](https://en.wikipedia.org/wiki/Actor_model)
|
98
|
+
(but you do not need to know anything about this!).
|
97
99
|
|
98
100
|
|
99
101
|
# :rocket: Demo
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
Suppose you want to extract structured information about the key terms
|
103
|
+
of a commercial lease document. You can easily do this with Langroid using a two-agent system,
|
104
|
+
as we show in the [langroid-examples](https://github.com/langroid/langroid-examples/blob/main/examples/docqa/chat_multi_extract.py) repo.
|
105
|
+
The demo showcases several features of Langroid:
|
106
|
+
- Multi-agent collaboration: `LeaseExtractor` is in charge of the task, and its LLM (GPT4) generates questions
|
107
|
+
to be answered by the `DocAgent`.
|
108
|
+
- Retrieval augmented question-answering: `DocAgent` LLM (GPT4) uses retrieval from a vector-store to
|
109
|
+
answer the `LeaseExtractor`'s questions.
|
110
|
+
- Function-calling (also known as tool/plugin): When it has all the information it
|
111
|
+
needs, the `LeaseExtractor` LLM presents the information in a structured
|
112
|
+
format using a Function-call.
|
113
|
+
|
114
|
+
Here is what it looks like in action:
|
109
115
|
|
110
116
|

|
111
117
|
|
112
118
|
|
113
119
|
# :zap: Highlights
|
114
120
|
|
115
|
-
- **Agents as first-class citizens:** The
|
121
|
+
- **Agents as first-class citizens:** The [Agent](https://langroid.github.io/langroid/reference/agent/base/#langroid.agent.base.Agent) class encapsulates LLM conversation state,
|
116
122
|
and optionally a vector-store and tools. Agents are a core abstraction in Langroid;
|
117
123
|
Agents act as _message transformers_, and by default provide 3 _responder_ methods, one corresponding to each entity: LLM, Agent, User.
|
118
|
-
- **Tasks:** A Task class wraps an Agent, and gives the agent instructions (or roles, or goals),
|
124
|
+
- **Tasks:** A [Task](https://langroid.github.io/langroid/reference/agent/task/) class wraps an Agent, and gives the agent instructions (or roles, or goals),
|
119
125
|
manages iteration over an Agent's responder methods,
|
120
126
|
and orchestrates multi-agent interactions via hierarchical, recursive
|
121
127
|
task-delegation. The `Task.run()` method has the same
|
@@ -166,34 +172,47 @@ Note that this will install `torch` and `sentence-transformers` libraries.
|
|
166
172
|
|
167
173
|
### Set up environment variables (API keys, etc)
|
168
174
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
175
|
+
In the root of the repo, copy the `.env-template` file to a new file `.env`:
|
176
|
+
```bash
|
177
|
+
cp .env-template .env
|
178
|
+
```
|
179
|
+
Then insert your OpenAI API Key. If you don't have one, see [this OpenAI Page](https://help.openai.com/en/collections/3675940-getting-started-with-openai-api).
|
180
|
+
Your `.env` file should look like this:
|
181
|
+
|
182
|
+
```bash
|
183
|
+
OPENAI_API_KEY=your-key-here-without-quotes
|
184
|
+
````
|
185
|
+
|
186
|
+
Currently only OpenAI models are supported. Others will be added later
|
187
|
+
(Pull Requests welcome!).
|
188
|
+
|
189
|
+
All of the below are optional and not strictly needed to run any of the examples.
|
190
|
+
|
191
|
+
- **Qdrant** Vector Store API Key, URL. This is only required if you want to use Qdrant cloud.
|
192
|
+
You can sign up for a free 1GB account at [Qdrant cloud](https://cloud.qdrant.io).
|
193
|
+
If you skip setting up these, Langroid will use Qdrant in local-storage mode.
|
174
194
|
Alternatively [Chroma](https://docs.trychroma.com/) is also currently supported.
|
175
195
|
We use the local-storage version of Chroma, so there is no need for an API key.
|
196
|
+
- **Redis** Password, host, port: This is optional, and only needed to cache LLM API responses
|
197
|
+
using Redis Cloud. Redis [offers](https://redis.com/try-free/) a free 30MB Redis account
|
198
|
+
which is more than sufficient to try out Langroid and even beyond.
|
199
|
+
If you don't set up these, Langroid will use a pure-python
|
200
|
+
Redis in-memory cache via the [Fakeredis](https://fakeredis.readthedocs.io/en/latest/) library.
|
176
201
|
- **GitHub** Personal Access Token (required for apps that need to analyze git
|
177
202
|
repos; token-based API calls are less rate-limited). See this
|
178
203
|
[GitHub page](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).
|
179
|
-
|
180
|
-
|
181
|
-
which is more than sufficient to try out Langroid and even beyond.
|
182
|
-
|
183
|
-
```bash
|
184
|
-
cp .env-template .env
|
185
|
-
# now edit the .env file, insert your secrets as above
|
186
|
-
```
|
187
|
-
Your `.env` file should look like this:
|
204
|
+
|
205
|
+
If you add all of these optional variables, your `.env` file should look like this:
|
188
206
|
```bash
|
189
|
-
OPENAI_API_KEY
|
190
|
-
GITHUB_ACCESS_TOKEN
|
191
|
-
REDIS_PASSWORD
|
192
|
-
|
207
|
+
OPENAI_API_KEY=your-key-here-without-quotes
|
208
|
+
GITHUB_ACCESS_TOKEN=your-personal-access-token-no-quotes
|
209
|
+
REDIS_PASSWORD=your-redis-password-no-quotes
|
210
|
+
REDIS_HOST=your-redis-hostname-no-quotes
|
211
|
+
REDIS_PORT=your-redis-port-no-quotes
|
212
|
+
QDRANT_API_KEY=your-key
|
213
|
+
QDRANT_API_URL=https://your.url.here:6333 # note port number must be included
|
193
214
|
```
|
194
215
|
|
195
|
-
Currently only OpenAI models are supported. Others will be added later
|
196
|
-
(Pull Requests welcome!).
|
197
216
|
|
198
217
|
---
|
199
218
|
|
@@ -207,24 +226,21 @@ and they are **not** complete runnable examples! For that we encourage you to
|
|
207
226
|
consult the [`langroid-examples`](https://github.com/langroid/langroid-examples)
|
208
227
|
repository.
|
209
228
|
|
210
|
-
:information_source: The
|
211
|
-
|
212
|
-
|
229
|
+
:information_source: The various LLM prompts and instructions in Langroid
|
230
|
+
have been tested to work well with GPT4.
|
231
|
+
Switching to GPT3.5-Turbo is easy via a config flag
|
232
|
+
(e.g., `cfg = OpenAIGPTConfig(chat_model=OpenAIChatModel.GPT3_5_TURBO)`),
|
233
|
+
and may suffice for some applications, but in general you may see inferior results.
|
234
|
+
|
213
235
|
|
214
236
|
:book: Also see the
|
215
237
|
[`Getting Started Guide`](https://langroid.github.io/langroid/quick-start/)
|
216
|
-
for a detailed tutorial.
|
238
|
+
for a detailed tutorial.
|
217
239
|
|
218
|
-
|
219
|
-
- [Simple Agent and Task](#agent-task)
|
220
|
-
- [Three Communicating Agents](#three-agents)
|
221
|
-
- [Agent with Tool/Function-calling](#agent-tool)
|
222
|
-
- [Extract Structured Info with Tool/Function-calling](#agent-tool-structured)
|
223
|
-
- [Retrieval-Augmented-Generation: Chat with Docs](#agent-rag)
|
224
|
-
|
225
|
-
---
|
240
|
+
Click to expand any of the code examples below:
|
226
241
|
|
227
|
-
|
242
|
+
<details>
|
243
|
+
<summary> <b> Direct interaction with OpenAI LLM </b> </summary>
|
228
244
|
|
229
245
|
```python
|
230
246
|
from langroid.language_models.openai_gpt import (
|
@@ -243,10 +259,10 @@ messages = [
|
|
243
259
|
response = mdl.chat(messages, max_tokens=200)
|
244
260
|
print(response.message)
|
245
261
|
```
|
262
|
+
</details>
|
246
263
|
|
247
|
-
|
248
|
-
|
249
|
-
## Define an agent, set up a task, and run it <a name="agent-task"></a>
|
264
|
+
<details>
|
265
|
+
<summary> <b> Define an agent, set up a task, and run it </b> </summary>
|
250
266
|
|
251
267
|
```python
|
252
268
|
from langroid.agent.chat_agent import ChatAgent, ChatAgentConfig
|
@@ -266,10 +282,12 @@ agent = ChatAgent(config)
|
|
266
282
|
task = Task(agent, name="Bot")
|
267
283
|
task.run() # ... a loop seeking response from LLM or User at each turn
|
268
284
|
```
|
285
|
+
</details>
|
269
286
|
|
270
|
-
|
287
|
+
<details>
|
288
|
+
<summary><b> Three communicating agents </b></summary>
|
271
289
|
|
272
|
-
|
290
|
+
```python
|
273
291
|
|
274
292
|
A toy numbers game, where when given a number `n`:
|
275
293
|
- `repeater_agent`'s LLM simply returns `n`,
|
@@ -329,9 +347,11 @@ and run the `repeater_task`, kicking it off with a number as input:
|
|
329
347
|
repeater_task.add_sub_task([even_task, odd_task])
|
330
348
|
repeater_task.run("3")
|
331
349
|
```
|
332
|
-
---
|
333
350
|
|
334
|
-
|
351
|
+
</details>
|
352
|
+
|
353
|
+
<details>
|
354
|
+
<summary><b> Simple Tool/Function-calling example </b></summary>
|
335
355
|
|
336
356
|
Langroid leverages Pydantic to support OpenAI's
|
337
357
|
[Function-calling API](https://platform.openai.com/docs/guides/gpt/function-calling)
|
@@ -396,10 +416,10 @@ spy_game_agent.enable_message(ProbeTool)
|
|
396
416
|
For a full working example see the
|
397
417
|
[chat-agent-tool.py](https://github.com/langroid/langroid-examples/blob/main/examples/quick-start/chat-agent-tool.py)
|
398
418
|
script in the `langroid-examples` repo.
|
419
|
+
</details>
|
399
420
|
|
400
|
-
|
401
|
-
|
402
|
-
## Tool/Function-calling to extract structured information from text <a name="agent-tool-structured"></a>
|
421
|
+
<details>
|
422
|
+
<summary> <b>Tool/Function-calling to extract structured information from text </b> </summary>
|
403
423
|
|
404
424
|
Suppose you want an agent to extract
|
405
425
|
the key terms of a lease, from a lease document, as a nested JSON structure.
|
@@ -460,10 +480,10 @@ lease_extractor_agent.enable_message(LeaseMessage)
|
|
460
480
|
|
461
481
|
See the [`chat_multi_extract.py`](https://github.com/langroid/langroid-examples/blob/main/examples/docqa/chat_multi_extract.py)
|
462
482
|
script in the `langroid-examples` repo for a full working example.
|
483
|
+
</details>
|
463
484
|
|
464
|
-
|
465
|
-
|
466
|
-
## Chat with documents (file paths, URLs, etc) <a name="agent-docs"></a>
|
485
|
+
<details>
|
486
|
+
<summary><b> Chat with documents (file paths, URLs, etc) </b></summary>
|
467
487
|
|
468
488
|
Langroid provides a specialized agent class `DocChatAgent` for this purpose.
|
469
489
|
It incorporates document sharding, embedding, storage in a vector-DB,
|
@@ -509,9 +529,14 @@ task.run()
|
|
509
529
|
See full working scripts in the
|
510
530
|
[`docqa`](https://github.com/langroid/langroid-examples/tree/main/examples/docqa)
|
511
531
|
folder of the `langroid-examples` repo.
|
532
|
+
</details>
|
512
533
|
|
513
534
|
---
|
514
535
|
|
536
|
+
# :heart: Thank you to our supporters!
|
537
|
+
|
538
|
+
[](https://github.com/langroid/langroid/stargazers)
|
539
|
+
|
515
540
|
# Contributors
|
516
541
|
|
517
542
|
- Prasad Chalasani (IIT BTech/CS, CMU PhD/ML; Independent ML Consultant)
|
@@ -14,7 +14,7 @@ langroid/agent/tool_message.py,sha256=7OdVcV7UyOZD2ihYgV1C_1fIwiWM-2pR8FFxoA1IgO
|
|
14
14
|
langroid/agent_config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
langroid/cachedb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
langroid/cachedb/base.py,sha256=F-QSDlRXrC0tBRbxL397MX8hulfBMAnZNs1e9zH71OQ,790
|
17
|
-
langroid/cachedb/redis_cachedb.py,sha256=
|
17
|
+
langroid/cachedb/redis_cachedb.py,sha256=xuQ96FAqcHTfK8PEt1tjrh1BkMWUjojFHIgjDfF3SnU,2369
|
18
18
|
langroid/embedding_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
langroid/embedding_models/base.py,sha256=176jDrjEAAhNzdFCG8pfossd8SAhvHR8Q5Y8pOOm0LI,983
|
20
20
|
langroid/embedding_models/clustering.py,sha256=tZWElUqXl9Etqla0FAa7og96iDKgjqWjucZR_Egtp-A,6684
|
@@ -60,8 +60,8 @@ langroid/vector_store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
60
60
|
langroid/vector_store/base.py,sha256=QZx3NUNwf2I0r3A7iuoUHIRGbqt_pFGD0hq1R-Yg8iM,3740
|
61
61
|
langroid/vector_store/chromadb.py,sha256=GPaXNPgPGIVUwYx2eO_-kreQoJ_33IFo13oigH5BP1c,5200
|
62
62
|
langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
|
63
|
-
langroid/vector_store/qdrantdb.py,sha256=
|
64
|
-
langroid-0.1.
|
65
|
-
langroid-0.1.
|
66
|
-
langroid-0.1.
|
67
|
-
langroid-0.1.
|
63
|
+
langroid/vector_store/qdrantdb.py,sha256=cnxCrp4yIdbJ7-pz7yRoepJhd29mOzwacV2C6O7G_AQ,8548
|
64
|
+
langroid-0.1.26.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
|
65
|
+
langroid-0.1.26.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
66
|
+
langroid-0.1.26.dist-info/METADATA,sha256=ozd74VngEPA1ZcQrREhERhw2Byb3h0wCuzAlaNJOsWo,21039
|
67
|
+
langroid-0.1.26.dist-info/RECORD,,
|
File without changes
|
File without changes
|