langroid 0.1.39__py3-none-any.whl → 0.1.41__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/base.py CHANGED
@@ -128,9 +128,10 @@ class Agent(ABC):
128
128
  raise ValueError("message_class must be a subclass of ToolMessage")
129
129
  tool = message_class.default_value("request")
130
130
  self.llm_tools_map[tool] = message_class
131
- if hasattr(message_class, "handle"):
131
+ if hasattr(message_class, "handle") and not hasattr(self, tool):
132
132
  """
133
133
  If the message class has a `handle` method,
134
+ and does NOT have a method with the same name as the tool,
134
135
  then we create a method for the agent whose name
135
136
  is the value of `tool`, and whose body is the `handle` method.
136
137
  This removes a separate step of having to define this method
@@ -304,14 +304,21 @@ class DocChatAgent(ChatAgent):
304
304
  )
305
305
 
306
306
  @no_type_check
307
- def answer_from_docs(self, query: str) -> Document:
308
- """Answer query based on docs in vecdb, and conv history"""
309
- response = Document(
310
- content=NO_ANSWER,
311
- metadata=DocMetaData(
312
- source="None",
313
- ),
314
- )
307
+ def get_relevant_extracts(self, query: str) -> List[Document]:
308
+ """
309
+ Get list of docs or extracts relevant to a query. These could be:
310
+ - the original docs, if they exist and are not too long, or
311
+ - a list of doc-chunks retrieved from the VecDB
312
+ that are "relevant" to the query, if these are not too long, or
313
+ - a list of relevant extracts from these doc-chunks
314
+
315
+ Args:
316
+ query (str): query to search for
317
+
318
+ Returns:
319
+ List[Document]: list of relevant docs
320
+
321
+ """
315
322
  if len(self.dialog) > 0 and not self.config.conversation_mode:
316
323
  # In conversation mode, we let self.message_history accumulate
317
324
  # and do not need to convert to standalone query
@@ -324,7 +331,7 @@ class DocChatAgent(ChatAgent):
324
331
 
325
332
  passages = self.original_docs
326
333
 
327
- # if original docs too long, no need to look for relevant parts.
334
+ # if original docs not too long, no need to look for relevant parts.
328
335
  if (
329
336
  passages is None
330
337
  or self.original_docs_length > self.config.max_context_tokens
@@ -335,7 +342,7 @@ class DocChatAgent(ChatAgent):
335
342
  k=self.config.parsing.n_similar_docs,
336
343
  )
337
344
  if len(docs_and_scores) == 0:
338
- return response
345
+ return []
339
346
  passages = [
340
347
  Document(content=d.content, metadata=d.metadata)
341
348
  for (d, _) in docs_and_scores
@@ -347,6 +354,29 @@ class DocChatAgent(ChatAgent):
347
354
  with console.status("[cyan]LLM Extracting verbatim passages..."):
348
355
  with StreamingIfAllowed(self.llm, False):
349
356
  extracts = self.llm.get_verbatim_extracts(query, passages)
357
+
358
+ return extracts
359
+
360
+ @no_type_check
361
+ def answer_from_docs(self, query: str) -> Document:
362
+ """
363
+ Answer query based on relevant docs from the VecDB
364
+
365
+ Args:
366
+ query (str): query to answer
367
+
368
+ Returns:
369
+ Document: answer
370
+ """
371
+ response = Document(
372
+ content=NO_ANSWER,
373
+ metadata=DocMetaData(
374
+ source="None",
375
+ ),
376
+ )
377
+ extracts = self.get_relevant_extracts(query)
378
+ if len(extracts) == 0:
379
+ return response
350
380
  with ExitStack() as stack:
351
381
  # conditionally use Streaming or rich console context
352
382
  cm = (
@@ -97,7 +97,7 @@ class RetrieverAgent(DocChatAgent, ABC):
97
97
  query_str = query.content
98
98
  else:
99
99
  query_str = query
100
- docs = self.get_relevant_docs(query_str)
100
+ docs = self.get_relevant_extracts(query_str)
101
101
  if len(docs) == 0:
102
102
  return None
103
103
  content = "\n\n".join([d.content for d in docs])
@@ -135,7 +135,7 @@ class RetrieverAgent(DocChatAgent, ABC):
135
135
  ]
136
136
  return docs
137
137
 
138
- def get_relevant_docs(self, query: str) -> List[Document]:
138
+ def get_relevant_extracts(self, query: str) -> List[Document]:
139
139
  """
