langroid 0.1.257__py3-none-any.whl → 0.1.260__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.
@@ -214,6 +214,7 @@ def wrap_text_preserving_structure(text: str, width: int = 90) -> str:
214
214
 
215
215
  class ChainlitCallbackConfig(BaseSettings):
216
216
  user_has_agent_name: bool = True # show agent name in front of "YOU" ?
217
+ show_subtask_response: bool = True # show sub-task response as a step?
217
218
 
218
219
 
219
220
  class ChainlitAgentCallbacks:
@@ -277,12 +278,6 @@ class ChainlitAgentCallbacks:
277
278
 
278
279
  def start_llm_stream(self) -> Callable[[str], None]:
279
280
  """Returns a streaming fn that can be passed to the LLM class"""
280
- logger.info(
281
- f"""
282
- Starting LLM stream for {self.agent.config.name}
283
- under parent {self._get_parent_id()}
284
- """
285
- )
286
281
  self.stream = cl.Step(
287
282
  id=self.curr_step.id if self.curr_step is not None else None,
288
283
  name=self._entity_name("llm"),
@@ -291,6 +286,13 @@ class ChainlitAgentCallbacks:
291
286
  )
292
287
  self.last_step = self.stream
293
288
  self.curr_step = None
289
+ logger.info(
290
+ f"""
291
+ Starting LLM stream for {self.agent.config.name}
292
+ id = {self.stream.id}
293
+ under parent {self._get_parent_id()}
294
+ """
295
+ )
294
296
  run_sync(self.stream.send()) # type: ignore
295
297
 
296
298
  def stream_token(t: str) -> None:
@@ -323,6 +325,13 @@ class ChainlitAgentCallbacks:
323
325
  language="json" if is_tool else None,
324
326
  )
325
327
  step.output = textwrap.dedent(content) or NO_ANSWER
328
+ logger.info(
329
+ f"""
330
+ Finish STREAM LLM response for {self.agent.config.name}
331
+ id = {step.id}
332
+ under parent {self._get_parent_id()}
333
+ """
334
+ )
326
335
  run_sync(step.update()) # type: ignore
327
336
 
