langroid 0.58.3__py3-none-any.whl → 0.59.0b2__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 (105) hide show
  1. langroid/agent/base.py +39 -17
  2. langroid/agent/base.py-e +2216 -0
  3. langroid/agent/callbacks/chainlit.py +2 -1
  4. langroid/agent/chat_agent.py +73 -55
  5. langroid/agent/chat_agent.py-e +2086 -0
  6. langroid/agent/chat_document.py +7 -7
  7. langroid/agent/chat_document.py-e +513 -0
  8. langroid/agent/openai_assistant.py +9 -9
  9. langroid/agent/openai_assistant.py-e +882 -0
  10. langroid/agent/special/arangodb/arangodb_agent.py +10 -18
  11. langroid/agent/special/arangodb/arangodb_agent.py-e +648 -0
  12. langroid/agent/special/arangodb/tools.py +3 -3
  13. langroid/agent/special/doc_chat_agent.py +16 -14
  14. langroid/agent/special/lance_rag/critic_agent.py +2 -2
  15. langroid/agent/special/lance_rag/query_planner_agent.py +4 -4
  16. langroid/agent/special/lance_tools.py +6 -5
  17. langroid/agent/special/lance_tools.py-e +61 -0
  18. langroid/agent/special/neo4j/neo4j_chat_agent.py +3 -7
  19. langroid/agent/special/neo4j/neo4j_chat_agent.py-e +430 -0
  20. langroid/agent/special/relevance_extractor_agent.py +1 -1
  21. langroid/agent/special/sql/sql_chat_agent.py +11 -3
  22. langroid/agent/task.py +9 -87
  23. langroid/agent/task.py-e +2418 -0
  24. langroid/agent/tool_message.py +33 -17
  25. langroid/agent/tool_message.py-e +400 -0
  26. langroid/agent/tools/file_tools.py +4 -2
  27. langroid/agent/tools/file_tools.py-e +234 -0
  28. langroid/agent/tools/mcp/fastmcp_client.py +19 -6
  29. langroid/agent/tools/mcp/fastmcp_client.py-e +584 -0
  30. langroid/agent/tools/orchestration.py +22 -17
  31. langroid/agent/tools/orchestration.py-e +301 -0
  32. langroid/agent/tools/recipient_tool.py +3 -3
  33. langroid/agent/tools/task_tool.py +22 -16
  34. langroid/agent/tools/task_tool.py-e +249 -0
  35. langroid/agent/xml_tool_message.py +90 -35
  36. langroid/agent/xml_tool_message.py-e +392 -0
  37. langroid/cachedb/base.py +1 -1
  38. langroid/embedding_models/base.py +2 -2
  39. langroid/embedding_models/models.py +3 -7
  40. langroid/embedding_models/models.py-e +563 -0
  41. langroid/exceptions.py +4 -1
  42. langroid/language_models/azure_openai.py +2 -2
  43. langroid/language_models/azure_openai.py-e +134 -0
  44. langroid/language_models/base.py +6 -4
  45. langroid/language_models/base.py-e +812 -0
  46. langroid/language_models/config.py +2 -4
  47. langroid/language_models/config.py-e +18 -0
  48. langroid/language_models/model_info.py +9 -1
  49. langroid/language_models/model_info.py-e +483 -0
  50. langroid/language_models/openai_gpt.py +53 -18
  51. langroid/language_models/openai_gpt.py-e +2280 -0
  52. langroid/language_models/provider_params.py +3 -22
  53. langroid/language_models/provider_params.py-e +153 -0
  54. langroid/mytypes.py +11 -4
  55. langroid/mytypes.py-e +132 -0
  56. langroid/parsing/code_parser.py +1 -1
  57. langroid/parsing/file_attachment.py +1 -1
  58. langroid/parsing/file_attachment.py-e +246 -0
  59. langroid/parsing/md_parser.py +14 -4
  60. langroid/parsing/md_parser.py-e +574 -0
  61. langroid/parsing/parser.py +22 -7
  62. langroid/parsing/parser.py-e +410 -0
  63. langroid/parsing/repo_loader.py +3 -1
  64. langroid/parsing/repo_loader.py-e +812 -0
  65. langroid/parsing/search.py +1 -1
  66. langroid/parsing/url_loader.py +17 -51
  67. langroid/parsing/url_loader.py-e +683 -0
  68. langroid/parsing/urls.py +5 -4
  69. langroid/parsing/urls.py-e +279 -0
  70. langroid/prompts/prompts_config.py +1 -1
  71. langroid/pydantic_v1/__init__.py +56 -6
  72. langroid/pydantic_v1/__init__.py-e +36 -0
  73. langroid/pydantic_v1/main.py +10 -4
  74. langroid/pydantic_v1/main.py-e +11 -0
  75. langroid/utils/configuration.py +13 -11
  76. langroid/utils/configuration.py-e +141 -0
  77. langroid/utils/constants.py +1 -1
  78. langroid/utils/constants.py-e +32 -0
  79. langroid/utils/globals.py +21 -5
  80. langroid/utils/globals.py-e +49 -0
  81. langroid/utils/html_logger.py +2 -1
  82. langroid/utils/html_logger.py-e +825 -0
  83. langroid/utils/object_registry.py +1 -1
  84. langroid/utils/object_registry.py-e +66 -0
  85. langroid/utils/pydantic_utils.py +55 -28
  86. langroid/utils/pydantic_utils.py-e +602 -0
  87. langroid/utils/types.py +2 -2
  88. langroid/utils/types.py-e +113 -0
  89. langroid/vector_store/base.py +3 -3
  90. langroid/vector_store/lancedb.py +5 -5
  91. langroid/vector_store/lancedb.py-e +404 -0
  92. langroid/vector_store/meilisearch.py +2 -2
  93. langroid/vector_store/pineconedb.py +4 -4
  94. langroid/vector_store/pineconedb.py-e +427 -0
  95. langroid/vector_store/postgres.py +1 -1
  96. langroid/vector_store/qdrantdb.py +3 -3
  97. langroid/vector_store/weaviatedb.py +1 -1
  98. {langroid-0.58.3.dist-info → langroid-0.59.0b2.dist-info}/METADATA +3 -2
  99. langroid-0.59.0b2.dist-info/RECORD +181 -0
  100. langroid/agent/special/doc_chat_task.py +0 -0
  101. langroid/mcp/__init__.py +0 -1
  102. langroid/mcp/server/__init__.py +0 -1
  103. langroid-0.58.3.dist-info/RECORD +0 -145
  104. {langroid-0.58.3.dist-info → langroid-0.59.0b2.dist-info}/WHEEL +0 -0
  105. {langroid-0.58.3.dist-info → langroid-0.59.0b2.dist-info}/licenses/LICENSE +0 -0