140
140
  Given a query, get the records/docs whose contents are most relevant to the
141
141
  query. First get nearest docs from vector store, then select the best
@@ -28,9 +28,9 @@ console = Console()
28
28
 
29
29
  DEFAULT_SQL_CHAT_SYSTEM_MESSAGE = """
30
30
  You are a savvy data scientist/database administrator, with expertise in
31
- answering questions by querying a SQL database.
31
+ answering questions by querying a {dialect} database.
32
32
  You do not have access to the database 'db' directly, so you will need to use the
33
- `run_query` tool/function-call to answer the question.
33
+ `run_query` tool/function-call to answer questions.
34
34
 
35
35
  The below JSON schema maps the SQL database structure. It outlines tables, each
36
36
  with a description and columns. Each table is identified by a key,
@@ -146,7 +146,7 @@ class SQLChatAgent(ChatAgent):
146
146
 
147
147
  # Update the system message with the table information
148
148
  self.config.system_message = self.config.system_message.format(
149
- schema_dict=schema_dict
149
+ schema_dict=schema_dict, dialect=self.engine.dialect.name
150
150
  )
151
151
 
152
152
  super().__init__(config)
@@ -10,7 +10,9 @@ the code and returns the result as a string.
10
10
  import io
11
11
  import logging
12
12
  import sys
13
+ from typing import no_type_check
13
14
 
15
+ import numpy as np
14
16
  import pandas as pd
15
17
  from rich.console import Console
16
18
 
@@ -26,16 +28,72 @@ logger = logging.getLogger(__name__)
26
28
  console = Console()
27
29
 
28
30
  DEFAULT_TABLE_CHAT_SYSTEM_MESSAGE = """
29
- You are a savvy data scientist, with expertise in analyzing tabular dataset,
31
+ You are a savvy data scientist, with expertise in analyzing tabular datasets,
30
32
  using Python and the Pandas library for dataframe manipulation.
31
33
  Since you do not have access to the dataframe 'df', you
32
34
  will need to use the `run_code` tool/function-call to answer the question.
33
- The columns in the dataframe are:
34
- {columns}
35
+ Here is a summary of the dataframe:
36
+ {summary}
35
37
  Do not assume any columns other than those shown.