328
337
  def show_llm_response(
@@ -343,6 +352,13 @@ class ChainlitAgentCallbacks:
343
352
  self.last_step = step
344
353
  self.curr_step = None
345
354
  step.output = textwrap.dedent(content) or NO_ANSWER
355
+ logger.info(
356
+ f"""
357
+ Showing NON-STREAM LLM response for {self.agent.config.name}
358
+ id = {step.id}
359
+ under parent {self._get_parent_id()}
360
+ """
361
+ )
346
362
  run_sync(step.send()) # type: ignore
347
363
 
348
364
  def show_error_message(self, error: str) -> None:
@@ -374,6 +390,13 @@ class ChainlitAgentCallbacks:
374
390
  self.last_step = step
375
391
  self.curr_step = None
376
392
  step.output = content
393
+ logger.info(
394
+ f"""
395
+ Showing AGENT response for {self.agent.config.name}
396
+ id = {step.id}
397
+ under parent {self._get_parent_id()}
398
+ """
399
+ )
377
400
  run_sync(step.send()) # type: ignore
378
401
 
379
402
  def show_start_response(self, entity: str) -> None:
@@ -390,6 +413,13 @@ class ChainlitAgentCallbacks:
390
413
  step.output = ""
391
414
  self.last_step = step
392
415
  self.curr_step = step
416
+ logger.info(
417
+ f"""
418
+ Showing START response for {self.agent.config.name} ({entity})
419
+ id = {step.id}
420
+ under parent {self._get_parent_id()}
421
+ """
422
+ )
393
423
  run_sync(step.send()) # type: ignore
394
424
 
395
425
  def _entity_name(
@@ -459,6 +489,13 @@ class ChainlitAgentCallbacks:
459
489
  parent_id=self._get_parent_id(),
460
490
  )
461
491
  step.output = message
492
+ logger.info(
493
+ f"""
494
+ Showing USER response for {self.agent.config.name}
495
+ id = {step.id}
496
+ under parent {self._get_parent_id()}
497
+ """
498
+ )
462
499
  run_sync(step.send())
463
500
 
464
501
  def show_first_user_message(self, msg: cl.Message):
@@ -575,7 +612,8 @@ class ChainlitTaskCallbacks(ChainlitAgentCallbacks):
575
612
  super().__init__(task.agent, msg, config)
576
613
  self._inject_callbacks(task)
577
614
  self.task = task
578
- self.task.callbacks.show_subtask_response = self.show_subtask_response
615
+ if config.show_subtask_response:
616
+ self.task.callbacks.show_subtask_response = self.show_subtask_response
579
617
 
580
618
  @classmethod
581
619
  def _inject_callbacks(
langroid/agent/task.py CHANGED
@@ -156,6 +156,11 @@ class Task:
156
156
  interactive (bool): if true, wait for human input after each non-human
157
157
  response (prevents infinite loop of non-human responses).
158
158
  Default is true. If false, then `default_human_response` is set to ""
159
+ Note: When interactive = False, the one exception is when the user
160
+ is explicitly addressed, via "@user" or using RecipientTool, in which
161
+ case the system will wait for a user response. In other words, use
162
+ `interactive=False` when you want a "largely non-interactive"
163
+ run, with the exception of explicit user addressing.
159
164
  only_user_quits_root (bool): if true, only user can quit the root task.
160
165
  [This param is ignored & deprecated; Keeping for backward compatibility.
161
166
  Instead of this, setting `interactive` suffices]
@@ -912,7 +917,11 @@ class Task:
912
917
  parent (ChatDocument|None): parent message of the current message
913
918
  """
914
919
  self.n_stalled_steps += 1
915
- if (not self.task_progress or self.allow_null_result) and not self.is_pass_thru:
920
+ user_dummy_response = self.pending_sender != Entity.USER and self.interactive
921
+ if (not self.is_pass_thru) and (
922
+ not self.task_progress or self.allow_null_result or user_dummy_response
923
+ ):
924
+
916
925
  # There has been no progress at all in this task, so we
917
926
  # update the pending_message to a dummy NO_ANSWER msg
918
927
  # from the entity 'opposite' to the current pending_sender,
@@ -1375,9 +1384,18 @@ class Task:
1375
1384
  )
1376
1385
 
1377
1386
  def _can_respond(self, e: Responder) -> bool:
1378
- if self.pending_sender == e:
1379
- # Responder cannot respond to its own message
1387
+ user_can_respond = self.interactive or (
1388
+ # regardless of self.interactive, if a msg is explicitly addressed to
1389
+ # user, then wait for user response
1390
+ self.pending_message is not None
1391
+ and self.pending_message.metadata.recipient == Entity.USER
1392
+ )
1393
+
1394
+ if self.pending_sender == e or (e == Entity.USER and not user_can_respond):
1395
+ # sender is same as e (an entity cannot respond to its own msg),
1396
+ # or user cannot respond
1380
1397
  return False
1398
+
1381
1399
  if self.pending_message is None:
1382
1400
  return True
1383
1401
  if self._recipient_mismatch(e):
@@ -421,7 +421,9 @@ class OpenAIGPT(LanguageModel):
421
421
  self.api_base = "http://" + self.api_base
422
422
  elif self.config.chat_model.startswith("ollama/"):
423
423
  self.config.ollama = True
424
- self.api_base = OLLAMA_BASE_URL
424
+
425
+ # use api_base from config if set, else fall back on OLLAMA_BASE_URL
426
+ self.api_base = self.config.api_base or OLLAMA_BASE_URL
425
427
  self.api_key = OLLAMA_API_KEY
426
428
  self.config.chat_model = self.config.chat_model.replace("ollama/", "")
427
429
  else:
@@ -68,7 +68,7 @@ class QdrantDBConfig(VectorStoreConfig):
68
68
  embedding: EmbeddingModelsConfig = OpenAIEmbeddingsConfig()
69
69
  distance: str = Distance.COSINE
70
70
  use_sparse_embeddings: bool = False
71
- sparse_embedding_model: str = ""
71
+ sparse_embedding_model: str = "naver/splade-v3-distilbert"
72
72
  sparse_limit: int = 3
73
73
 
74
74
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.1.257
3
+ Version: 0.1.260
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -10,13 +10,14 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
+ Provides-Extra: all
13
14
  Provides-Extra: chainlit
14
15
  Provides-Extra: chromadb
15
16
  Provides-Extra: db
16
17
  Provides-Extra: doc-chat
17
18
  Provides-Extra: docx
18
- Provides-Extra: embeddings
19
19
  Provides-Extra: hf-embeddings
20
+ Provides-Extra: hf-transformers
20
21
  Provides-Extra: lancedb
21
22
  Provides-Extra: litellm
22
23
  Provides-Extra: meilisearch
@@ -31,11 +32,12 @@ Provides-Extra: scrapy
31
32
  Provides-Extra: sql
32
33
  Provides-Extra: transformers
33
34
  Provides-Extra: unstructured
35
+ Provides-Extra: vecdbs
34
36
  Requires-Dist: aiohttp (>=3.9.1,<4.0.0)
35
37
  Requires-Dist: async-generator (>=1.10,<2.0)
36
38
  Requires-Dist: bs4 (>=0.0.1,<0.0.2)
37
- Requires-Dist: chainlit (>=1.0.400,<2.0.0) ; extra == "chainlit"
38
- Requires-Dist: chromadb (>=0.4.21,<=0.4.23) ; extra == "chromadb"
39
+ Requires-Dist: chainlit (>=1.0.400,<2.0.0) ; extra == "all" or extra == "chainlit"
40
+ Requires-Dist: chromadb (>=0.4.21,<=0.4.23) ; extra == "vecdbs" or extra == "all" or extra == "chromadb"
39
41
  Requires-Dist: colorlog (>=6.7.0,<7.0.0)
40
42
  Requires-Dist: docstring-parser (>=0.15,<0.16)
41
43
  Requires-Dist: duckduckgo-search (>=6.0.0,<7.0.0)
@@ -47,47 +49,38 @@ Requires-Dist: google-generativeai (>=0.5.2,<0.6.0)
47
49
  Requires-Dist: groq (>=0.5.0,<0.6.0)
48
50
  Requires-Dist: grpcio (>=1.62.1,<2.0.0)
49
51
  Requires-Dist: halo (>=0.0.31,<0.0.32)
50
- Requires-Dist: huggingface-hub (>=0.21.2,<0.22.0) ; extra == "embeddings" or extra == "transformers"
52
+ Requires-Dist: huggingface-hub (>=0.21.2,<0.22.0) ; extra == "hf-transformers" or extra == "all" or extra == "transformers"
51
53
  Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
52
- Requires-Dist: lancedb (>=0.6.2,<0.7.0) ; extra == "lancedb"
53
- Requires-Dist: litellm (>=1.30.1,<2.0.0) ; extra == "litellm"
54
+ Requires-Dist: lancedb (>=0.6.2,<0.7.0) ; extra == "vecdbs" or extra == "all" or extra == "lancedb"
55
+ Requires-Dist: litellm (>=1.30.1,<2.0.0) ; extra == "all" or extra == "litellm"
54
56
  Requires-Dist: lxml (>=4.9.3,<5.0.0)
55
57
  Requires-Dist: meilisearch (>=0.28.3,<0.29.0) ; extra == "meilisearch"
56
58
  Requires-Dist: meilisearch-python-sdk (>=2.2.3,<3.0.0) ; extra == "meilisearch"
57
- Requires-Dist: metaphor-python (>=0.1.23,<0.2.0) ; extra == "metaphor"
58
- Requires-Dist: mkdocs (>=1.4.2,<2.0.0) ; extra == "mkdocs"
59
- Requires-Dist: mkdocs-awesome-pages-plugin (>=2.8.0,<3.0.0) ; extra == "mkdocs"
60
- Requires-Dist: mkdocs-gen-files (>=0.4.0,<0.5.0) ; extra == "mkdocs"
61
- Requires-Dist: mkdocs-jupyter (>=0.24.1,<0.25.0) ; extra == "mkdocs"
62
- Requires-Dist: mkdocs-literate-nav (>=0.6.0,<0.7.0) ; extra == "mkdocs"
63
- Requires-Dist: mkdocs-material (>=9.1.5,<10.0.0) ; extra == "mkdocs"
64
- Requires-Dist: mkdocs-rss-plugin (>=1.8.0,<2.0.0) ; extra == "mkdocs"
65
- Requires-Dist: mkdocs-section-index (>=0.3.5,<0.4.0) ; extra == "mkdocs"
66
- Requires-Dist: mkdocstrings[python] (>=0.21.2,<0.22.0) ; extra == "mkdocs"
59
+ Requires-Dist: metaphor-python (>=0.1.23,<0.2.0) ; extra == "all" or extra == "metaphor"
67
60
  Requires-Dist: momento (>=1.10.2,<2.0.0) ; extra == "momento"
68
- Requires-Dist: neo4j (>=5.14.1,<6.0.0) ; extra == "neo4j"
61
+ Requires-Dist: neo4j (>=5.14.1,<6.0.0) ; extra == "all" or extra == "neo4j"
69
62
  Requires-Dist: nest-asyncio (>=1.6.0,<2.0.0)
70
63
  Requires-Dist: nltk (>=3.8.1,<4.0.0)
71
64
  Requires-Dist: onnxruntime (>=1.16.1,<2.0.0)
72
65
  Requires-Dist: openai (>=1.14.0,<2.0.0)
73
66
  Requires-Dist: pandas (>=2.0.3,<3.0.0)
74
- Requires-Dist: pdf2image (>=1.17.0,<2.0.0) ; extra == "doc-chat" or extra == "pdf-parsers"
75
- Requires-Dist: pdfplumber (>=0.10.2,<0.11.0) ; extra == "doc-chat" or extra == "pdf-parsers"
67
+ Requires-Dist: pdf2image (>=1.17.0,<2.0.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
68
+ Requires-Dist: pdfplumber (>=0.10.2,<0.11.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
76
69
  Requires-Dist: prettytable (>=3.8.0,<4.0.0)
77
- Requires-Dist: psycopg2 (>=2.9.7,<3.0.0) ; extra == "db" or extra == "postgres" or extra == "sql"
78
- Requires-Dist: pyarrow (==15.0.0) ; extra == "lancedb"
70
+ Requires-Dist: psycopg2 (>=2.9.7,<3.0.0) ; extra == "db" or extra == "all" or extra == "postgres" or extra == "sql"
71
+ Requires-Dist: pyarrow (==15.0.0) ; extra == "vecdbs" or extra == "all" or extra == "lancedb"
79
72
  Requires-Dist: pydantic (==1.10.13)
80
73
  Requires-Dist: pygithub (>=1.58.1,<2.0.0)
81
74
  Requires-Dist: pygments (>=2.15.1,<3.0.0)
82
- Requires-Dist: pymupdf (>=1.23.3,<2.0.0) ; extra == "doc-chat" or extra == "pdf-parsers"
83
- Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "db" or extra == "mysql" or extra == "sql"
75
+ Requires-Dist: pymupdf (>=1.23.3,<2.0.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
76
+ Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "db" or extra == "all" or extra == "mysql" or extra == "sql"
84
77
  Requires-Dist: pyparsing (>=3.0.9,<4.0.0)
85
- Requires-Dist: pypdf (>=3.12.2,<4.0.0) ; extra == "doc-chat" or extra == "pdf-parsers"
86
- Requires-Dist: pytesseract (>=0.3.10,<0.4.0) ; extra == "doc-chat" or extra == "pdf-parsers"
87
- Requires-Dist: python-docx (>=1.1.0,<2.0.0) ; extra == "doc-chat" or extra == "docx"
78
+ Requires-Dist: pypdf (>=3.12.2,<4.0.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
79
+ Requires-Dist: pytesseract (>=0.3.10,<0.4.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
80
+ Requires-Dist: python-docx (>=1.1.0,<2.0.0) ; extra == "doc-chat" or extra == "all" or extra == "docx"
88
81
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
89
82
  Requires-Dist: python-magic (>=0.4.27,<0.5.0)
90
- Requires-Dist: python-socketio (>=5.11.0,<6.0.0) ; extra == "chainlit"
83
+ Requires-Dist: python-socketio (>=5.11.0,<6.0.0) ; extra == "all" or extra == "chainlit"
91
84
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
92
85
  Requires-Dist: qdrant-client (>=1.8.0,<2.0.0)
93
86
  Requires-Dist: rank-bm25 (>=0.2.2,<0.3.0)
@@ -96,16 +89,16 @@ Requires-Dist: requests (>=2.31.0,<3.0.0)
96
89
  Requires-Dist: requests-oauthlib (>=1.3.1,<2.0.0)
97
90
  Requires-Dist: rich (>=13.3.4,<14.0.0)
98
91
  Requires-Dist: scrapy (>=2.11.0,<3.0.0) ; extra == "scrapy"
99
- Requires-Dist: sentence-transformers (==2.2.2) ; extra == "embeddings" or extra == "hf-embeddings"
100
- Requires-Dist: sqlalchemy (>=2.0.19,<3.0.0) ; extra == "db" or extra == "sql"
101
- Requires-Dist: tantivy (>=0.21.0,<0.22.0) ; extra == "lancedb"
92
+ Requires-Dist: sentence-transformers (==2.2.2) ; extra == "hf-transformers" or extra == "all" or extra == "hf-embeddings"
93
+ Requires-Dist: sqlalchemy (>=2.0.19,<3.0.0) ; extra == "db" or extra == "all" or extra == "sql"
94
+ Requires-Dist: tantivy (>=0.21.0,<0.22.0) ; extra == "vecdbs" or extra == "all" or extra == "lancedb"
102
95
  Requires-Dist: thefuzz (>=0.20.0,<0.21.0)
103
96
  Requires-Dist: tiktoken (>=0.7.0,<0.8.0)
104
- Requires-Dist: torch (==2.0.0) ; extra == "embeddings" or extra == "hf-embeddings" or extra == "transformers"
97
+ Requires-Dist: torch (==2.0.0) ; extra == "hf-transformers" or extra == "all" or extra == "hf-embeddings" or extra == "transformers"
105
98
  Requires-Dist: trafilatura (>=1.5.0,<2.0.0)
106
- Requires-Dist: transformers (>=4.40.1,<5.0.0) ; extra == "embeddings" or extra == "transformers"
99
+ Requires-Dist: transformers (>=4.40.1,<5.0.0) ; extra == "hf-transformers" or extra == "all" or extra == "transformers"
107
100
  Requires-Dist: typer (>=0.9.0,<0.10.0)
108
- Requires-Dist: unstructured[docx,pdf,pptx] (>=0.10.16,<0.10.18) ; extra == "doc-chat" or extra == "unstructured"
101
+ Requires-Dist: unstructured[docx,pdf,pptx] (>=0.10.16,<0.10.18) ; extra == "doc-chat" or extra == "all" or extra == "unstructured"
109
102
  Requires-Dist: wget (>=3.2,<4.0)
110
103
  Description-Content-Type: text/markdown
111
104
 
@@ -117,6 +110,7 @@ Description-Content-Type: text/markdown
117
110
  <div align="center">
118
111
 
119
112
  [![PyPI - Version](https://img.shields.io/pypi/v/langroid)](https://pypi.org/project/langroid/)
113
+ [![Downloads](https://img.shields.io/pypi/dm/langroid)](https://pypi.org/project/langroid/)
120
114
  [![Pytest](https://github.com/langroid/langroid/actions/workflows/pytest.yml/badge.svg)](https://github.com/langroid/langroid/actions/workflows/pytest.yml)
121
115
  [![codecov](https://codecov.io/gh/langroid/langroid/branch/main/graph/badge.svg?token=H94BX5F0TE)](https://codecov.io/gh/langroid/langroid)
122
116
  [![Multi-Architecture DockerHub](https://github.com/langroid/langroid/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/langroid/langroid/actions/workflows/docker-publish.yml)
@@ -234,12 +228,22 @@ teacher_task.run()
234
228
  <summary> <b>Click to expand</b></summary>
235
229
 
236
230
  - **May 2024:**
231
+ - **Slimmer langroid**: All document-parsers (i.e. pdf, doc, docx) and most
232
+ vector-databases (except qdrant)
233
+ are now optional/extra dependencies, which helps reduce build size, script
234
+ start-up time, and install time. For convenience various grouping of "extras" are
235
+ provided, e.g. `doc-chat`, `db` (for database-related dependencies). See updated
236
+ install instructions below and in the docs.
237
+ - **Few-shot examples** for tools: when defining a [ToolMessage](https://langroid.github.io/langroid/quick-start/chat-agent-tool/#example-find-the-smallest-number-in-a-list), previously you were able to include a classmethod named `examples`,
238
+ and a random example from this list would be used to generate a 1-shot example
239
+ for the LLM. This has been improved so you can now supply a list of examples
240
+ where each example is either a tool instance, or a tuple of (description,
241
+ tool instance), where the description is a "thought" that leads the LLM to use
242
+ the tool (see example in the [docs](https://langroid.github.io/langroid/quick-start/chat-agent-tool/#example-find-the-smallest-number-in-a-list)). In some scenarios this can improve LLM tool
243
+ generation accuracy. Also, now instead of a random example, ALL examples are used to generate few-shot
244
+ examples.
237
245
  - [Infinite loop detection](https://github.com/langroid/langroid/blob/0ed30eb467b00d5eaf2933b577a4b2cc37de1aa1/langroid/agent/task.py#L1121) for task loops of cycle-length <= 10 (configurable
238
- in [`TaskConfig`](https://github.
239
- com/langroid/langroid/blob/0ed30eb467b00d5eaf2933b577a4b2cc37de1aa1/langroid/agent
240
- /task.py#L61). Only detects _exact_ loops, rather than
241
- _approximate_ loops where the entities are saying essentially similar (but not
242
- exactly the same) things repeatedly.
246
+ in [`TaskConfig`](https://langroid.github.io/langroid/reference/agent/task/#langroid.agent.task.TaskConfig). Only detects _exact_ loops, rather than _approximate_ loops where the entities are saying essentially similar (but not exactly the same) things repeatedly.
243
247
  - "@"-addressing: any entity can address any other by name, which can be the name
244
248
  of an agent's responder ("llm", "user", "agent") or a sub-task name. This is a
245
249
  simpler alternative to the `RecipientTool` mechanism, with the tradeoff that
@@ -433,7 +437,7 @@ section above)
433
437
  a task of an agent can delegate to other sub-tasks: from the point of view of a Task,
434
438
  sub-tasks are simply additional responders, to be used in a round-robin fashion
435
439
  after the agent's own responders.
436
- - **Modularity, Reusabilily, Loose coupling:** The `Agent` and `Task` abstractions allow users to design
440
+ - **Modularity, Reusability, Loose coupling:** The `Agent` and `Task` abstractions allow users to design
437
441
  Agents with specific skills, wrap them in Tasks, and combine tasks in a flexible way.
438
442
  - **LLM Support**: Langroid supports OpenAI LLMs as well as LLMs from hundreds of
439
443
  providers (local/open or remote/commercial) via proxy libraries and local model servers
@@ -489,7 +493,10 @@ For many practical scenarios, you may need additional optional dependencies:
489
493
  ```bash
490
494
  pip install "langroid[doc-chat,db]"
491
495
  ```
492
-
496
+ - To simply install _all_ optional dependencies, use the `all` extra (but note that this will result in longer load/startup times and a larger install size):
497
+ ```bash
498
+ pip install "langroid[all]"
499
+ ```
493
500
  <details>
494
501
  <summary><b>Optional Installs for using SQL Chat with a PostgreSQL DB </b></summary>
495
502
 
@@ -3,7 +3,7 @@ langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,78
3
3
  langroid/agent/base.py,sha256=aSwWmOBg0d3QQHUSauscMNfnl8Wkv6nrk2nngKa9DjM,37183
4
4
  langroid/agent/batch.py,sha256=feRA_yRG768ElOQjrKEefcRv6Aefd_yY7qktuYUQDwc,10040
5
5
  langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- langroid/agent/callbacks/chainlit.py,sha256=XWih3UkHsYgPIaBQ1cZ-8H2VU_URh-sSfw8fcq1hfMo,20841
6
+ langroid/agent/callbacks/chainlit.py,sha256=6gkk9Qf_i4fOD13w8ZdUfMcgKYPzLMw30hzFUN60AIc,22044
7
7
  langroid/agent/chat_agent.py,sha256=hnmeOxdi4i5w8WaL2kPjQOEpenoRW_hG5EfeMWuuVsQ,39478
8
8
  langroid/agent/chat_document.py,sha256=uwCq53SHRyxQw6qyhjzPYuJG48VHBgOf2122Ew3fk6c,9316
9
9
  langroid/agent/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -32,7 +32,7 @@ langroid/agent/special/sql/utils/populate_metadata.py,sha256=1J22UsyEPKzwK0XlJZt
32
32
  langroid/agent/special/sql/utils/system_message.py,sha256=qKLHkvQWRQodTtPLPxr1GSLUYUFASZU8x-ybV67cB68,1885
33
33
  langroid/agent/special/sql/utils/tools.py,sha256=6uB2424SLtmapui9ggcEr0ZTiB6_dL1-JRGgN8RK9Js,1332
34
34
  langroid/agent/special/table_chat_agent.py,sha256=d9v2wsblaRx7oMnKhLV7uO_ujvk9gh59pSGvBXyeyNc,9659
35
- langroid/agent/task.py,sha256=8f65p79ID17mCT8l2F7VuldL7uEWOavLTOkX0B29sbo,59465
35
+ langroid/agent/task.py,sha256=Su1TpEmt3aPVTzXnTvJdyjSqZsXmUUcHN12KAs-gMY0,60408
36
36
  langroid/agent/tool_message.py,sha256=7t-UGEbykosKHAvaLI0Rm59sgxvN31IO3-P7bg7gLug,9730
37
37
  langroid/agent/tools/__init__.py,sha256=8Pc9BlGCB5FQ2IDGKS_WPpHCoWp5jblMU8EHJwwikAY,303
38
38
  langroid/agent/tools/duckduckgo_search_tool.py,sha256=NhsCaGZkdv28nja7yveAhSK_w6l_Ftym8agbrdzqgfo,1935
@@ -65,7 +65,7 @@ langroid/language_models/azure_openai.py,sha256=ncRCbKooqLVOY-PWQUIo9C3yTuKEFbAw
65
65
  langroid/language_models/base.py,sha256=8FTvWtOmIrz6K78kzyrVqf2uJk03dBc0AUnVY-l9ucg,21031
66
66
  langroid/language_models/config.py,sha256=5UF3DzO1a-Dfsc3vghE0XGq7g9t_xDsRCsuRiU4dgBg,366
67
67
  langroid/language_models/openai_assistants.py,sha256=9K-DEAL2aSWHeXj2hwCo2RAlK9_1oCPtqX2u1wISCj8,36
68
- langroid/language_models/openai_gpt.py,sha256=SSLBYb41ITLegdinFHL2u9Hm5v2bNgBDF8q0BsznY8A,50596
68
+ langroid/language_models/openai_gpt.py,sha256=OZcFAtVI8JPGOPPRozWI1PfkdE450hS16RChaUc2uFM,50702
69
69
  langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
70
70
  langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
71
71
  langroid/language_models/prompt_formatter/hf_formatter.py,sha256=TFL6ppmeQWnzr6CKQzRZFYY810zE1mr8DZnhw6i85ok,5217
@@ -125,8 +125,9 @@ langroid/vector_store/lancedb.py,sha256=nC5pcrFoUOOO941Y7XiPZONUO4LuoZIAR1aR4Pec
125
125
  langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3HmhHQICXLs,11663
126
126
  langroid/vector_store/momento.py,sha256=QaPzUnTwlswoawGB-paLtUPyLRvckFXLfLDfvbTzjNQ,10505
127
127
  langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
128
- langroid/vector_store/qdrantdb.py,sha256=sk5Qb2ZNbooi0rorsMuqIMokF7WADw6PJ0D6goM2XBw,16802
129
- langroid-0.1.257.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
130
- langroid-0.1.257.dist-info/METADATA,sha256=xLoU_XiewcfxXk98d6dG8S8dkniC4r5hVrEFgS9_h8s,51001
131
- langroid-0.1.257.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
132
- langroid-0.1.257.dist-info/RECORD,,
128
+ langroid/vector_store/qdrantdb.py,sha256=wYOuu5c2vIKn9ZgvTXcAiZXMpV8AOXEWFAzI8S8UP-0,16828
129
+ pyproject.toml,sha256=6Vqvoq2dWP_JzMKXoKVlTteWCZGmWPW4tFQV0KfRtVQ,7026
130
+ langroid-0.1.260.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
131
+ langroid-0.1.260.dist-info/METADATA,sha256=ftMLe9Jwmp1GkP9bsiO4kdxABtcgFuR1hsOdaXrKNkI,52506
132
+ langroid-0.1.260.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
133
+ langroid-0.1.260.dist-info/RECORD,,
pyproject.toml ADDED
@@ -0,0 +1,233 @@
1
+ [tool.poetry]
2
+ name = "langroid"
3
+ version = "0.1.260"
4
+ description = "Harness LLMs with Multi-Agent Programming"
5
+ authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
6
+ readme = "README.md"
7
+ license = "MIT"
8
+ include = ["pyproject.toml"]
9
+
10
+
11
+ # =============== MAIN DEPS ==============
12
+ [tool.poetry.dependencies]
13
+ python = ">=3.10,<3.12"
14
+
15
+ # =========== OPTIONALS ==============================
16
+ chromadb = {version=">=0.4.21, <=0.4.23", optional=true}
17
+ momento = {version="^1.10.2", optional=true}
18
+ unstructured = {extras = ["docx", "pptx", "pdf"], version = ">=0.10.16,<0.10.18", optional=true}
19
+ sentence-transformers = {version="2.2.2", optional=true}
20
+ torch = {version="2.0.0", optional=true}
21
+ psycopg2 = {version="^2.9.7", optional=true}
22
+ pymysql = {version = "^1.1.0", optional = true}
23
+ meilisearch = {version="^0.28.3", optional=true}
24
+ meilisearch-python-sdk = {version="^2.2.3", optional=true}
25
+ litellm = {version = "^1.30.1", optional = true}
26
+ metaphor-python = {version = "^0.1.23", optional = true}
27
+ chainlit = {version = "^1.0.400", optional = true}
28
+ python-socketio = {version="^5.11.0", optional=true}
29
+ neo4j = {version = "^5.14.1", optional = true}
30
+ huggingface-hub = {version="^0.21.2", optional=true}
31
+ transformers = {version="^4.40.1", optional=true}
32
+ lancedb = {version="^0.6.2", optional=true}
33
+ tantivy = {version="^0.21.0", optional=true}
34
+ pypdf = {version="^3.12.2", optional=true}
35
+ pymupdf = {version="^1.23.3", optional=true}
36
+ pdf2image = {version="^1.17.0", optional=true}
37
+ pytesseract = {version="^0.3.10", optional=true}
38
+ sqlalchemy = {version="^2.0.19", optional=true}
39
+ pyarrow = {version="15.0.0", optional=true}
40
+ pdfplumber = {version="^0.10.2", optional=true}
41
+ python-docx = {version="^1.1.0", optional=true}
42
+ scrapy = {version="^2.11.0", optional=true}
43
+
44
+ # ====CORE================================
45
+ pyyaml = "^6.0.1"
46
+ onnxruntime = "^1.16.1"
47
+ fire = "^0.5.0"
48
+ bs4 = "^0.0.1"
49
+ python-dotenv = "^1.0.0"
50
+ wget = "^3.2"
51
+ rich = "^13.3.4"
52
+ requests-oauthlib = "^1.3.1"
53
+ trafilatura = "^1.5.0"
54
+ halo = "^0.0.31"
55
+ typer = "^0.9.0"
56
+ colorlog = "^6.7.0"
57
+ openai = "^1.14.0"
58
+ tiktoken = "^0.7.0"
59
+ pygithub = "^1.58.1"
60
+ pygments = "^2.15.1"
61
+ redis = "^5.0.1"
62
+ fakeredis = "^2.12.1"
63
+ faker = "^18.9.0"
64
+ requests = "^2.31.0"
65
+ pyparsing = "^3.0.9"
66
+ nltk = "^3.8.1"
67
+ qdrant-client = "^1.8.0"
68
+ pydantic = "1.10.13"
69
+ pandas = "^2.0.3"
70
+ prettytable = "^3.8.0"
71
+
72
+ google-api-python-client = "^2.95.0"
73
+ lxml = "^4.9.3"
74
+
75
+ rank-bm25 = "^0.2.2"
76
+ thefuzz = "^0.20.0"
77
+
78
+ jinja2 = "^3.1.2"
79
+ docstring-parser = "^0.15"
80
+
81
+ aiohttp = "^3.9.1"
82
+ grpcio = "^1.62.1"
83
+ duckduckgo-search = "^6.0.0"
84
+
85
+ google-generativeai = "^0.5.2"
86
+ groq = "^0.5.0"
87
+ nest-asyncio = "^1.6.0"
88
+ async-generator = "^1.10"
89
+
90
+ python-magic = "^0.4.27"
91
+
92
+ [tool.poetry.extras]
93
+ # install these using, e.g.,
94
+ # `poetry install -E [...]` where [...] is one of the extras below
95
+ # or install multiple extras using, e.g., `poetry install -E "litellm mysql"
96
+
97
+ # Groupings for common use-cases
98
+ doc-chat = [
99
+ "unstructured", "python-docx", "pdfplumber", "pypdf",
100
+ "pymupdf", "pdf2image", "pytesseract"
101
+ ]
102
+ db = ["postgres", "mysql", "sqlalchemy", "psycopg2", "pymysql"]
103
+ hf-transformers = ["sentence-transformers", "torch", "transformers", "huggingface-hub"]
104
+ vecdbs = ["lancedb", "tantivy", "pyarrow", "chromadb"]
105
+ all = [
106
+ "unstructured", "python-docx", "pdfplumber", "pypdf",
107
+ "pymupdf", "pdf2image", "pytesseract",
108
+ "postgres", "mysql", "sqlalchemy", "psycopg2", "pymysql",
109
+ "sentence-transformers", "torch", "transformers", "huggingface-hub",
110
+ "lancedb", "tantivy", "pyarrow", "chromadb",
111
+ "metaphor-python", "neo4j",
112
+ "litellm",
113
+ "chainlit", "python-socketio",
114
+ ]
115
+ # more granular groupings
116
+ lancedb = ["lancedb", "tantivy", "pyarrow"]
117
+ pdf-parsers = ["pdfplumber", "pypdf", "pymupdf", "pdf2image", "pytesseract"]
118
+ docx = ["python-docx"]
119
+ scrapy = ["scrapy"]
120
+ hf-embeddings = ["sentence-transformers", "torch"]
121
+ transformers = ["transformers", "huggingface-hub", "torch"]
122
+ unstructured = ["unstructured"]
123
+ postgres = ["psycopg2"]
124
+ mysql = ["pymysql"]
125
+ sql = ["sqlalchemy", "pymysql", "psycopg2"]
126
+ litellm = ["litellm"]
127
+ neo4j = ["neo4j"]
128
+ metaphor = ["metaphor-python"]
129
+ chainlit = ["chainlit", "python-socketio"]
130
+ chromadb = ["chromadb"]
131
+ mkdocs = [
132
+ "mkdocs", "mkdocs-material", "mkdocstrings", "mkdocs-awesome-pages-plugin",
133
+ "mkdocs-gen-files", "mkdocs-literate-nav",
134
+ "mkdocs-section-index", "mkdocs-jupyter", "mkdocs-rss-plugin"
135
+ ]
136
+ meilisearch = ["meilisearch", "meilisearch-python-sdk"]
137
+ momento = ["momento"]
138
+
139
+
140
+ # ================= DEV DEPS =================
141
+ [tool.poetry.group.dev.dependencies]
142
+ black = {extras = ["jupyter"], version = "^24.3.0"}
143
+ flake8 = "^6.0.0"
144
+ mypy = "^1.7.0"
145
+ ruff = "^0.2.2"
146
+ pre-commit = "^3.3.2"
147
+ autopep8 = "^2.0.2"
148
+
149
+ types-redis = "^4.5.5.2"
150
+ types-requests = "^2.31.0.1"
151
+ types-pyyaml = "^6.0.12.20240311"
152
+ types-pillow = "^10.2.0.20240406"
153
+
154
+ pytest = "^7.3.1"
155
+ pytest-redis = "^3.0.2"
156
+ pytest-asyncio = "^0.21.1"
157
+ pytest-postgresql = "^5.0.0"
158
+ pytest-mysql = "^2.4.2"
159
+ coverage = "^7.2.5"
160
+
161
+ [tool.poetry.group.docs]
162
+ optional = true
163
+
164
+ [tool.poetry.group.docs.dependencies]
165
+
166
+ mkdocs = "^1.4.2"
167
+ mkdocs-material = "^9.1.5"
168
+ mkdocstrings = {extras = ["python"], version = "^0.21.2"}
169
+ mkdocs-awesome-pages-plugin = "^2.8.0"
170
+ mkdocs-rss-plugin = "^1.8.0"
171
+ mkdocs-gen-files = "^0.4.0"
172
+ mkdocs-literate-nav = "^0.6.0"
173
+ mkdocs-section-index = "^0.3.5"
174
+ mkdocs-jupyter = "^0.24.1"
175
+
176
+
177
+
178
+ # ========================================
179
+ [build-system]
180
+ requires = ["poetry-core"]
181
+ build-backend = "poetry.core.masonry.api"
182
+
183
+ [tool.black]
184
+ line-length = 88
185
+ include = '\.pyi?$'
186
+ # extend-exclude = '.*pyi$'
187
+ # exclude = '^stubs/'
188
+
189
+ [tool.pytype]
190
+ inputs = ["langroid"]
191
+
192
+ [tool.mypy]
193
+ python_version = "3.11"
194
+ #mypy_path = ["stubs"]
195
+
196
+ #follow_imports = "skip"
197
+ #check_untyped_defs = "True"
198
+ disallow_untyped_defs = "True"
199
+ ignore_missing_imports = "True"
200
+ warn_unused_ignores = "False"
201
+ strict = true
202
+ exclude = [
203
+ "docs", ".venv", "venv", "examples", "examples_dev", "langroid/utils/web",
204
+ "notebooks",
205
+ "langroid/parsing/repo_loader.py",
206
+ "langroid/embedding_models/clustering.py",
207
+ "langroid/agent/callbacks/chainlit.py",
208
+ "langroid/vector_store/chromadb.py",
209
+ "langroid/embedding_models/protoc" # ignore generated files
210
+ ]
211
+ files=["langroid/*"]
212
+ plugins = [
213
+ "pydantic.mypy"
214
+ ]
215
+
216
+ [tool.ruff]
217
+ line-length = 88
218
+ # Allow unused variables when underscore-prefixed.
219
+ lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
220
+ # Assume Python 3.11.
221
+ target-version = "py311"
222
+ lint.select = [
223
+ "E", # pycodestyle
224
+ "F", # pyflakes
225
+ "I", # isort
226
+ ]
227
+ lint.exclude = ["docs/**", ".venv", "venv", "examples/**", "examples_dev", "langroid/utils/web", "notebooks", "__init__.py", "langroid/embedding_models/protoc/*"]
228
+ lint.fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
229
+ lint.unfixable = []
230
+ lint.extend-ignore = ["F821"]
231
+
232
+ [tool.pytest.ini_options]
233
+ filterwarnings = ["ignore::DeprecationWarning"]