@@ -12,6 +12,7 @@ from typing import (
12
12
  Callable,
13
13
  Dict,
14
14
  List,
15
+ Mapping,
15
16
  Optional,
16
17
  Tuple,
17
18
  Type,
@@ -24,6 +25,8 @@ from cerebras.cloud.sdk import AsyncCerebras, Cerebras
24
25
  from groq import AsyncGroq, Groq
25
26
  from httpx import Timeout
26
27
  from openai import AsyncOpenAI, OpenAI
28
+ from pydantic import BaseModel
29
+ from pydantic_settings import BaseSettings, SettingsConfigDict
27
30
  from rich import print
28
31
  from rich.markup import escape
29
32
 
@@ -78,7 +81,6 @@ from langroid.language_models.utils import (
78
81
  retry_with_exponential_backoff,
79
82
  )
80
83
  from langroid.parsing.parse_json import parse_imperfect_json
81
- from langroid.pydantic_v1 import BaseModel, BaseSettings
82
84
  from langroid.utils.configuration import settings
83
85
  from langroid.utils.constants import Colors
84
86
  from langroid.utils.system import friendly_error
@@ -220,7 +222,7 @@ class OpenAICallParams(BaseModel):
220
222
  extra_body: Dict[str, Any] | None = None # additional params for API request body
221
223
 
222
224
  def to_dict_exclude_none(self) -> Dict[str, Any]:
223
- return {k: v for k, v in self.dict().items() if v is not None}
225
+ return {k: v for k, v in self.model_dump().items() if v is not None}
224
226
 
225
227
 
226
228
  class LiteLLMProxyConfig(BaseSettings):
@@ -229,8 +231,7 @@ class LiteLLMProxyConfig(BaseSettings):
229
231
  api_key: str = "" # read from env var LITELLM_API_KEY if set
230
232
  api_base: str = "" # read from env var LITELLM_API_BASE if set
231
233
 
232
- class Config:
233
- env_prefix = "LITELLM_"
234
+ model_config = SettingsConfigDict(env_prefix="LITELLM_")
234
235
 
235
236
 
236
237
  class OpenAIGPTConfig(LLMConfig):
@@ -259,7 +260,7 @@ class OpenAIGPTConfig(LLMConfig):
259
260
  litellm_proxy: LiteLLMProxyConfig = LiteLLMProxyConfig()
260
261
  ollama: bool = False # use ollama's OpenAI-compatible endpoint?
261
262
  min_output_tokens: int = 1
262
- use_chat_for_completion = True # do not change this, for OpenAI models!
263
+ use_chat_for_completion: bool = True # do not change this, for OpenAI models!
263
264
  timeout: int = 20
264
265
  temperature: float = 0.2
265
266
  seed: int | None = 42
@@ -316,8 +317,43 @@ class OpenAIGPTConfig(LLMConfig):
316
317
 
317
318
  super().__init__(**kwargs)
318
319
 
319
- class Config:
320
- env_prefix = "OPENAI_"
320
+ model_config = SettingsConfigDict(env_prefix="OPENAI_")
321
+
322
+ def model_copy(
323
+ self, *, update: Mapping[str, Any] | None = None, deep: bool = False
324
+ ) -> "OpenAIGPTConfig":
325
+ """
326
+ Override model_copy to handle unpicklable fields properly.
327
+
328
+ This preserves fields like http_client_factory during normal copying
329
+ while still allowing exclusion for pickling operations.
330
+ """
331
+ # Save references to unpicklable fields
332
+ http_client_factory = self.http_client_factory
333
+ streamer = self.streamer
334
+ streamer_async = self.streamer_async
335
+
336
+ # Get the current model data, excluding problematic fields
337
+ data = self.model_dump(
338
+ exclude={"http_client_factory", "streamer", "streamer_async"}
339
+ )
340
+
341
+ # Apply any updates
342
+ if update:
343
+ data.update(update)
344
+
345
+ # Create a new instance with the copied data
346
+ new_instance = self.__class__(**data)
347
+
348
+ # Restore the unpicklable fields if they weren't overridden by update
349
+ if "http_client_factory" not in (update or {}):
350
+ new_instance.http_client_factory = http_client_factory
351
+ if "streamer" not in (update or {}):
352
+ new_instance.streamer = streamer
353
+ if "streamer_async" not in (update or {}):
354
+ new_instance.streamer_async = streamer_async
355
+
356
+ return new_instance
321
357
 
322
358
  def _validate_litellm(self) -> None:
323
359
  """
@@ -330,12 +366,12 @@ class OpenAIGPTConfig(LLMConfig):
330
366
  import litellm
331
367
  except ImportError:
332
368
  raise LangroidImportError("litellm", "litellm")
369
+
333
370
  litellm.telemetry = False
334
371
  litellm.drop_params = True # drop un-supported params without crashing
335
- # modify params to fit the model expectations, and avoid crashing
336
- # (e.g. anthropic doesn't like first msg to be system msg)
337
372
  litellm.modify_params = True
338
373
  self.seed = None # some local mdls don't support seed
374
+
339
375
  if self.api_key == DUMMY_API_KEY:
340
376
  keys_dict = litellm.utils.validate_environment(self.chat_model)
341
377
  missing_keys = keys_dict.get("missing_keys", [])
@@ -365,8 +401,7 @@ class OpenAIGPTConfig(LLMConfig):
365
401
  class DynamicConfig(OpenAIGPTConfig):
366
402
  pass
367
403
 
368
- DynamicConfig.Config.env_prefix = prefix.upper() + "_"
369
-
404
+ DynamicConfig.model_config = SettingsConfigDict(env_prefix=prefix.upper() + "_")
370
405
  return DynamicConfig
371
406
 
372
407
 
@@ -407,7 +442,7 @@ class OpenAIGPT(LanguageModel):
407
442
  config: configuration for openai-gpt model
408
443
  """
409
444
  # copy the config to avoid modifying the original
410
- config = config.copy()
445
+ config = config.model_copy()
411
446
  super().__init__(config)
412
447
  self.config: OpenAIGPTConfig = config
413
448
  # save original model name such as `provider/model` before
@@ -1477,7 +1512,7 @@ class OpenAIGPT(LanguageModel):
1477
1512
 
1478
1513
  if has_function:
1479
1514
  function_call = LLMFunctionCall(name=function_name)
1480
- function_call_dict = function_call.dict()
1515
+ function_call_dict = function_call.model_dump()
1481
1516
  if function_args == "":
1482
1517
  function_call.arguments = None
1483
1518
  else:
@@ -1529,7 +1564,7 @@ class OpenAIGPT(LanguageModel):
1529
1564
  ),
1530
1565
  ),
1531
1566
  ),
1532
- openai_response.dict(),
1567
+ openai_response.model_dump(),
1533
1568
  )
1534
1569
 
1535
1570
  def _cache_store(self, k: str, v: Any) -> None:
@@ -1680,7 +1715,7 @@ class OpenAIGPT(LanguageModel):
1680
1715
  cached, hashed_key, response = completions_with_backoff(**args)
1681
1716
  # assume response is an actual response rather than a streaming event
1682
1717
  if not isinstance(response, dict):
1683
- response = response.dict()
1718
+ response = response.model_dump()
1684
1719
  if "message" in response["choices"][0]:
1685
1720
  msg = response["choices"][0]["message"]["content"].strip()
1686
1721
  else:
@@ -1758,7 +1793,7 @@ class OpenAIGPT(LanguageModel):
1758
1793
  )
1759
1794
  # assume response is an actual response rather than a streaming event
1760
1795
  if not isinstance(response, dict):
1761
- response = response.dict()
1796
+ response = response.model_dump()
1762
1797
  if "message" in response["choices"][0]:
1763
1798
  msg = response["choices"][0]["message"]["content"].strip()
1764
1799
  else:
@@ -2056,7 +2091,7 @@ class OpenAIGPT(LanguageModel):
2056
2091
  if functions is not None:
2057
2092
  args.update(
2058
2093
  dict(
2059
- functions=[f.dict() for f in functions],
2094
+ functions=[f.model_dump() for f in functions],
2060
2095
  function_call=function_call,
2061
2096
  )
2062
2097
  )
@@ -2074,7 +2109,7 @@ class OpenAIGPT(LanguageModel):
2074
2109
  tools=[
2075
2110
  dict(
2076
2111
  type="function",
2077
- function=t.function.dict()
2112
+ function=t.function.model_dump()
2078
2113
  | ({"strict": t.strict} if t.strict is not None else {}),
2079
2114
  )
2080
2115
  for t in tools