38
+ In the code you submit to the `run_code` tool/function,
39
+ do not forget to include any necessary imports, such as `import pandas as pd`.
40
+ Sometimes you may not be able to answer the question in a single call to `run_code`,
41
+ so you can use a series of calls to `run_code` to build up the answer.
42
+ For example you may first want to know something about the possible values in a column.
43
+
44
+ If you receive a null or other unexpected result, see if you have made an assumption
45
+ in your code, and try another way, or use `run_code` to explore the dataframe
46
+ before submitting your final code.
47
+
48
+ Start by asking me what I want to know about the data.
36
49
  """
37
50
 
38
51
 
52
+ @no_type_check
53
+ def dataframe_summary(df: pd.DataFrame) -> str:
54
+ """
55
+ Generate a structured summary for a pandas DataFrame containing numerical
56
+ and categorical values.
57
+
58
+ Args:
59
+ df (pd.DataFrame): The input DataFrame to summarize.
60
+
61
+ Returns:
62
+ str: A nicely structured and formatted summary string.
63
+ """
64
+
65
+ # Column names display
66
+ col_names_str = (
67
+ "COLUMN NAMES:\n" + " ".join([f"'{col}'" for col in df.columns]) + "\n\n"
68
+ )
69
+
70
+ # Numerical data summary
71
+ num_summary = df.describe().applymap(lambda x: "{:.2f}".format(x))
72
+ num_str = "Numerical Column Summary:\n" + num_summary.to_string() + "\n\n"
73
+
74
+ # Categorical data summary
75
+ cat_columns = df.select_dtypes(include=[np.object_]).columns
76
+ cat_summary_list = []
77
+
78
+ for col in cat_columns:
79
+ unique_values = df[col].unique()
80
+ if len(unique_values) < 10:
81
+ cat_summary_list.append(f"'{col}': {', '.join(map(str, unique_values))}")
82
+ else:
83
+ cat_summary_list.append(f"'{col}': {df[col].nunique()} unique values")
84
+
85
+ cat_str = "Categorical Column Summary:\n" + "\n".join(cat_summary_list) + "\n\n"
86
+
87
+ # Missing values summary
88
+ nan_summary = df.isnull().sum().rename("missing_values").to_frame()
89
+ nan_str = "Missing Values Column Summary:\n" + nan_summary.to_string() + "\n"
90
+
91
+ # Combine the summaries into one structured string
92
+ summary_str = col_names_str + num_str + cat_str + nan_str
93
+
94
+ return summary_str
95
+
96
+
39
97
  class TableChatAgentConfig(ChatAgentConfig):
40
98
  system_message: str = DEFAULT_TABLE_CHAT_SYSTEM_MESSAGE
41
99
  user_message: None | str = None
@@ -77,10 +135,8 @@ class TableChatAgent(ChatAgent):
77
135
  df = read_tabular_data(config.data, config.separator)
78
136
 
79
137
  self.df = df
80
- columns_with_quotes = [f"'{c}'" for c in df.columns]
81
- config.system_message = config.system_message.format(
82
- columns=", ".join(columns_with_quotes)
83
- )
138
+ summary = dataframe_summary(df)
139
+ config.system_message = config.system_message.format(summary=summary)
84
140
 
85
141
  super().__init__(config)
86
142
  self.config: TableChatAgentConfig = config
@@ -1,61 +1,16 @@
1
- import os
2
- from typing import Dict, List
1
+ """
2
+ A tool to trigger a Google 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(GoogleSearchTool)`
3
6
 
4
- import requests
5
- from bs4 import BeautifulSoup
6
- from dotenv import load_dotenv
7
- from googleapiclient.discovery import Resource, build
8
- from requests.models import Response
7
+ NOTE: Using this tool requires setting the GOOGLE_API_KEY and GOOGLE_CSE_ID
8
+ environment variables in your `.env` file, as explained in the
9
+ [README](https://github.com/langroid/langroid#gear-installation-and-setup).
10
+ """
9
11
 
10
12
  from langroid.agent.tool_message import ToolMessage
11
-
12
-
13
- class GoogleSearchResult:
14
- """
15
- Class representing a Google Search result, containing the title, link,
16
- summary and full content of the result.
17
- """
18
-
19
- def __init__(
20
- self,
21
- title: str,
22
- link: str,
23
- max_content_length: int = 3500,
24
- max_summary_length: int = 300,
25
- ):
26
- """
27
- Args:
28
- title (str): The title of the search result.
29
- link (str): The link to the search result.
30
- max_content_length (int): The maximum length of the full content.
31
- max_summary_length (int): The maximum length of the summary.
32
- """
33
- self.title = title
34
- self.link = link
35
- self.max_content_length = max_content_length
36
- self.max_summary_length = max_summary_length
37
- self.full_content = self.get_full_content()
38
- self.summary = self.get_summary()
39
-
40
- def get_summary(self) -> str:
41
- return self.full_content[: self.max_summary_length]
42
-
43
- def get_full_content(self) -> str:
44
- response: Response = requests.get(self.link)
45
- soup: BeautifulSoup = BeautifulSoup(response.text, "lxml")
46
- text = " ".join(soup.stripped_strings)
47
- return text[: self.max_content_length]
48
-
49
- def __str__(self) -> str:
50
- return f"Title: {self.title}\nLink: {self.link}\nSummary: {self.summary}"
51
-
52
- def to_dict(self) -> Dict[str, str]:
53
- return {
54
- "title": self.title,
55
- "link": self.link,
56
- "summary": self.summary,
57
- "full_content": self.full_content,
58
- }
13
+ from langroid.parsing.web_search import google_search
59
14
 
60
15
 
61
16
  class GoogleSearchTool(ToolMessage):
@@ -68,19 +23,6 @@ class GoogleSearchTool(ToolMessage):
68
23
  num_results: int
69
24
 
70
25
  def handle(self) -> str:
71
- load_dotenv()
72
- api_key = os.getenv("GOOGLE_API_KEY")
73
- cse_id = os.getenv("GOOGLE_CSE_ID")
74
- service: Resource = build("customsearch", "v1", developerKey=api_key)
75
- raw_results = (
76
- service.cse()
77
- .list(q=self.query, cx=cse_id, num=self.num_results)
78
- .execute()["items"]
79
- )
80
-
81
- search_results: List[GoogleSearchResult] = [
82
- GoogleSearchResult(result["title"], result["link"], 3500, 300)
83
- for result in raw_results
84
- ]
85
- # return Title and Link of each result, separated by two newlines
26
+ search_results = google_search(self.query, self.num_results)
27
+ # return Title, Link, Summary of each result, separated by two newlines
86
28
  return "\n\n".join(str(result) for result in search_results)
@@ -4,7 +4,7 @@ import logging
4
4
  import os
5
5
  import sys
6
6
  from enum import Enum
7
- from typing import Any, Dict, List, Optional, Tuple, Union, cast
7
+ from typing import Any, Dict, List, Optional, Tuple, Union
8
8
 
9
9
  import openai
10
10
  from dotenv import load_dotenv
@@ -361,13 +361,13 @@ class OpenAIGPT(LanguageModel):
361
361
  LLMResponse object
362
362
  """
363
363
  openai.api_key = self.api_key
364
- if type(messages) == str:
364
+ if isinstance(messages, str):
365
365
  llm_messages = [
366
366
  LLMMessage(role=Role.SYSTEM, content="You are a helpful assistant."),
367
367
  LLMMessage(role=Role.USER, content=messages),
368
368
  ]
369
369
  else:
370
- llm_messages = cast(List[LLMMessage], messages)
370
+ llm_messages = messages
371
371
 
372
372
  @retry_with_exponential_backoff
373
373
  def completions_with_backoff(**kwargs): # type: ignore
@@ -0,0 +1,79 @@
1
+ """
2
+ Utilities for web search.
3
+
4
+ NOTE: Using Google Search requires setting the GOOGLE_API_KEY and GOOGLE_CSE_ID
5
+ environment variables in your `.env` file, as explained in the
6
+ [README](https://github.com/langroid/langroid#gear-installation-and-setup).
7
+ """
8
+
9
+ import os
10
+ from typing import Dict, List
11
+
12
+ import requests
13
+ from bs4 import BeautifulSoup
14
+ from dotenv import load_dotenv
15
+ from googleapiclient.discovery import Resource, build
16
+ from requests.models import Response
17
+
18
+
19
+ class WebSearchResult:
20
+ """
21
+ Class representing a Web Search result, containing the title, link,
22
+ summary and full content of the result.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ title: str,
28
+ link: str,
29
+ max_content_length: int = 3500,
30
+ max_summary_length: int = 300,
31
+ ):
32
+ """
33
+ Args:
34
+ title (str): The title of the search result.
35
+ link (str): The link to the search result.
36
+ max_content_length (int): The maximum length of the full content.
37
+ max_summary_length (int): The maximum length of the summary.
38
+ """
39
+ self.title = title
40
+ self.link = link
41
+ self.max_content_length = max_content_length
42
+ self.max_summary_length = max_summary_length
43
+ self.full_content = self.get_full_content()
44
+ self.summary = self.get_summary()
45
+
46
+ def get_summary(self) -> str:
47
+ return self.full_content[: self.max_summary_length]
48
+
49
+ def get_full_content(self) -> str:
50
+ response: Response = requests.get(self.link)
51
+ soup: BeautifulSoup = BeautifulSoup(response.text, "lxml")
52
+ text = " ".join(soup.stripped_strings)
53
+ return text[: self.max_content_length]
54
+
55
+ def __str__(self) -> str:
56
+ return f"Title: {self.title}\nLink: {self.link}\nSummary: {self.summary}"
57
+
58
+ def to_dict(self) -> Dict[str, str]:
59
+ return {
60
+ "title": self.title,
61
+ "link": self.link,
62
+ "summary": self.summary,
63
+ "full_content": self.full_content,
64
+ }
65
+
66
+
67
+ def google_search(query: str, num_results: int = 5) -> List[WebSearchResult]:
68
+ load_dotenv()
69
+ api_key = os.getenv("GOOGLE_API_KEY")
70
+ cse_id = os.getenv("GOOGLE_CSE_ID")
71
+ service: Resource = build("customsearch", "v1", developerKey=api_key)
72
+ raw_results = (
73
+ service.cse().list(q=query, cx=cse_id, num=num_results).execute()["items"]
74
+ )
75
+
76
+ return [
77
+ WebSearchResult(result["title"], result["link"], 3500, 300)
78
+ for result in raw_results
79
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.1.39
3
+ Version: 0.1.41
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -39,6 +39,7 @@ Requires-Dist: openai (>=0.27.5,<0.28.0)
39
39
  Requires-Dist: pandas (>=2.0.3,<3.0.0)
40
40
  Requires-Dist: pre-commit (>=3.3.2,<4.0.0)
41
41
  Requires-Dist: prettytable (>=3.8.0,<4.0.0)
42
+ Requires-Dist: psycopg2 (>=2.9.7,<3.0.0)
42
43
  Requires-Dist: pydantic (==1.10.11)
43
44
  Requires-Dist: pygithub (>=1.58.1,<2.0.0)
44
45
  Requires-Dist: pygments (>=2.15.1,<3.0.0)
@@ -77,6 +78,8 @@ Description-Content-Type: text/markdown
77
78
  [![Static Badge](https://img.shields.io/badge/Discord-orange?logoColor=orange&link=https%3A%2F%2Fdiscord.gg%2FZU36McDgDs)](https://discord.gg/ZU36McDgDs)
78
79
  [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langroid/langroid/blob/main/examples/langroid_quick_examples.ipynb)
79
80
 
81
+ [![Share on Twitter](https://img.shields.io/twitter/url?style=social&url=https://github.com/langroid/langroid)](https://twitter.com/intent/tweet?text=Langroid%20is%20a%20powerful,%20elegant%20new%20framework%20to%20easily%20build%20%23LLM%20applications.%20You%20set%20up%20LLM-powered%20Agents%20with%20vector-stores,%20assign%20tasks,%20and%20have%20them%20collaboratively%20solve%20problems%20via%20message-transformations.%20https://github.com/langroid/langroid)
82
+ [![Share on LinkedIn](https://img.shields.io/badge/Share%20on-LinkedIn-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https://github.com/langroid/langroid&title=Langroid:%20A%20Powerful,%20Elegant%20Framework&summary=Langroid%20is%20a%20powerful,%20elegant%20new%20framework%20to%20easily%20build%20%23LLM%20applications.%20You%20set%20up%20LLM-powered%20Agents%20with%20vector-stores,%20assign%20tasks,%20and%20have%20them%20collaboratively%20solve%20problems%20via%20message-transformations.)
80
83
 
81
84
  </div>
82
85
 
@@ -114,7 +117,8 @@ for ideas on what to contribute.
114
117
  <summary> <b>:fire: Updates/Releases</b></summary>
115
118
 
116
119
  - **Aug 2023:**
117
- - **0.1.38:** [`GoogleSearchTool`](langroid/agent/stateless_tools/google_search_tool.py) to enable Agents (their LLM) to do Google searches via function-calling/tools.
120
+ - **Example:** [Answer questions](examples/docqa/chat-search.py) using Google Search + vecdb-retrieval from URL contents.
121
+ - **0.1.39:** [`GoogleSearchTool`](langroid/agent/stateless_tools/google_search_tool.py) to enable Agents (their LLM) to do Google searches via function-calling/tools.
118
122
  See [this chat example](examples/basic/chat-search.py) for how easy it is to add this tool to an agent.
119
123
  - **Colab notebook** to try the quick-start examples: [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/langroid/langroid/blob/main/examples/langroid_quick_examples.ipynb)
120
124
  - **0.1.37:** Added [`SQLChatAgent`](langroid/agent/special/sql_chat_agent.py) -- thanks to our latest contributor [Rithwik Babu](https://github.com/rithwikbabu)!
@@ -232,7 +236,8 @@ export OPENAI_API_KEY=your-key-here-without-quotes
232
236
  <details>
233
237
  <summary><b>Optional Setup Instructions (click to expand) </b></summary>
234
238
 
235
- All of the below are optional and not strictly needed to run any of the examples.
239
+ All of the following environment variable settings are optional, and some are only needed
240
+ to use specific features (as noted below).
236
241
 
237
242
  - **Qdrant** Vector Store API Key, URL. This is only required if you want to use Qdrant cloud.
238
243
  You can sign up for a free 1GB account at [Qdrant cloud](https://cloud.qdrant.io).
@@ -357,8 +362,6 @@ task.run() # ... a loop seeking response from LLM or User at each turn
357
362
  <details>
358
363
  <summary><b> Three communicating agents </b></summary>
359
364
 
360
- ```python
361
-
362
365
  A toy numbers game, where when given a number `n`:
363
366
  - `repeater_agent`'s LLM simply returns `n`,
364
367
  - `even_agent`'s LLM returns `n/2` if `n` is even, else says "DO-NOT-KNOW"
@@ -663,13 +666,24 @@ script in the `langroid-examples` repo.
663
666
 
664
667
  # :heart: Thank you to our [supporters](https://github.com/langroid/langroid/stargazers)
665
668
 
666
- If you like this repo, don't forget to leave a star :star: !
669
+ If you like this project, please give it a star ⭐ and 📢 spread the word in your network:
670
+
671
+ [![Share on Twitter](https://img.shields.io/twitter/url?style=social&url=https://github.com/langroid/langroid)](https://twitter.com/intent/tweet?text=Langroid%20is%20a%20powerful,%20elegant%20new%20framework%20to%20easily%20build%20%23LLM%20applications.%20You%20set%20up%20LLM-powered%20Agents%20with%20vector-stores,%20assign%20tasks,%20and%20have%20them%20collaboratively%20solve%20problems%20via%20message-transformations.%20https://github.com/langroid/langroid)
672
+ [![Share on LinkedIn](https://img.shields.io/badge/Share%20on-LinkedIn-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https://github.com/langroid/langroid&title=Langroid:%20A%20Powerful,%20Elegant%20Framework&summary=Langroid%20is%20a%20powerful,%20elegant%20new%20framework%20to%20easily%20build%20%23LLM%20applications.%20You%20set%20up%20LLM-powered%20Agents%20with%20vector-stores,%20assign%20tasks,%20and%20have%20them%20collaboratively%20solve%20problems%20via%20message-transformations.)
673
+
674
+
675
+
676
+
677
+ Your support will help build Langroid's momentum and community.
678
+
679
+
680
+
681
+
682
+ # Langroid Co-Founders
683
+
684
+ - [Prasad Chalasani](https://www.linkedin.com/in/pchalasani/) (IIT BTech/CS, CMU PhD/ML; Independent ML Consultant)
685
+ - [Somesh Jha](https://www.linkedin.com/in/somesh-jha-80208015/) (IIT BTech/CS, CMU PhD/CS; Professor of CS, U Wisc at Madison)
667
686
 
668
- # Contributors
669
687
 
670
- - Prasad Chalasani (IIT BTech/CS, CMU PhD/ML; Independent ML Consultant)
671
- - Somesh Jha (IIT BTech/CS, CMU PhD/CS; Professor of CS, U Wisc at Madison)
672
- - Mohannad Alhanahnah (Research Associate, U Wisc at Madison)
673
- - Ashish Hooda (IIT BTech/CS; PhD Candidate, U Wisc at Madison)
674
688
 
675
689
 
@@ -1,18 +1,18 @@
1
1
  langroid/__init__.py,sha256=sEKJ_5WJBAMZApevfeE3gxLK-eotVzJMJlT83G0rAko,30
2
2
  langroid/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- langroid/agent/base.py,sha256=TpCp7I1480RcCLzHJ4g1TUS2wH3kz5o2KzElFPehuBc,22466
3
+ langroid/agent/base.py,sha256=fWlSdA1omU9TcuphtRzREwvBZ_ZoMo7yOowplpsadN0,22569
4
4
  langroid/agent/chat_agent.py,sha256=mLCHlYxU1lB7PGOLjjkaEQUqMNKcq0-HOjlG4ZcDjQE,20522
5
5
  langroid/agent/chat_document.py,sha256=Rj7Hfp_FrNjuKsTMA3KyZhno5zKpmvnPPk7WgAuAF2Y,5745
6
6
  langroid/agent/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  langroid/agent/junk,sha256=LxfuuW7Cijsg0szAzT81OjWWv1PMNI-6w_-DspVIO2s,339
8
8
  langroid/agent/special/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- langroid/agent/special/doc_chat_agent.py,sha256=NhoS02rlLr3nAfRvLB1YNcmfsWZJH24K8O-m-uYnb-I,15741
9
+ langroid/agent/special/doc_chat_agent.py,sha256=FjuHxV6OyHvPcHuPgsm9kXMIL8qVhOM8oa-oYdzXzN8,16568
10
10
  langroid/agent/special/recipient_validator_agent.py,sha256=x2UprcGlh-fyxQCZbb_fkKrruU5Om0mgOnNzk_PYBNM,4527
11
- langroid/agent/special/retriever_agent.py,sha256=dkG_-QdL5KvpeS4K4jnx1kV9h_KxVEhgHz2rzdilZss,7196
12
- langroid/agent/special/sql_chat_agent.py,sha256=DNbz60O1HvGgWpsgYgCKE4GU7FqBoUeyZxfTbBHQ7gg,10178
13
- langroid/agent/special/table_chat_agent.py,sha256=FRkeEMvJxFievRgwschphIVNYYTLmheEyn7RQCggXdg,4953
11
+ langroid/agent/special/retriever_agent.py,sha256=DeOB5crFjXBvDEZT9k9ZVinOfFM2VgS6tQWWFyXSk9o,7204
12
+ langroid/agent/special/sql_chat_agent.py,sha256=2pw8o-0ul909HAOUO3G7SVVAaB3qVBkjtaXneNzy1x0,10215
13
+ langroid/agent/special/table_chat_agent.py,sha256=L0T6Tj_3AMckwWI2HTb19hyp7r3P77KEFMldkT3acUU,7058
14
14
  langroid/agent/stateless_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- langroid/agent/stateless_tools/google_search_tool.py,sha256=riNFJEMNVdJuy4hSUUaH8Iz1hJqI_rGyrdcT6XXp_Sc,2770
15
+ langroid/agent/stateless_tools/google_search_tool.py,sha256=64F9oMNdS237BBOitrvYXN4Il_ES_fNrHkh35tBEDfA,1160
16
16
  langroid/agent/task.py,sha256=KJZt6lSfCAVctyFfBJWLFcfys73kjrQJV4Y3aMVwO1M,26233
17
17
  langroid/agent/tool_message.py,sha256=7OdVcV7UyOZD2ihYgV1C_1fIwiWM-2pR8FFxoA1IgOo,5379
18
18
  langroid/agent_config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -26,7 +26,7 @@ langroid/embedding_models/clustering.py,sha256=tZWElUqXl9Etqla0FAa7og96iDKgjqWju
26
26
  langroid/embedding_models/models.py,sha256=1xcv9hqmCTsbUbS8v7XeZRsf25Tu79JUoSipIYpvNoo,2765
27
27
  langroid/language_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  langroid/language_models/base.py,sha256=7FMiUyJ3Kf9Uiqvjh-lNGfwnCibY0SbnK4jdORCv3SM,12657
29
- langroid/language_models/openai_gpt.py,sha256=TuertCPkjJzz35YYGHTwX2E5gevENEPdPoFVyGl8M6k,17973
29
+ langroid/language_models/openai_gpt.py,sha256=L5Lm3ApOflqMI3405rR5Wp6tAFKTGsPc0iQAVNdV9N8,17947
30
30
  langroid/language_models/utils.py,sha256=rmnSn-sJ3aKl_wBdeLPkck0Li4Ed6zkCxZYYl7n1V34,4668
31
31
  langroid/mytypes.py,sha256=YA42IJcooJnTxAwk-B4FmZ1hqzIIF1ZZKcpUKzBTGGo,1537
32
32
  langroid/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,6 +43,7 @@ langroid/parsing/url_loader.py,sha256=tdYPMC2V9zI_B207LFdU4aroZzJW4sY9y794XePFAV
43
43
  langroid/parsing/url_loader_cookies.py,sha256=Lg4sNpRz9MByWq2mde6T0hKv68VZSV3mtMjNEHuFeSU,2327
44
44
  langroid/parsing/urls.py,sha256=_Bcf1iRdT7cQrQ8hnbPX0Jtzxc0lVFaucTS5rJoKA14,3709
45
45
  langroid/parsing/utils.py,sha256=__1Z6mFHk_TqHQY-9uU1aV_bIXeYw8H7NEXagUOEX0I,1818
46
+ langroid/parsing/web_search.py,sha256=hGUVoSJNdpoT5rsm-ikAteMiUropHrzKaxN8EVVqO2U,2496
46
47
  langroid/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
48
  langroid/prompts/dialog.py,sha256=SpfiSyofSgy2pwD1YboHR_yHO3LEEMbv6j2sm874jKo,331
48
49
  langroid/prompts/prompts_config.py,sha256=EMK1Fm7EmS8y3CV4AkrVgn5K4NipiM4m7J8819W1KeM,98
@@ -67,7 +68,7 @@ langroid/vector_store/base.py,sha256=QZx3NUNwf2I0r3A7iuoUHIRGbqt_pFGD0hq1R-Yg8iM
67
68
  langroid/vector_store/chromadb.py,sha256=s5pQkKjaMP-Tt5A8M10EInFzttaALPbJAq7q4gf0TKg,5235
68
69
  langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
69
70
  langroid/vector_store/qdrantdb.py,sha256=KRvIIj1IZG2zFqejofMnRs2hT86B-27LgBEnuczdqOU,9072
70
- langroid-0.1.39.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
71
- langroid-0.1.39.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
72
- langroid-0.1.39.dist-info/METADATA,sha256=Sgv3L8vKuyQnNHCvbZFsfM2rmFp4MuUlxOCuuyJHG4I,27527
73
- langroid-0.1.39.dist-info/RECORD,,
71
+ langroid-0.1.41.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
72
+ langroid-0.1.41.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
73
+ langroid-0.1.41.dist-info/METADATA,sha256=eIqNnzfP3fq3V05ResrFM7U8k16CYgJ8Je4VTZEjqLo,29766
74
+ langroid-0.1.41.dist-info/RECORD,,