langroid 0.37.4__py3-none-any.whl → 0.37.6__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.
@@ -1023,7 +1023,7 @@ class ChatAgent(Agent):
1023
1023
  all_tools: bool = False,
1024
1024
  ) -> List[ToolMessage]:
1025
1025
  """
1026
- Extracts messages and tracks whether any errors occured. If strict mode
1026
+ Extracts messages and tracks whether any errors occurred. If strict mode
1027
1027
  was enabled, disables it for the tool, else triggers strict recovery.
1028
1028
  """
1029
1029
  self.tool_error = False
@@ -427,15 +427,7 @@ class SQLChatAgent(ChatAgent):
427
427
  return error_message_template
428
428
 
429
429
  def _available_tool_names(self) -> str:
430
- return ",".join(
431
- tool.name() # type: ignore
432
- for tool in [
433
- RunQueryTool,
434
- GetTableNamesTool,
435
- GetTableSchemaTool,
436
- GetColumnDescriptionsTool,
437
- ]
438
- )
430
+ return ",".join(self.llm_tools_usable)
439
431
 
440
432
  def _tool_result_llm_answer_prompt(self) -> str:
441
433
  """
@@ -510,7 +502,7 @@ class SQLChatAgent(ChatAgent):
510
502
  {self._tool_result_llm_answer_prompt()}
511
503
  OTHERWISE:
512
504
  continue using one of your available TOOLs:
513
- {self._available_tool_names()}
505
+ {",".join(self.llm_tools_usable)}
514
506
  """
515
507
  return final_message
516
508
 
@@ -78,6 +78,7 @@ class LLMConfig(BaseSettings):
78
78
  # TODO: we could have a `stream_reasoning` flag here to control whether to show
79
79
  # reasoning output from reasoning models
80
80
  cache_config: None | CacheDBConfig = RedisCacheConfig()
81
+ thought_delimiters: Tuple[str, str] = ("<think>", "</think>")
81
82
 
82
83
  # Dict of model -> (input/prompt cost, output/completion cost)
83
84
  chat_cost_per_1k_tokens: Tuple[float, float] = (0.0, 0.0)
@@ -646,6 +647,26 @@ class LanguageModel(ABC):
646
647
  total_cost += counter.cost
647
648
  return total_tokens, total_cost
648
649
 
650
+ def get_reasoning_final(self, message: str) -> Tuple[str, str]:
651
+ """Extract "reasoning" and "final answer" from an LLM response, if the
652
+ reasoning is found within configured delimiters, like <think>, </think>.
653
+ E.g.,
654
+ '<think> Okay, let's see, the user wants... </think> 2 + 3 = 5'
655
+
656
+ Args:
657
+ message (str): message from LLM
658
+
659
+ Returns:
660
+ Tuple[str, str]: reasoning, final answer
661
+ """
662
+ start, end = self.config.thought_delimiters
663
+ if start in message and end in message:
664
+ parts = message.split(start)
665
+ if len(parts) > 1:
666
+ reasoning, final = parts[1].split(end)
667
+ return reasoning, final
668
+ return "", message
669
+
649
670
  def followup_to_standalone(
650
671
  self, chat_history: List[Tuple[str, str]], question: str
651
672
  ) -> str:
@@ -1368,6 +1368,11 @@ class OpenAIGPT(LanguageModel):
1368
1368
  choices=[msg],
1369
1369
  usage=dict(total_tokens=0),
1370
1370
  )
1371
+ if reasoning == "":
1372
+ # some LLM APIs may not return a separate reasoning field,
1373
+ # and the reasoning may be included in the message content
1374
+ # within delimiters like <think> ... </think>
1375
+ reasoning, completion = self.get_reasoning_final(completion)
1371
1376
  return (
1372
1377
  LLMResponse(
1373
1378
  message=completion,
@@ -1897,9 +1902,19 @@ class OpenAIGPT(LanguageModel):
1897
1902
  }
1898
1903
  }
