langroid 0.19.0__tar.gz → 0.19.2__tar.gz

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 (143) hide show
  1. {langroid-0.19.0 → langroid-0.19.2}/PKG-INFO +3 -2
  2. {langroid-0.19.0 → langroid-0.19.2}/README.md +2 -1
  3. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/base.py +11 -1
  4. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/xml_tool_message.py +59 -29
  5. {langroid-0.19.0 → langroid-0.19.2}/langroid/exceptions.py +5 -0
  6. {langroid-0.19.0 → langroid-0.19.2}/pyproject.toml +1 -1
  7. {langroid-0.19.0 → langroid-0.19.2}/LICENSE +0 -0
  8. {langroid-0.19.0 → langroid-0.19.2}/langroid/__init__.py +0 -0
  9. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/__init__.py +0 -0
  10. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/batch.py +0 -0
  11. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/callbacks/__init__.py +0 -0
  12. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/callbacks/chainlit.py +0 -0
  13. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/chat_agent.py +0 -0
  14. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/chat_document.py +0 -0
  15. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/helpers.py +0 -0
  16. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/junk +0 -0
  17. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/openai_assistant.py +0 -0
  18. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/__init__.py +0 -0
  19. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/doc_chat_agent.py +0 -0
  20. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
  21. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_rag/__init__.py +0 -0
  22. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
  23. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
  24. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
  25. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/lance_tools.py +0 -0
  26. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/neo4j/__init__.py +0 -0
  27. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
  28. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
  29. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/neo4j/utils/__init__.py +0 -0
  30. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/neo4j/utils/system_message.py +0 -0
  31. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/relevance_extractor_agent.py +0 -0
  32. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/retriever_agent.py +0 -0
  33. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/__init__.py +0 -0
  34. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
  35. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/utils/__init__.py +0 -0
  36. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
  37. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
  38. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/utils/system_message.py +0 -0
  39. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/sql/utils/tools.py +0 -0
  40. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/special/table_chat_agent.py +0 -0
  41. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/structured_message.py +0 -0
  42. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/task.py +0 -0
  43. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tool_message.py +0 -0
  44. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/__init__.py +0 -0
  45. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
  46. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/file_tools.py +0 -0
  47. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/google_search_tool.py +0 -0
  48. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/metaphor_search_tool.py +0 -0
  49. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/orchestration.py +0 -0
  50. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/recipient_tool.py +0 -0
  51. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/retrieval_tool.py +0 -0
  52. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/rewind_tool.py +0 -0
  53. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/tools/segment_extract_tool.py +0 -0
  54. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent/typed_task.py +0 -0
  55. {langroid-0.19.0 → langroid-0.19.2}/langroid/agent_config.py +0 -0
  56. {langroid-0.19.0 → langroid-0.19.2}/langroid/cachedb/__init__.py +0 -0
  57. {langroid-0.19.0 → langroid-0.19.2}/langroid/cachedb/base.py +0 -0
  58. {langroid-0.19.0 → langroid-0.19.2}/langroid/cachedb/momento_cachedb.py +0 -0
  59. {langroid-0.19.0 → langroid-0.19.2}/langroid/cachedb/redis_cachedb.py +0 -0
  60. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/__init__.py +0 -0
  61. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/base.py +0 -0
  62. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/clustering.py +0 -0
  63. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/models.py +0 -0
  64. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/protoc/__init__.py +0 -0
  65. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/protoc/embeddings.proto +0 -0
  66. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
  67. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
  68. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
  69. {langroid-0.19.0 → langroid-0.19.2}/langroid/embedding_models/remote_embeds.py +0 -0
  70. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/.chainlit/config.toml +0 -0
  71. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/.chainlit/translations/en-US.json +0 -0
  72. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/__init__.py +0 -0
  73. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/azure_openai.py +0 -0
  74. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/base.py +0 -0
  75. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/config.py +0 -0
  76. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/mock_lm.py +0 -0
  77. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/openai_gpt.py +0 -0
  78. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/prompt_formatter/__init__.py +0 -0
  79. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/prompt_formatter/base.py +0 -0
  80. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
  81. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
  82. {langroid-0.19.0 → langroid-0.19.2}/langroid/language_models/utils.py +0 -0
  83. {langroid-0.19.0 → langroid-0.19.2}/langroid/mytypes.py +0 -0
  84. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/__init__.py +0 -0
  85. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/agent_chats.py +0 -0
  86. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/code-parsing.md +0 -0
  87. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/code_parser.py +0 -0
  88. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/config.py +0 -0
  89. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/document_parser.py +0 -0
  90. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/image_text.py +0 -0
  91. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/para_sentence_split.py +0 -0
  92. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/parse_json.py +0 -0
  93. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/parser.py +0 -0
  94. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/repo_loader.py +0 -0
  95. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/routing.py +0 -0
  96. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/search.py +0 -0
  97. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/spider.py +0 -0
  98. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/table_loader.py +0 -0
  99. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/url_loader.py +0 -0
  100. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/url_loader_cookies.py +0 -0
  101. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/urls.py +0 -0
  102. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/utils.py +0 -0
  103. {langroid-0.19.0 → langroid-0.19.2}/langroid/parsing/web_search.py +0 -0
  104. {langroid-0.19.0 → langroid-0.19.2}/langroid/prompts/__init__.py +0 -0
  105. {langroid-0.19.0 → langroid-0.19.2}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
  106. {langroid-0.19.0 → langroid-0.19.2}/langroid/prompts/dialog.py +0 -0
  107. {langroid-0.19.0 → langroid-0.19.2}/langroid/prompts/prompts_config.py +0 -0
  108. {langroid-0.19.0 → langroid-0.19.2}/langroid/prompts/templates.py +0 -0
  109. {langroid-0.19.0 → langroid-0.19.2}/langroid/py.typed +0 -0
  110. {langroid-0.19.0 → langroid-0.19.2}/langroid/pydantic_v1/__init__.py +0 -0
  111. {langroid-0.19.0 → langroid-0.19.2}/langroid/pydantic_v1/main.py +0 -0
  112. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/.chainlit/config.toml +0 -0
  113. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/.chainlit/translations/en-US.json +0 -0
  114. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/__init__.py +0 -0
  115. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/algorithms/__init__.py +0 -0
  116. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/algorithms/graph.py +0 -0
  117. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/configuration.py +0 -0
  118. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/constants.py +0 -0
  119. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/docker.py +0 -0
  120. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/git_utils.py +0 -0
  121. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/globals.py +0 -0
  122. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/llms/__init__.py +0 -0
  123. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/llms/strings.py +0 -0
  124. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/logging.py +0 -0
  125. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/object_registry.py +0 -0
  126. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/output/__init__.py +0 -0
  127. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/output/citations.py +0 -0
  128. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/output/printing.py +0 -0
  129. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/output/status.py +0 -0
  130. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/pandas_utils.py +0 -0
  131. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/pydantic_utils.py +0 -0
  132. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/system.py +0 -0
  133. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/types.py +0 -0
  134. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/web/__init__.py +0 -0
  135. {langroid-0.19.0 → langroid-0.19.2}/langroid/utils/web/login.py +0 -0
  136. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/__init__.py +0 -0
  137. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/base.py +0 -0
  138. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/chromadb.py +0 -0
  139. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/lancedb.py +0 -0
  140. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/meilisearch.py +0 -0
  141. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/momento.py +0 -0
  142. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/qdrant_cloud.py +0 -0
  143. {langroid-0.19.0 → langroid-0.19.2}/langroid/vector_store/qdrantdb.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.19.0
