langroid 0.27.4__tar.gz → 0.28.0__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 (148) hide show
  1. {langroid-0.27.4 → langroid-0.28.0}/PKG-INFO +2 -1
  2. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/base.py +34 -15
  3. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/openai_gpt.py +32 -1
  4. {langroid-0.27.4 → langroid-0.28.0}/pyproject.toml +2 -1
  5. {langroid-0.27.4 → langroid-0.28.0}/LICENSE +0 -0
  6. {langroid-0.27.4 → langroid-0.28.0}/README.md +0 -0
  7. {langroid-0.27.4 → langroid-0.28.0}/langroid/__init__.py +0 -0
  8. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/__init__.py +0 -0
  9. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/batch.py +0 -0
  10. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/callbacks/__init__.py +0 -0
  11. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/callbacks/chainlit.py +0 -0
  12. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/chat_agent.py +0 -0
  13. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/chat_document.py +0 -0
  14. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/helpers.py +0 -0
  15. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/junk +0 -0
  16. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/openai_assistant.py +0 -0
  17. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/__init__.py +0 -0
  18. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/arangodb/__init__.py +0 -0
  19. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/arangodb/arangodb_agent.py +0 -0
  20. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/arangodb/system_messages.py +0 -0
  21. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/arangodb/tools.py +0 -0
  22. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/arangodb/utils.py +0 -0
  23. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/doc_chat_agent.py +0 -0
  24. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
  25. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_rag/__init__.py +0 -0
  26. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
  27. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
  28. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
  29. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/lance_tools.py +0 -0
  30. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/neo4j/__init__.py +0 -0
  31. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
  32. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
  33. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/neo4j/system_messages.py +0 -0
  34. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/neo4j/tools.py +0 -0
  35. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/relevance_extractor_agent.py +0 -0
  36. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/retriever_agent.py +0 -0
  37. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/__init__.py +0 -0
  38. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
  39. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/utils/__init__.py +0 -0
  40. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
  41. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
  42. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/utils/system_message.py +0 -0
  43. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/sql/utils/tools.py +0 -0
  44. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/special/table_chat_agent.py +0 -0
  45. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/structured_message.py +0 -0
  46. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/task.py +0 -0
  47. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tool_message.py +0 -0
  48. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/__init__.py +0 -0
  49. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
  50. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/file_tools.py +0 -0
  51. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/google_search_tool.py +0 -0
  52. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/metaphor_search_tool.py +0 -0
  53. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/orchestration.py +0 -0
  54. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/recipient_tool.py +0 -0
  55. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/retrieval_tool.py +0 -0
  56. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/rewind_tool.py +0 -0
  57. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/tools/segment_extract_tool.py +0 -0
  58. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/typed_task.py +0 -0
  59. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent/xml_tool_message.py +0 -0
  60. {langroid-0.27.4 → langroid-0.28.0}/langroid/agent_config.py +0 -0
  61. {langroid-0.27.4 → langroid-0.28.0}/langroid/cachedb/__init__.py +0 -0
  62. {langroid-0.27.4 → langroid-0.28.0}/langroid/cachedb/base.py +0 -0
  63. {langroid-0.27.4 → langroid-0.28.0}/langroid/cachedb/momento_cachedb.py +0 -0
  64. {langroid-0.27.4 → langroid-0.28.0}/langroid/cachedb/redis_cachedb.py +0 -0
  65. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/__init__.py +0 -0
  66. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/base.py +0 -0
  67. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/clustering.py +0 -0
  68. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/models.py +0 -0
  69. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/protoc/__init__.py +0 -0
  70. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/protoc/embeddings.proto +0 -0
  71. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
  72. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
  73. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
  74. {langroid-0.27.4 → langroid-0.28.0}/langroid/embedding_models/remote_embeds.py +0 -0
  75. {langroid-0.27.4 → langroid-0.28.0}/langroid/exceptions.py +0 -0
  76. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/.chainlit/config.toml +0 -0
  77. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/.chainlit/translations/en-US.json +0 -0
  78. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/__init__.py +0 -0
  79. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/azure_openai.py +0 -0
  80. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/base.py +0 -0
  81. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/config.py +0 -0
  82. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/mock_lm.py +0 -0
  83. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/prompt_formatter/__init__.py +0 -0
  84. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/prompt_formatter/base.py +0 -0
  85. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
  86. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
  87. {langroid-0.27.4 → langroid-0.28.0}/langroid/language_models/utils.py +0 -0
  88. {langroid-0.27.4 → langroid-0.28.0}/langroid/mytypes.py +0 -0
  89. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/__init__.py +0 -0
  90. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/agent_chats.py +0 -0
  91. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/code-parsing.md +0 -0
  92. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/code_parser.py +0 -0
  93. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/config.py +0 -0
  94. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/document_parser.py +0 -0
  95. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/image_text.py +0 -0
  96. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/para_sentence_split.py +0 -0
  97. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/parse_json.py +0 -0
  98. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/parser.py +0 -0
  99. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/repo_loader.py +0 -0
  100. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/routing.py +0 -0
  101. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/search.py +0 -0
  102. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/spider.py +0 -0
  103. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/table_loader.py +0 -0
  104. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/url_loader.py +0 -0
  105. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/url_loader_cookies.py +0 -0
  106. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/urls.py +0 -0
  107. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/utils.py +0 -0
  108. {langroid-0.27.4 → langroid-0.28.0}/langroid/parsing/web_search.py +0 -0
  109. {langroid-0.27.4 → langroid-0.28.0}/langroid/prompts/__init__.py +0 -0
  110. {langroid-0.27.4 → langroid-0.28.0}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
  111. {langroid-0.27.4 → langroid-0.28.0}/langroid/prompts/dialog.py +0 -0
  112. {langroid-0.27.4 → langroid-0.28.0}/langroid/prompts/prompts_config.py +0 -0
  113. {langroid-0.27.4 → langroid-0.28.0}/langroid/prompts/templates.py +0 -0
  114. {langroid-0.27.4 → langroid-0.28.0}/langroid/py.typed +0 -0
  115. {langroid-0.27.4 → langroid-0.28.0}/langroid/pydantic_v1/__init__.py +0 -0
  116. {langroid-0.27.4 → langroid-0.28.0}/langroid/pydantic_v1/main.py +0 -0
  117. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/.chainlit/config.toml +0 -0
  118. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/.chainlit/translations/en-US.json +0 -0
  119. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/__init__.py +0 -0
  120. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/algorithms/__init__.py +0 -0
  121. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/algorithms/graph.py +0 -0
  122. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/configuration.py +0 -0
  123. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/constants.py +0 -0
  124. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/docker.py +0 -0
  125. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/git_utils.py +0 -0
  126. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/globals.py +0 -0
  127. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/llms/__init__.py +0 -0
  128. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/llms/strings.py +0 -0
  129. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/logging.py +0 -0
  130. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/object_registry.py +0 -0
  131. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/output/__init__.py +0 -0
  132. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/output/citations.py +0 -0
  133. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/output/printing.py +0 -0
  134. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/output/status.py +0 -0
  135. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/pandas_utils.py +0 -0
  136. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/pydantic_utils.py +0 -0
  137. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/system.py +0 -0
  138. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/types.py +0 -0
  139. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/web/__init__.py +0 -0
  140. {langroid-0.27.4 → langroid-0.28.0}/langroid/utils/web/login.py +0 -0
  141. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/__init__.py +0 -0
  142. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/base.py +0 -0
  143. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/chromadb.py +0 -0
  144. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/lancedb.py +0 -0
  145. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/meilisearch.py +0 -0
  146. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/momento.py +0 -0
  147. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/qdrant_cloud.py +0 -0
  148. {langroid-0.27.4 → langroid-0.28.0}/langroid/vector_store/qdrantdb.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.27.4
3
+ Version: 0.28.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -85,6 +85,7 @@ Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "db" or extra == "all" or ext
85
85
  Requires-Dist: pyparsing (>=3.0.9,<4.0.0)
86
86
  Requires-Dist: pypdf (>=3.12.2,<4.0.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
87
87
  Requires-Dist: pytesseract (>=0.3.10,<0.4.0) ; extra == "doc-chat" or extra == "all" or extra == "pdf-parsers"
88
+ Requires-Dist: pytest-rerunfailures (>=15.0,<16.0)
88
89
  Requires-Dist: python-arango (>=8.1.2,<9.0.0) ; extra == "all" or extra == "arango"
89
90
  Requires-Dist: python-docx (>=1.1.0,<2.0.0) ; extra == "doc-chat" or extra == "all" or extra == "docx"
90
91
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
@@ -282,17 +282,27 @@ class Agent(ABC):
282
282
  if not issubclass(message_class, ToolMessage):
283
283
  raise ValueError("message_class must be a subclass of ToolMessage")
284
284
  tool = message_class.default_value("request")
285
+
286
+ """
287
+ if tool has handler method explicitly defined - use it,
288
+ otherwise use the tool name as the handler
289
+ """
290
+ if hasattr(message_class, "_handler"):
291
+ handler = getattr(message_class, "_handler", tool)
292
+ else:
293
+ handler = tool
294
+
285
295
  self.llm_tools_map[tool] = message_class
286
296
  if (
287
297
  hasattr(message_class, "handle")
288
298
  and inspect.isfunction(message_class.handle)
289
- and not hasattr(self, tool)
299
+ and not hasattr(self, handler)
290
300
  ):
291
301
  """
292
302
  If the message class has a `handle` method,
293
- and agent does NOT have a method with the same name as the tool,
303
+ and agent does NOT have a tool handler method,
294
304
  then we create a method for the agent whose name
295
- is the value of `tool`, and whose body is the `handle` method.
305
+ is the value of `handler`, and whose body is the `handle` method.
296
306
  This removes a separate step of having to define this method
297
307
  for the agent, and also keeps the tool definition AND handling
298
308
  in one place, i.e. in the message class.
@@ -302,21 +312,22 @@ class Agent(ABC):
302
312
  len(inspect.signature(message_class.handle).parameters) > 1
303
313
  )
304
314
  if has_chat_doc_arg:
305
- setattr(self, tool, lambda obj, chat_doc: obj.handle(chat_doc))
315
+ setattr(self, handler, lambda obj, chat_doc: obj.handle(chat_doc))
306
316
  else:
307
- setattr(self, tool, lambda obj: obj.handle())
317
+ setattr(self, handler, lambda obj: obj.handle())
308
318
  elif (
309
319
  hasattr(message_class, "response")
310
320
  and inspect.isfunction(message_class.response)
311
- and not hasattr(self, tool)
321
+ and not hasattr(self, handler)
312
322
  ):
313
323
  has_chat_doc_arg = (
314
324
  len(inspect.signature(message_class.response).parameters) > 2
315
325
  )
316
326
  if has_chat_doc_arg:
317
- setattr(self, tool, lambda obj, chat_doc: obj.response(self, chat_doc))
327
+ setattr(self, handler, lambda obj,
328
+ chat_doc: obj.response(self, chat_doc))
318
329
  else:
319
- setattr(self, tool, lambda obj: obj.response(self))
330
+ setattr(self, handler, lambda obj: obj.response(self))
320
331
 
321
332
  if hasattr(message_class, "handle_message_fallback") and (
322
333
  inspect.isfunction(message_class.handle_message_fallback)
@@ -327,11 +338,11 @@ class Agent(ABC):
327
338
  lambda msg: message_class.handle_message_fallback(self, msg),
328
339
  )
329
340
 
330
- async_tool_name = f"{tool}_async"
341
+ async_handler_name = f"{handler}_async"
331
342
  if (
332
343
  hasattr(message_class, "handle_async")
333
344
  and inspect.isfunction(message_class.handle_async)
334
- and not hasattr(self, async_tool_name)
345
+ and not hasattr(self, async_handler_name)
335
346
  ):
336
347
  has_chat_doc_arg = (
337
348
  len(inspect.signature(message_class.handle_async).parameters) > 1
@@ -349,11 +360,11 @@ class Agent(ABC):
349
360
  async def handler(obj):
350
361
  return await obj.handle_async()
351
362
 
352
- setattr(self, async_tool_name, handler)
363
+ setattr(self, async_handler_name, handler)
353
364
  elif (
354
365
  hasattr(message_class, "response_async")
355
366
  and inspect.isfunction(message_class.response_async)
356
- and not hasattr(self, async_tool_name)
367
+ and not hasattr(self, async_handler_name)
357
368
  ):
358
369
  has_chat_doc_arg = (
359
370
  len(inspect.signature(message_class.response_async).parameters) > 2
@@ -371,7 +382,7 @@ class Agent(ABC):
371
382
  async def handler(obj):
372
383
  return await obj.response_async(self)
373
384
 
374
- setattr(self, async_tool_name, handler)
385
+ setattr(self, async_handler_name, handler)
375
386
 
376
387
  return [tool]
377
388
 
@@ -1742,7 +1753,11 @@ class Agent(ABC):
1742
1753
  Asynch version of `handle_tool_message`. See there for details.
1743
1754
  """
1744
1755
  tool_name = tool.default_value("request")
1745
- handler_method = getattr(self, tool_name + "_async", None)
1756
+ if hasattr(tool, "_handler"):
1757
+ handler_name = getattr(tool, "_handler", tool_name)
1758
+ else:
1759
+ handler_name = tool_name
1760
+ handler_method = getattr(self, handler_name + "_async", None)
1746
1761
  if handler_method is None:
1747
1762
  return self.handle_tool_message(tool, chat_doc=chat_doc)
1748
1763
  has_chat_doc_arg = (
@@ -1781,7 +1796,11 @@ class Agent(ABC):
1781
1796
 
1782
1797
  """
1783
1798
  tool_name = tool.default_value("request")
1784
- handler_method = getattr(self, tool_name, None)
1799
+ if hasattr(tool, "_handler"):
1800
+ handler_name = getattr(tool, "_handler", tool_name)
1801
+ else:
1802
+ handler_name = tool_name
1803
+ handler_method = getattr(self, handler_name, None)
1785
1804
  if handler_method is None:
1786
1805
  return None
1787
1806
  has_chat_doc_arg = (
@@ -105,6 +105,7 @@ class GeminiModel(str, Enum):
105
105
  GEMINI_1_5_FLASH = "gemini/gemini-1.5-flash"
106
106
  GEMINI_1_5_FLASH_8B = "gemini/gemini-1.5-flash-8b"
107
107
  GEMINI_1_5_PRO = "gemini/gemini-1.5-pro"
108
+ GEMINI_2_FLASH = "gemini/gemini-2.0-flash-exp"
108
109
 
109
110
 
110
111
  class OpenAICompletionModel(str, Enum):
@@ -443,6 +444,7 @@ class OpenAIGPT(LanguageModel):
443
444
  config = config.copy()
444
445
  super().__init__(config)
445
446
  self.config: OpenAIGPTConfig = config
447
+ self.chat_model_orig = self.config.chat_model
446
448
 
447
449
  # Run the first time the model is used
448
450
  self.run_on_first_use = cache(self.config.run_on_first_use)
@@ -451,6 +453,7 @@ class OpenAIGPT(LanguageModel):
451
453
  # to allow quick testing with other models
452
454
  if settings.chat_model != "":
453
455
  self.config.chat_model = settings.chat_model
456
+ self.chat_model_orig = settings.chat_model
454
457
  self.config.completion_model = settings.chat_model
455
458
 
456
459
  if len(parts := self.config.chat_model.split("//")) > 1:
@@ -565,7 +568,7 @@ class OpenAIGPT(LanguageModel):
565
568
 
566
569
  self.is_groq = self.config.chat_model.startswith("groq/")
567
570
  self.is_cerebras = self.config.chat_model.startswith("cerebras/")
568
- self.is_gemini = self.config.chat_model.startswith("gemini/")
571
+ self.is_gemini = self.is_gemini_model()
569
572
  self.is_glhf = self.config.chat_model.startswith("glhf/")
570
573
  self.is_openrouter = self.config.chat_model.startswith("openrouter/")
571
574
 
@@ -690,6 +693,20 @@ class OpenAIGPT(LanguageModel):
690
693
  openai_completion_models = [e.value for e in OpenAICompletionModel]
691
694
  return self.config.completion_model in openai_completion_models
692
695
 
696
+ def is_gemini_model(self) -> bool:
697
+ gemini_models = [e.value for e in GeminiModel]
698
+ return self.chat_model_orig in gemini_models or self.chat_model_orig.startswith(
699
+ "gemini/"
700
+ )
701
+
702
+ def requires_first_user_message(self) -> bool:
703
+ """
704
+ Does the chat_model require a non-empty first user message?
705
+ TODO: Add other models here; we know gemini requires a non-empty
706
+ user message, after the system message.
707
+ """
708
+ return self.is_gemini_model()
709
+
693
710
  def unsupported_params(self) -> List[str]:
694
711
  """
695
712
  List of params that are not supported by the current model
@@ -1663,6 +1680,20 @@ class OpenAIGPT(LanguageModel):
1663
1680
  ]
1664
1681
  else:
1665
1682
  llm_messages = messages
1683
+ if (
1684
+ len(llm_messages) == 1
1685
+ and llm_messages[0].role == Role.SYSTEM
1686
+ and self.requires_first_user_message()
1687
+ ):
1688
+ # some LLMs, notable Gemini as of 12/11/24,
1689
+ # require the first message to be from the user,
1690
+ # so insert a dummy user msg if needed.
1691
+ llm_messages.insert(
1692
+ 1,
1693
+ LLMMessage(
1694
+ role=Role.USER, content="Follow the above instructions."
1695
+ ),
1696
+ )
1666
1697
 
1667
1698
  # Azure uses different parameters. It uses ``engine`` instead of ``model``
1668
1699
  # and the value should be the deployment_name not ``self.config.chat_model``
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langroid"
3
- version = "0.27.4"
3
+ version = "0.28.0"
4
4
  description = "Harness LLMs with Multi-Agent Programming"
5
5
  authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
6
6
  readme = "README.md"
@@ -93,6 +93,7 @@ gitpython = "^3.1.43"
93
93
  python-arango = {version="^8.1.2", optional=true}
94
94
  arango-datasets = {version="^1.2.2", optional=true}
95
95
  adb-cloud-connector = "^1.0.2"
96
+ pytest-rerunfailures = "^15.0"
96
97
 
97
98
 
98
99
  [tool.poetry.extras]
File without changes
File without changes
File without changes
File without changes
File without changes