1899
1904
  """
1900
- message = response["choices"][0]["message"]
1905
+ if response.get("choices") is None:
1906
+ message = {}
1907
+ else:
1908
+ message = response["choices"][0].get("message", {})
1909
+ if message is None:
1910
+ message = {}
1901
1911
  msg = message.get("content", "")
1902
1912
  reasoning = message.get("reasoning_content", "")
1913
+ if reasoning == "":
1914
+ # some LLM APIs may not return a separate reasoning field,
1915
+ # and the reasoning may be included in the message content
1916
+ # within delimiters like <think> ... </think>
1917
+ reasoning, msg = self.get_reasoning_final(msg)
1903
1918
 
1904
1919
  if message.get("function_call") is None:
1905
1920
  fun_call = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langroid
3
- Version: 0.37.4
3
+ Version: 0.37.6
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  Author-email: Prasad Chalasani <pchalasani@gmail.com>
6
6
  License: MIT
@@ -5,7 +5,7 @@ langroid/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,786
6
6
  langroid/agent/base.py,sha256=oThlrYygKDu1-bKjAfygldJ511gMKT8Z0qCrD52DdDM,77834
7
7
  langroid/agent/batch.py,sha256=vi1r5i1-vN80WfqHDSwjEym_KfGsqPGUtwktmiK1nuk,20635
8
- langroid/agent/chat_agent.py,sha256=UvcZRoQ5jIYvlei8rku0T2Ul8tMpEhCJ2FGvr5_yc5Q,82275
8
+ langroid/agent/chat_agent.py,sha256=_7vOhTauPpPiOih2hnec8hz0rytaxGN110ja9wRCLJ0,82276
9
9
  langroid/agent/chat_document.py,sha256=xzMtrPbaW-Y-BnF7kuhr2dorsD-D5rMWzfOqJ8HAoo8,17885
10
10
  langroid/agent/openai_assistant.py,sha256=JkAcs02bIrgPNVvUWVR06VCthc5-ulla2QMBzux_q6o,34340
11
11
  langroid/agent/task.py,sha256=XrXUbSoiFasvpIsZPn_cBpdWaTCKljJPRimtLMrSZrs,90347
@@ -35,7 +35,7 @@ langroid/agent/special/neo4j/neo4j_chat_agent.py,sha256=1RMKupJra0KZ-hA7AiiR662S
35
35
  langroid/agent/special/neo4j/system_messages.py,sha256=m2jsVayey6E_88F5B_gW2WbWKBJvIeDUoVCRBbNs97o,4522
36
36
  langroid/agent/special/neo4j/tools.py,sha256=Vw3HvtDfG2c4_bUHgt4_ZbJq48lpIQstbjjwhh1BjrQ,905
37
37
  langroid/agent/special/sql/__init__.py,sha256=mWfmm1QpXCezpFOS2eI57M0L_Ok3q5_ukG8tXBnBrEA,319
38
- langroid/agent/special/sql/sql_chat_agent.py,sha256=CJ-vQFbtcGhmOM-GBQvG2quUmicXXW0XPK1pj52E-54,25639
38
+ langroid/agent/special/sql/sql_chat_agent.py,sha256=X0GzKPOHoYv36M_jYYUgYKW9H1Rum87O11iFpR0yhKQ,25430
39
39
  langroid/agent/special/sql/utils/__init__.py,sha256=JFif6CRTrN-bc91uuAI4K9fe2ndIWSNMVxJ0WA68--M,446
40
40
  langroid/agent/special/sql/utils/description_extractors.py,sha256=cX8TIpmTPXZXQTMpIi3OUFwFsPywxFFdurpx717Kq0I,6529
41
41
  langroid/agent/special/sql/utils/populate_metadata.py,sha256=1J22UsyEPKzwK0XlJZtYn9r6kYc0FXIr8-lZrndYlhc,3131
@@ -66,10 +66,10 @@ langroid/embedding_models/protoc/embeddings_pb2.pyi,sha256=UkNy7BrNsmQm0vLb3NtGX
66
66
  langroid/embedding_models/protoc/embeddings_pb2_grpc.py,sha256=9dYQqkW3JPyBpSEjeGXTNpSqAkC-6FPtBHyteVob2Y8,2452
67
67
  langroid/language_models/__init__.py,sha256=ps8nhRavCu2-Bv7IQ5hrzody6lzKjHkivJsblDZZIQ8,1020
68
68
  langroid/language_models/azure_openai.py,sha256=zNQzzsERxNestq-hFfQZbvTzK43G2vjRWnTV3ktm1DQ,5845
69
- langroid/language_models/base.py,sha256=avM_RgoTPm1Esr8KSmW-4G0YBSfabeOnTEX3hrT_vM0,24104
69
+ langroid/language_models/base.py,sha256=qxPcY-zBoP9xXVtytg4kfjTKLU9QOZLLAfDa_6skE94,24921
70
70
  langroid/language_models/config.py,sha256=9Q8wk5a7RQr8LGMT_0WkpjY8S4ywK06SalVRjXlfCiI,378
71
71
  langroid/language_models/mock_lm.py,sha256=5BgHKDVRWFbUwDT_PFgTZXz9-k8wJSA2e3PZmyDgQ1k,4022
72
- langroid/language_models/openai_gpt.py,sha256=1Nru0al-5i2jI4qqwteUt4mYqcBm5Cxdt19wGSnVU7s,79550
72
+ langroid/language_models/openai_gpt.py,sha256=wcxfFIovwPG5Xgzh5t5gXL_5E52YwvQJnnEHHkRvC7o,80286
73
73
  langroid/language_models/utils.py,sha256=L4_CbihDMTGcsg0TOG1Yd5JFEto46--h7CX_14m89sQ,5016
74
74
  langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
75
75
  langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
@@ -123,7 +123,7 @@ langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3Hmh
123
123
  langroid/vector_store/momento.py,sha256=xOaU7Hlyyn_5ihb0ARS5JHtmrKrTCt2IdRA-ioMM5ek,10307
124
124
  langroid/vector_store/qdrantdb.py,sha256=v7TAsIoj_vxeKDYS9tpwJLBZA8fuTweTYxHo0X_uawM,17949
125
125
  langroid/vector_store/weaviatedb.py,sha256=FOzgvqLqvdN5jJebVtJ-8tu2CeBzBfSP3ih4_ODEOOw,10605
126
- langroid-0.37.4.dist-info/METADATA,sha256=Qvam94KDF18KTUuUZerNojHZbq1feM1SuztuWoPTwRU,60524
127
- langroid-0.37.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
128
- langroid-0.37.4.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
129
- langroid-0.37.4.dist-info/RECORD,,
126
+ langroid-0.37.6.dist-info/METADATA,sha256=ojHxwQNyv1AjqVZzNBMkUw0M3DPa_Ml4xEY3gFK81YU,60524
127
+ langroid-0.37.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
128
+ langroid-0.37.6.dist-info/licenses/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
129
+ langroid-0.37.6.dist-info/RECORD,,