3
+ Version: 0.19.2
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -153,7 +153,8 @@ This Multi-Agent paradigm is inspired by the
153
153
  (but you do not need to know anything about this!).
154
154
 
155
155
  `Langroid` is a fresh take on LLM app-development, where considerable thought has gone
156
- into simplifying the developer experience; it does not use `Langchain`.
156
+ into simplifying the developer experience;
157
+ it does not use `Langchain`, or any other LLM framework.
157
158
 
158
159
  :fire: Read the (WIP) [overview of the langroid architecture](https://langroid.github.io/langroid/blog/2024/08/15/overview-of-langroids-multi-agent-architecture-prelim/)
159
160
 
@@ -44,7 +44,8 @@ This Multi-Agent paradigm is inspired by the
44
44
  (but you do not need to know anything about this!).
45
45
 
46
46
  `Langroid` is a fresh take on LLM app-development, where considerable thought has gone
47
- into simplifying the developer experience; it does not use `Langchain`.
47
+ into simplifying the developer experience;
48
+ it does not use `Langchain`, or any other LLM framework.
48
49
 
49
50
  :fire: Read the (WIP) [overview of the langroid architecture](https://langroid.github.io/langroid/blog/2024/08/15/overview-of-langroids-multi-agent-architecture-prelim/)
50
51
 
@@ -33,6 +33,7 @@ from rich.prompt import Prompt
33
33
  from langroid.agent.chat_document import ChatDocMetaData, ChatDocument
34
34
  from langroid.agent.tool_message import ToolMessage
35
35
  from langroid.agent.xml_tool_message import XMLToolMessage
36
+ from langroid.exceptions import XMLException
36
37
  from langroid.language_models.base import (
37
38
  LanguageModel,
38
39
  LLMConfig,
@@ -1120,6 +1121,8 @@ class Agent(ABC):
1120
1121
  except ValidationError as ve:
1121
1122
  # correct tool name but bad fields
1122
1123
  return self.tool_validation_error(ve)
1124
+ except XMLException as xe: # from XMLToolMessage parsing
1125
+ return str(xe)
1123
1126
  except ValueError:
1124
1127
  # invalid tool name
1125
1128
  # We return None since returning "invalid tool name" would
@@ -1242,7 +1245,14 @@ class Agent(ABC):
1242
1245
  if is_json:
1243
1246
  maybe_tool_dict = json.loads(tool_candidate_str)
1244
1247
  else:
1245
- maybe_tool_dict = XMLToolMessage.extract_field_values(tool_candidate_str)
1248
+ try:
1249
+ maybe_tool_dict = XMLToolMessage.extract_field_values(
1250
+ tool_candidate_str
1251
+ )
1252
+ except Exception as e:
1253
+ from langroid.exceptions import XMLException
1254
+
1255
+ raise XMLException(f"Error extracting XML fields:\n {str(e)}")
1246
1256
  # check if the maybe_tool_dict contains a "properties" field
1247
1257
  # which further contains the actual tool-call
1248
1258
  # (some weak LLMs do this). E.g. gpt-4o sometimes generates this:
@@ -1,4 +1,5 @@
1
- from typing import Any, Dict, List, Optional
1
+ from collections.abc import Mapping
2
+ from typing import Any, Dict, List, Optional, get_args, get_origin
2
3
 
3
4
  from lxml import etree
4
5
 
@@ -106,12 +107,17 @@ class XMLToolMessage(ToolMessage):
106
107
  Optional["XMLToolMessage"]: An instance of the class if parsing succeeds,
107
108
  None otherwise.
108
109
  """
109
- parsed_data = cls.extract_field_values(formatted_string)
110
- if parsed_data is None:
111
- return None
110
+ try:
111
+ parsed_data = cls.extract_field_values(formatted_string)
112
+ if parsed_data is None:
113
+ return None
114
+
115
+ # Use Pydantic's parse_obj to create and validate the instance
116
+ return cls.parse_obj(parsed_data)
117
+ except Exception as e:
118
+ from langroid.exceptions import XMLException
112
119
 
113
- # Use Pydantic's parse_obj to create and validate the instance
114
- return cls.parse_obj(parsed_data)
120
+ raise XMLException(f"Error parsing XML: {str(e)}")
115
121
 
116
122
  @classmethod
117
123
  def find_verbatim_fields(
@@ -133,15 +139,6 @@ class XMLToolMessage(ToolMessage):
133
139
 
134
140
  @classmethod
135
141
  def format_instructions(cls, tool: bool = False) -> str:
136
- """
137
- Instructions to the LLM showing how to use the XML tool.
138
-
139
- Args:
140
- tool: Not used in this implementation, kept for compatibility.
141
-
142
- Returns:
143
- str: instructions on how to use the XML message
144
- """
145
142
  fields = [
146
143
  f
147
144
  for f in cls.__fields__.keys()
@@ -165,35 +162,62 @@ class XMLToolMessage(ToolMessage):
165
162
  nonlocal preamble, xml_format
166
163
  current_path = f"{path}.{field_name}" if path else field_name
167
164
 
168
- if issubclass(field_type, BaseModel):
165
+ origin = get_origin(field_type)
166
+ args = get_args(field_type)
167
+
168
+ if (
169
+ origin is None
170
+ and isinstance(field_type, type)
171
+ and issubclass(field_type, BaseModel)
172
+ ):
169
173
  preamble += (
170
174
  f"{field_name.upper()} = [nested structure for {field_name}]\n"
171
175
  )
172
176
  xml_format += f"{indent}<{field_name}>\n"
173
177
  for sub_field, sub_field_info in field_type.__fields__.items():
174
178
  format_field(
175
- sub_field, sub_field_info.type_, indent + " ", current_path
179
+ sub_field,
180
+ sub_field_info.outer_type_,
181
+ indent + " ",
182
+ current_path,
176
183
  )
177
184
  xml_format += f"{indent}</{field_name}>\n"
178
- elif issubclass(field_type, List):
179
- item_type = getattr(field_type, "__args__", [Any])[0]
180
- preamble += f"{field_name.upper()} = [list of {item_type.__name__}]\n"
185
+ elif origin in (list, List) or (field_type is list):
186
+ item_type = args[0] if args else Any
187
+ if isinstance(item_type, type) and issubclass(item_type, BaseModel):
188
+ preamble += (
189
+ f"{field_name.upper()} = "
190
+ f"[list of nested structures for {field_name}]\n"
191
+ )
192
+ else:
193
+ preamble += (
194
+ f"{field_name.upper()} = "
195
+ f"[list of {getattr(item_type, '__name__', str(item_type))} "
196
+ f"for {field_name}]\n"
197
+ )
181
198
  xml_format += f"{indent}<{field_name}>\n"
182
- xml_format += f"{indent} <item>[{item_type.__name__} value]</item>\n"
199
+ xml_format += (
200
+ f"{indent} <item>"
201
+ f"[{getattr(item_type, '__name__', str(item_type))} value]"
202
+ f"</item>\n"
203
+ )
183
204
  xml_format += f"{indent} ...\n"
184
205
  xml_format += f"{indent}</{field_name}>\n"
185
- elif issubclass(field_type, Dict):
186
- key_type, value_type = getattr(field_type, "__args__", [Any, Any])
206
+ elif origin in (dict, Dict) or (
207
+ isinstance(field_type, type) and issubclass(field_type, Mapping)
208
+ ):
209
+ key_type, value_type = args if len(args) == 2 else (Any, Any)
187
210
  preamble += (
188
211
  f"{field_name.upper()} = "
189
- f"[dictionary with {key_type.__name__} keys and "
190
- f"{value_type.__name__} values]\n"
212
+ f"[dictionary with "
213
+ f"{getattr(key_type, '__name__', str(key_type))} keys and "
214
+ f"{getattr(value_type, '__name__', str(value_type))} values]\n"
191
215
  )
192
216
  xml_format += f"{indent}<{field_name}>\n"
193
217
  xml_format += (
194
- f"{indent} <{key_type.__name__}>"
195
- f"[{value_type.__name__} value]"
196
- f"</{key_type.__name__}>\n"
218
+ f"{indent} <{getattr(key_type, '__name__', str(key_type))}>"
219
+ f"[{getattr(value_type, '__name__', str(value_type))} value]"
220
+ f"</{getattr(key_type, '__name__', str(key_type))}>\n"
197
221
  )
198
222
  xml_format += f"{indent} ...\n"
199
223
  xml_format += f"{indent}</{field_name}>\n"
@@ -213,7 +237,10 @@ class XMLToolMessage(ToolMessage):
213
237
  verbatim_fields = cls.find_verbatim_fields()
214
238
 
215
239
  for field in fields:
216
- field_type = cls.__fields__[field].type_
240
+ field_info = cls.__fields__[field]
241
+ field_type = (
242
+ field_info.outer_type_
243
+ ) # Use outer_type_ to get the actual type including List, etc.
217
244
  format_field(field, field_type)
218
245
 
219
246
  xml_format += f"</{cls.Config.root_element}>"
@@ -260,6 +287,9 @@ class XMLToolMessage(ToolMessage):
260
287
  def create_element(
261
288
  parent: etree._Element, name: str, value: Any, path: str = ""
262
289
  ) -> None:
290
+ if value is None:
291
+ return
292
+
263
293
  elem = etree.SubElement(parent, name)
264
294
  current_path = f"{path}.{name}" if path else name
265
295
 
@@ -1,6 +1,11 @@
1
1
  from typing import Optional
2
2
 
3
3
 
4
+ class XMLException(Exception):
5
+ def __init__(self, message: str) -> None:
6
+ super().__init__(message)
7
+
8
+
4
9
  class InfiniteLoopException(Exception):
5
10
  def __init__(self, message: str = "Infinite loop detected", *args: object) -> None:
6
11
  super().__init__(message, *args)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langroid"
3
- version = "0.19.0"
3
+ version = "0.19.2"
4
4
  description = "Harness LLMs with Multi-Agent Programming"
5
5
  authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes