langroid 0.1.85__py3-none-any.whl → 0.1.219__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.
Files changed (107) hide show
  1. langroid/__init__.py +95 -0
  2. langroid/agent/__init__.py +40 -0
  3. langroid/agent/base.py +222 -91
  4. langroid/agent/batch.py +264 -0
  5. langroid/agent/callbacks/chainlit.py +608 -0
  6. langroid/agent/chat_agent.py +247 -101
  7. langroid/agent/chat_document.py +41 -4
  8. langroid/agent/openai_assistant.py +842 -0
  9. langroid/agent/special/__init__.py +50 -0
  10. langroid/agent/special/doc_chat_agent.py +837 -141
  11. langroid/agent/special/lance_doc_chat_agent.py +258 -0
  12. langroid/agent/special/lance_rag/__init__.py +9 -0
  13. langroid/agent/special/lance_rag/critic_agent.py +136 -0
  14. langroid/agent/special/lance_rag/lance_rag_task.py +80 -0
  15. langroid/agent/special/lance_rag/query_planner_agent.py +180 -0
  16. langroid/agent/special/lance_tools.py +44 -0
  17. langroid/agent/special/neo4j/__init__.py +0 -0
  18. langroid/agent/special/neo4j/csv_kg_chat.py +174 -0
  19. langroid/agent/special/neo4j/neo4j_chat_agent.py +370 -0
  20. langroid/agent/special/neo4j/utils/__init__.py +0 -0
  21. langroid/agent/special/neo4j/utils/system_message.py +46 -0
  22. langroid/agent/special/relevance_extractor_agent.py +127 -0
  23. langroid/agent/special/retriever_agent.py +32 -198
  24. langroid/agent/special/sql/__init__.py +11 -0
  25. langroid/agent/special/sql/sql_chat_agent.py +47 -23
  26. langroid/agent/special/sql/utils/__init__.py +22 -0
  27. langroid/agent/special/sql/utils/description_extractors.py +95 -46
  28. langroid/agent/special/sql/utils/populate_metadata.py +28 -21
  29. langroid/agent/special/table_chat_agent.py +43 -9
  30. langroid/agent/task.py +475 -122
  31. langroid/agent/tool_message.py +75 -13
  32. langroid/agent/tools/__init__.py +13 -0
  33. langroid/agent/tools/duckduckgo_search_tool.py +66 -0
  34. langroid/agent/tools/google_search_tool.py +11 -0
  35. langroid/agent/tools/metaphor_search_tool.py +67 -0
  36. langroid/agent/tools/recipient_tool.py +16 -29
  37. langroid/agent/tools/run_python_code.py +60 -0
  38. langroid/agent/tools/sciphi_search_rag_tool.py +79 -0
  39. langroid/agent/tools/segment_extract_tool.py +36 -0
  40. langroid/cachedb/__init__.py +9 -0
  41. langroid/cachedb/base.py +22 -2
  42. langroid/cachedb/momento_cachedb.py +26 -2
  43. langroid/cachedb/redis_cachedb.py +78 -11
  44. langroid/embedding_models/__init__.py +34 -0
  45. langroid/embedding_models/base.py +21 -2
  46. langroid/embedding_models/models.py +120 -18
  47. langroid/embedding_models/protoc/embeddings.proto +19 -0
  48. langroid/embedding_models/protoc/embeddings_pb2.py +33 -0
  49. langroid/embedding_models/protoc/embeddings_pb2.pyi +50 -0
  50. langroid/embedding_models/protoc/embeddings_pb2_grpc.py +79 -0
  51. langroid/embedding_models/remote_embeds.py +153 -0
  52. langroid/language_models/__init__.py +45 -0
  53. langroid/language_models/azure_openai.py +80 -27
  54. langroid/language_models/base.py +117 -12
  55. langroid/language_models/config.py +5 -0
  56. langroid/language_models/openai_assistants.py +3 -0
  57. langroid/language_models/openai_gpt.py +558 -174
  58. langroid/language_models/prompt_formatter/__init__.py +15 -0
  59. langroid/language_models/prompt_formatter/base.py +4 -6
  60. langroid/language_models/prompt_formatter/hf_formatter.py +135 -0
  61. langroid/language_models/utils.py +18 -21
  62. langroid/mytypes.py +25 -8
  63. langroid/parsing/__init__.py +46 -0
  64. langroid/parsing/document_parser.py +260 -63
  65. langroid/parsing/image_text.py +32 -0
  66. langroid/parsing/parse_json.py +143 -0
  67. langroid/parsing/parser.py +122 -59
  68. langroid/parsing/repo_loader.py +114 -52
  69. langroid/parsing/search.py +68 -63
  70. langroid/parsing/spider.py +3 -2
  71. langroid/parsing/table_loader.py +44 -0
  72. langroid/parsing/url_loader.py +59 -11
  73. langroid/parsing/urls.py +85 -37
  74. langroid/parsing/utils.py +298 -4
  75. langroid/parsing/web_search.py +73 -0
  76. langroid/prompts/__init__.py +11 -0
  77. langroid/prompts/chat-gpt4-system-prompt.md +68 -0
  78. langroid/prompts/prompts_config.py +1 -1
  79. langroid/utils/__init__.py +17 -0
  80. langroid/utils/algorithms/__init__.py +3 -0
  81. langroid/utils/algorithms/graph.py +103 -0
  82. langroid/utils/configuration.py +36 -5
  83. langroid/utils/constants.py +4 -0
  84. langroid/utils/globals.py +2 -2
  85. langroid/utils/logging.py +2 -5
  86. langroid/utils/output/__init__.py +21 -0
  87. langroid/utils/output/printing.py +47 -1
  88. langroid/utils/output/status.py +33 -0
  89. langroid/utils/pandas_utils.py +30 -0
  90. langroid/utils/pydantic_utils.py +616 -2
  91. langroid/utils/system.py +98 -0
  92. langroid/vector_store/__init__.py +40 -0
  93. langroid/vector_store/base.py +203 -6
  94. langroid/vector_store/chromadb.py +59 -32
  95. langroid/vector_store/lancedb.py +463 -0
  96. langroid/vector_store/meilisearch.py +10 -7
  97. langroid/vector_store/momento.py +262 -0
  98. langroid/vector_store/qdrantdb.py +104 -22
  99. {langroid-0.1.85.dist-info → langroid-0.1.219.dist-info}/METADATA +329 -149
  100. langroid-0.1.219.dist-info/RECORD +127 -0
  101. {langroid-0.1.85.dist-info → langroid-0.1.219.dist-info}/WHEEL +1 -1
  102. langroid/agent/special/recipient_validator_agent.py +0 -157
  103. langroid/parsing/json.py +0 -64
  104. langroid/utils/web/selenium_login.py +0 -36
  105. langroid-0.1.85.dist-info/RECORD +0 -94
  106. /langroid/{scripts → agent/callbacks}/__init__.py +0 -0
  107. {langroid-0.1.85.dist-info → langroid-0.1.219.dist-info}/LICENSE +0 -0
@@ -1,7 +1,9 @@
1
+ import copy
1
2
  import os
2
- from typing import List
3
+ from contextlib import contextmanager
4
+ from typing import Iterator, List, Literal
3
5
 
4
- from dotenv import load_dotenv
6
+ from dotenv import find_dotenv, load_dotenv
5
7
  from pydantic import BaseSettings
6
8
 
7
9
 
@@ -12,17 +14,18 @@ class Settings(BaseSettings):
12
14
  progress: bool = False # show progress spinners/bars?
13
15
  stream: bool = True # stream output?
14
16
  cache: bool = True # use cache?
15
- cache_type: str = "redis" # cache type: "redis" or "momento"
17
+ cache_type: Literal["redis", "fakeredis", "momento"] = "redis" # cache type
16
18
  interactive: bool = True # interactive mode?
17
19
  gpt3_5: bool = True # use GPT-3.5?
18
- nofunc: bool = False # use model without function_call? (i.e. gpt-4)
19
20
  chat_model: str = "" # language model name, e.g. litellm/ollama/llama2
21
+ quiet: bool = False # quiet mode (i.e. suppress all output)?
22
+ notebook: bool = False # running in a notebook?
20
23
 
21
24
  class Config:
22
25
  extra = "forbid"
23
26
 
24
27
 
25
- load_dotenv() # get settings from .env file
28
+ load_dotenv(find_dotenv(usecwd=True)) # get settings from .env file
26
29
  settings = Settings()
27
30
 
28
31
 
@@ -55,6 +58,34 @@ def set_global(key_vals: Settings) -> None:
55
58
  settings.__dict__.update(key_vals.__dict__)
56
59
 
57
60
 
61
+ @contextmanager
62
+ def temporary_settings(temp_settings: Settings) -> Iterator[None]:
63
+ """Temporarily update the global settings and restore them afterward."""
64
+ original_settings = copy.deepcopy(settings)
65
+
66
+ set_global(temp_settings)
67
+
68
+ try:
69
+ yield
70
+ finally:
71
+ settings.__dict__.update(original_settings.__dict__)
72
+
73
+
74
+ @contextmanager
75
+ def quiet_mode(quiet: bool = True) -> Iterator[None]:
76
+ """Temporarily set quiet=True in global settings and restore afterward."""
77
+ original_settings = copy.deepcopy(settings)
78
+ if quiet:
79
+ temp_settings = original_settings.copy(update={"quiet": True})
80
+ set_global(temp_settings)
81
+
82
+ try:
83
+ yield
84
+ finally:
85
+ if quiet:
86
+ settings.__dict__.update(original_settings.__dict__)
87
+
88
+
58
89
  def set_env(settings: BaseSettings) -> None:
59
90
  """
60
91
  Set environment variables from a BaseSettings instance
@@ -16,3 +16,7 @@ class Colors(BaseModel):
16
16
  USER_QUIT = ["q", "x", "quit", "exit", "bye"]
17
17
  NO_ANSWER = "DO-NOT-KNOW"
18
18
  DONE = "DONE"
19
+ PASS = "__PASS__"
20
+ PASS_TO = PASS + ":"
21
+ SEND_TO = "SEND:"
22
+ TOOL = "TOOL"
langroid/utils/globals.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Any, Optional, Type, TypeVar
1
+ from typing import Any, Dict, Optional, Type, TypeVar
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
@@ -23,7 +23,7 @@ class GlobalState(BaseModel):
23
23
  return cls._instance
24
24
 
25
25
  @classmethod
26
- def set_values(cls: Type[T], **kwargs) -> None: # type: ignore
26
+ def set_values(cls: Type[T], **kwargs: Dict[str, Any]) -> None:
27
27
  """
28
28
  Set values on the global instance of the specific subclass.
29
29
 
langroid/utils/logging.py CHANGED
@@ -72,12 +72,9 @@ def setup_file_logger(
72
72
  propagate: bool = False,
73
73
  ) -> logging.Logger:
74
74
  os.makedirs(os.path.dirname(filename), exist_ok=True)
75
- if not append:
76
- if os.path.exists(filename):
77
- os.remove(filename)
78
-
75
+ file_mode = "a" if append else "w"
79
76
  logger = setup_logger(name)
80
- handler = logging.FileHandler(filename)
77
+ handler = logging.FileHandler(filename, mode=file_mode)
81
78
  handler.setLevel(logging.INFO)
82
79
  if log_format:
83
80
  formatter = logging.Formatter(
@@ -0,0 +1,21 @@
1
+ from . import printing
2
+
3
+ from .printing import (
4
+ shorten_text,
5
+ print_long_text,
6
+ show_if_debug,
7
+ SuppressLoggerWarnings,
8
+ PrintColored,
9
+ )
10
+
11
+ from .status import status
12
+
13
+ __all__ = [
14
+ "printing",
15
+ "shorten_text",
16
+ "print_long_text",
17
+ "show_if_debug",
18
+ "SuppressLoggerWarnings",
19
+ "PrintColored",
20
+ "status",
21
+ ]
@@ -1,5 +1,7 @@
1
+ import logging
1
2
  import sys
2
- from typing import Any, Optional
3
+ from contextlib import contextmanager
4
+ from typing import Any, Iterator, Optional
3
5
 
4
6
  from rich import print as rprint
5
7
  from rich.text import Text
@@ -46,3 +48,47 @@ class PrintColored:
46
48
 
47
49
  def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
48
50
  print(Colors().RESET)
51
+
52
+
53
+ @contextmanager
54
+ def silence_stdout() -> Iterator[None]:
55
+ """
56
+ Temporarily silence all output to stdout and from rich.print.
57
+
58
+ This context manager redirects all output written to stdout (which includes
59
+ outputs from the built-in print function and rich.print) to /dev/null on
60
+ UNIX-like systems or NUL on Windows. Once the context block exits, stdout is
61
+ restored to its original state.
62
+
63
+ Example:
64
+ with silence_stdout_and_rich():
65
+ print("This won't be printed")
66
+ rich.print("This also won't be printed")
67
+
68
+ Note:
69
+ This suppresses both standard print functions and the rich library outputs.
70
+ """
71
+ platform_null = "/dev/null" if sys.platform != "win32" else "NUL"
72
+ original_stdout = sys.stdout
73
+ fnull = open(platform_null, "w")
74
+ sys.stdout = fnull
75
+ try:
76
+ yield
77
+ finally:
78
+ sys.stdout = original_stdout
79
+ fnull.close()
80
+
81
+
82
+ class SuppressLoggerWarnings:
83
+ def __init__(self, logger: str | None = None):
84
+ # If no logger name is given, get the root logger
85
+ self.logger = logging.getLogger(logger)
86
+ self.original_level = self.logger.getEffectiveLevel()
87
+
88
+ def __enter__(self) -> None:
89
+ # Set the logging level to 'ERROR' to suppress warnings
90
+ self.logger.setLevel(logging.ERROR)
91
+
92
+ def __exit__(self, exc_type, exc_value, traceback) -> None: # type: ignore
93
+ # Reset the logging level to its original value
94
+ self.logger.setLevel(self.original_level)
@@ -0,0 +1,33 @@
1
+ import logging
2
+ from contextlib import AbstractContextManager, ExitStack
3
+ from typing import Any
4
+
5
+ from rich.console import Console
6
+
7
+ from langroid.utils.configuration import quiet_mode, settings
8
+
9
+ console = Console()
10
+ logger = logging.getLogger(__name__)
11
+ logger.setLevel(logging.INFO)
12
+
13
+
14
+ def status(
15
+ msg: str,
16
+ log_if_quiet: bool = True,
17
+ ) -> AbstractContextManager[Any]:
18
+ """
19
+ Displays a rich spinner if not in quiet mode, else optionally logs the message.
20
+ """
21
+ stack = ExitStack()
22
+
23
+ if settings.quiet:
24
+ if log_if_quiet:
25
+ logger.info(msg)
26
+ if settings.quiet and log_if_quiet:
27
+ logger.info(msg)
28
+ else:
29
+ stack.enter_context(console.status(msg))
30
+
31
+ stack.enter_context(quiet_mode(not settings.debug))
32
+
33
+ return stack
@@ -0,0 +1,30 @@
1
+ from typing import Any
2
+
3
+ import pandas as pd
4
+
5
+
6
+ def stringify(x: Any) -> str:
7
+ # Convert x to DataFrame if it is not one already
8
+ if isinstance(x, pd.Series):
9
+ df = x.to_frame()
10
+ elif not isinstance(x, pd.DataFrame):
11
+ return str(x)
12
+ else:
13
+ df = x
14
+
15
+ # Truncate long text columns to 1000 characters
16
+ for col in df.columns:
17
+ if df[col].dtype == object:
18
+ df[col] = df[col].apply(
19
+ lambda item: (
20
+ (item[:1000] + "...")
21
+ if isinstance(item, str) and len(item) > 1000
22
+ else item
23
+ )
24
+ )
25
+
26
+ # Limit to 10 rows
27
+ df = df.head(10)
28
+
29
+ # Convert to string
30
+ return df.to_string(index=False) # type: ignore