langroid 0.6.7__py3-none-any.whl → 0.8.0__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.
@@ -4,6 +4,7 @@ import logging
4
4
  import os
5
5
  import sys
6
6
  import warnings
7
+ from collections import defaultdict
7
8
  from enum import Enum
8
9
  from functools import cache
9
10
  from itertools import chain
@@ -37,7 +38,10 @@ from langroid.language_models.base import (
37
38
  LLMMessage,
38
39
  LLMResponse,
39
40
  LLMTokenUsage,
41
+ OpenAIToolCall,
42
+ OpenAIToolSpec,
40
43
  Role,
44
+ ToolChoiceTypes,
41
45
  )
42
46
  from langroid.language_models.config import HFPromptFormatterConfig
43
47
  from langroid.language_models.prompt_formatter.hf_formatter import (
@@ -544,7 +548,7 @@ class OpenAIGPT(LanguageModel):
544
548
  Order of priority:
545
549
  - (1) Params (mainly max_tokens) in the chat/achat/generate/agenerate call
546
550
  (these are passed in via kwargs)
547
- - (2) Params in OpenAIGPTConfi.params (of class OpenAICallParams)
551
+ - (2) Params in OpenAIGPTConfig.params (of class OpenAICallParams)
548
552
  - (3) Specific Params in OpenAIGPTConfig (just temperature for now)
549
553
  """
550
554
  params = dict(
@@ -614,6 +618,7 @@ class OpenAIGPT(LanguageModel):
614
618
  self,
615
619
  event,
616
620
  chat: bool = False,
621
+ tool_deltas: List[Dict[str, Any]] = [],
617
622
  has_function: bool = False,
618
623
  completion: str = "",
619
624
  function_args: str = "",
@@ -637,6 +642,7 @@ class OpenAIGPT(LanguageModel):
637
642
  choices = [{}]
638
643
  event_args = ""
639
644
  event_fn_name = ""
645
+ event_tool_deltas: Optional[List[Dict[str, Any]]] = None
640
646
 
641
647
  # The first two events in the stream of Azure OpenAI is useless.
642
648
  # In the 1st: choices list is empty, in the 2nd: the dict delta has null content
@@ -648,6 +654,10 @@ class OpenAIGPT(LanguageModel):
648
654
  event_fn_name = delta["function_call"]["name"]
649
655
  if "arguments" in delta["function_call"]:
650
656
  event_args = delta["function_call"]["arguments"]
657
+ if "tool_calls" in delta and delta["tool_calls"] is not None:
658
+ # it's a list of deltas, usually just one
659
+ event_tool_deltas = delta["tool_calls"]
660
+ tool_deltas += event_tool_deltas
651
661
  else:
652
662
  event_text = choices[0]["text"]
653
663
  if event_text:
@@ -670,7 +680,31 @@ class OpenAIGPT(LanguageModel):
670
680
  sys.stdout.write(Colors().GREEN + event_args)
671
681
  sys.stdout.flush()
672
682
  self.config.streamer(event_args)
673
- if choices[0].get("finish_reason", "") in ["stop", "function_call"]:
683
+
684
+ if event_tool_deltas is not None:
685
+ # print out streaming tool calls
686
+ for td in event_tool_deltas:
687
+ if td["function"]["name"] is not None:
688
+ tool_fn_name = td["function"]["name"]
689
+ if not is_async:
690
+ sys.stdout.write(
691
+ Colors().GREEN + "OAI-TOOL: " + tool_fn_name + ": "
692
+ )
693
+ sys.stdout.flush()
694
+ self.config.streamer(tool_fn_name)
695
+ if td["function"]["arguments"] != "":
696
+ tool_fn_args = td["function"]["arguments"]
697
+ if not is_async:
698
+ sys.stdout.write(Colors().GREEN + tool_fn_args)
699
+ sys.stdout.flush()
700
+ self.config.streamer(tool_fn_args)
701
+
702
+ # show this delta in the stream
703
+ if choices[0].get("finish_reason", "") in [
704
+ "stop",
705
+ "function_call",
706
+ "tool_calls",
707
+ ]:
674
708
  # for function_call, finish_reason does not necessarily
675
709
  # contain "function_call" as mentioned in the docs.
676
710
  # So we check for "stop" or "function_call" here.
@@ -699,6 +733,7 @@ class OpenAIGPT(LanguageModel):
699
733
  sys.stdout.write(Colors().GREEN)
700
734
  sys.stdout.flush()
701
735
  has_function = False
736
+ tool_deltas: List[Dict[str, Any]] = []
702
737
  try:
703
738
  for event in response:
704
739
  (
@@ -710,6 +745,7 @@ class OpenAIGPT(LanguageModel):
710
745
  ) = self._process_stream_event(
711
746
  event,
712
747
  chat=chat,
748
+ tool_deltas=tool_deltas,
713
749
  has_function=has_function,
714
750
  completion=completion,
715
751
  function_args=function_args,
@@ -725,11 +761,11 @@ class OpenAIGPT(LanguageModel):
725
761
 
726
762
  return self._create_stream_response(
727
763
  chat=chat,
764
+ tool_deltas=tool_deltas,
728
765
  has_function=has_function,
729
766
  completion=completion,
730
767
  function_args=function_args,
731
768
  function_name=function_name,
732
- is_async=False,
733
769
  )
734
770
 
735
771
  @async_retry_with_exponential_backoff
@@ -754,6 +790,7 @@ class OpenAIGPT(LanguageModel):
754
790
  sys.stdout.write(Colors().GREEN)
755
791
  sys.stdout.flush()
756
792
  has_function = False
793
+ tool_deltas: List[Dict[str, Any]] = []
757
794
  try:
758
795
  async for event in response:
759
796
  (
@@ -765,6 +802,7 @@ class OpenAIGPT(LanguageModel):
765
802
  ) = self._process_stream_event(
766
803
  event,
767
804
  chat=chat,
805
+ tool_deltas=tool_deltas,
768
806
  has_function=has_function,
769
807
  completion=completion,
770
808
  function_args=function_args,
@@ -780,52 +818,182 @@ class OpenAIGPT(LanguageModel):
780
818
 
781
819
  return self._create_stream_response(
782
820
  chat=chat,
821
+ tool_deltas=tool_deltas,
783
822
  has_function=has_function,
784
823
  completion=completion,
785
824
  function_args=function_args,
786
825
  function_name=function_name,
787
- is_async=True,
788
826
  )
789
827
 
828
+ @staticmethod
829
+ def tool_deltas_to_tools(tools: List[Dict[str, Any]]) -> Tuple[
830
+ str,
831
+ List[OpenAIToolCall],
832
+ List[Dict[str, Any]],
833
+ ]:
834
+ """
835
+ Convert accumulated tool-call deltas to OpenAIToolCall objects.
836
+ Adapted from this excellent code:
837
+ https://community.openai.com/t/help-for-function-calls-with-streaming/627170/2
838
+
839
+ Args:
840
+ tools: list of tool deltas received from streaming API
841
+
842
+ Returns:
843
+ str: plain text corresponding to tool calls that failed to parse
844
+ List[OpenAIToolCall]: list of OpenAIToolCall objects
845
+ List[Dict[str, Any]]: list of tool dicts
846
+ (to reconstruct OpenAI API response, so it can be cached)
847
+ """
848
+ # Initialize a dictionary with default values
849
+
850
+ # idx -> dict repr of tool
851
+ # (used to simulate OpenAIResponse object later, and also to
852
+ # accumulate function args as strings)
853
+ idx2tool_dict: Dict[str, Dict[str, Any]] = defaultdict(
854
+ lambda: {
855
+ "id": None,
856
+ "function": {"arguments": "", "name": None},
857
+ "type": None,
858
+ }
859
+ )
860
+
861
+ for tool_delta in tools:
862
+ if tool_delta["id"] is not None:
863
+ idx2tool_dict[tool_delta["index"]]["id"] = tool_delta["id"]
864
+
865
+ if tool_delta["function"]["name"] is not None:
866
+ idx2tool_dict[tool_delta["index"]]["function"]["name"] = tool_delta[
867
+ "function"
868
+ ]["name"]
869
+
870
+ idx2tool_dict[tool_delta["index"]]["function"]["arguments"] += tool_delta[
871
+ "function"
872
+ ]["arguments"]
873
+
874
+ if tool_delta["type"] is not None:
875
+ idx2tool_dict[tool_delta["index"]]["type"] = tool_delta["type"]
876
+
877
+ # (try to) parse the fn args of each tool
878
+ contents: List[str] = []
879
+ good_indices = []
880
+ id2args: Dict[str, None | Dict[str, Any]] = {}
881
+ for idx, tool_dict in idx2tool_dict.items():
882
+ failed_content, args_dict = OpenAIGPT._parse_function_args(
883
+ tool_dict["function"]["arguments"]
884
+ )
885
+ # used to build tool_calls_list below
886
+ id2args[tool_dict["id"]] = args_dict or None # if {}, store as None
887
+ if failed_content != "":
888
+ contents.append(failed_content)
889
+ else:
890
+ good_indices.append(idx)
891
+
892
+ # remove the failed tool calls
893
+ idx2tool_dict = {
894
+ idx: tool_dict
895
+ for idx, tool_dict in idx2tool_dict.items()
896
+ if idx in good_indices
897
+ }
898
+
899
+ # create OpenAIToolCall list
900
+ tool_calls_list = [
901
+ OpenAIToolCall(
902
+ id=tool_dict["id"],
903
+ function=LLMFunctionCall(
904
+ name=tool_dict["function"]["name"],
905
+ arguments=id2args.get(tool_dict["id"]),
906
+ ),
907
+ type=tool_dict["type"],
908
+ )
909
+ for tool_dict in idx2tool_dict.values()
910
+ ]
911
+ return "\n".join(contents), tool_calls_list, list(idx2tool_dict.values())
912
+
913
+ @staticmethod
914
+ def _parse_function_args(args: str) -> Tuple[str, Dict[str, Any]]:
915
+ """
916
+ Try to parse the `args` string as function args.
917
+
918
+ Args:
919
+ args: string containing function args
920
+
921
+ Returns:
922
+ Tuple of content, function name and args dict.
923
+ If parsing unsuccessful, returns the original string as content,
924
+ else returns the args dict.
925
+ """
926
+ content = ""
927
+ args_dict = {}
928
+ try:
929
+ stripped_fn_args = args.strip()
930
+ dict_or_list = parse_imperfect_json(stripped_fn_args)
931
+ if not isinstance(dict_or_list, dict):
932
+ raise ValueError(
933
+ f"""
934
+ Invalid function args: {stripped_fn_args}
935
+ parsed as {dict_or_list},
936
+ which is not a valid dict.
937
+ """
938
+ )
939
+ args_dict = dict_or_list
940
+ except (SyntaxError, ValueError) as e:
941
+ logging.warning(
942
+ f"""
943
+ Parsing OpenAI function args failed: {args};
944
+ treating args as normal message. Error detail:
945
+ {e}
946
+ """
947
+ )
948
+ content = args
949
+
950
+ return content, args_dict
951
+
790
952
  def _create_stream_response(
791
953
  self,
792
954
  chat: bool = False,
955
+ tool_deltas: List[Dict[str, Any]] = [],
793
956
  has_function: bool = False,
794
957
  completion: str = "",
795
958
  function_args: str = "",
796
959
  function_name: str = "",
797
- is_async: bool = False,
798
960
  ) -> Tuple[LLMResponse, Dict[str, Any]]:
961
+ """
962
+ Create an LLMResponse object from the streaming API response.
963
+
964
+ Args:
965
+ chat: whether in chat-mode (or else completion-mode)
966
+ tool_deltas: list of tool deltas received from streaming API
967
+ has_function: whether the response contains a function_call
968
+ completion: completion text
969
+ function_args: string representing function args
970
+ function_name: name of the function
971
+ Returns:
972
+ Tuple consisting of:
973
+ LLMResponse object (with message, usage),
974
+ Dict version of OpenAIResponse object (with choices, usage)
975
+ (this is needed so we can cache the response, as if it were
976
+ a non-streaming response)
977
+ """
799
978
  # check if function_call args are valid, if not,
800
979
  # treat this as a normal msg, not a function call
801
- args = {}
980
+ args: Dict[str, Any] = {}
802
981
  if has_function and function_args != "":
803
- try:
804
- stripped_fn_args = function_args.strip()
805
- dict_or_list = parse_imperfect_json(stripped_fn_args)
806
- if not isinstance(dict_or_list, dict):
807
- raise ValueError(
808
- f"""
809
- Invalid function args: {stripped_fn_args}
810
- parsed as {dict_or_list},
811
- which is not a valid dict.
812
- """
813
- )
814
- args = dict_or_list
815
- except (SyntaxError, ValueError) as e:
816
- logging.warning(
817
- f"""
818
- Parsing OpenAI function args failed: {function_args};
819
- treating args as normal message. Error detail:
820
- {e}
821
- """
822
- )
982
+ content, args = self._parse_function_args(function_args)
983
+ completion = completion + content
984
+ if content != "":
823
985
  has_function = False
824
- completion = completion + function_args
825
986
 
826
987
  # mock openai response so we can cache it
827
988
  if chat:
989
+ failed_content, tool_calls, tool_dicts = OpenAIGPT.tool_deltas_to_tools(
990
+ tool_deltas,
991
+ )
992
+ completion = completion + "\n" + failed_content
828
993
  msg: Dict[str, Any] = dict(message=dict(content=completion))
994
+ if len(tool_dicts) > 0:
995
+ msg["message"]["tool_calls"] = tool_dicts
996
+
829
997
  if has_function:
830
998
  function_call = LLMFunctionCall(name=function_name)
831
999
  function_call_dict = function_call.dict()
@@ -839,6 +1007,8 @@ class OpenAIGPT(LanguageModel):
839
1007
  # non-chat mode has no function_call
840
1008
  msg = dict(text=completion)
841
1009
 
1010
+ # create an OpenAIResponse object so we can cache it as if it were
1011
+ # a non-streaming response
842
1012
  openai_response = OpenAIResponse(
843
1013
  choices=[msg],
844
1014
  usage=dict(total_tokens=0),
@@ -847,6 +1017,7 @@ class OpenAIGPT(LanguageModel):
847
1017
  LLMResponse(
848
1018
  message=completion,
849
1019
  cached=False,
1020
+ oai_tool_calls=tool_calls or None, # don't allow empty list [] here
850
1021
  function_call=function_call if has_function else None,
851
1022
  ),
852
1023
  openai_response.dict(),
@@ -1061,16 +1232,19 @@ class OpenAIGPT(LanguageModel):
1061
1232
  self,
1062
1233
  messages: Union[str, List[LLMMessage]],
1063
1234
  max_tokens: int = 200,
1235
+ tools: Optional[List[OpenAIToolSpec]] = None,
1236
+ tool_choice: ToolChoiceTypes | Dict[str, str | Dict[str, str]] = "auto",
1064
1237
  functions: Optional[List[LLMFunctionSpec]] = None,
1065
1238
  function_call: str | Dict[str, str] = "auto",
1066
1239
  ) -> LLMResponse:
1067
1240
  self.run_on_first_use()
1068
1241
 
1069
- if functions is not None and not self.is_openai_chat_model():
1242
+ if [functions, tools] != [None, None] and not self.is_openai_chat_model():
1070
1243
  raise ValueError(
1071
1244
  f"""
1072
- `functions` can only be specified for OpenAI chat models;
1073
- {self.config.chat_model} does not support function-calling.
1245
+ `functions` and `tools` can only be specified for OpenAI chat LLMs,
1246
+ or LLMs served via an OpenAI-compatible API.
1247
+ {self.config.chat_model} does not support function-calling or tools.
1074
1248
  Instead, please use Langroid's ToolMessages, which are equivalent.
1075
1249
  In the ChatAgentConfig, set `use_functions_api=False`
1076
1250
  and `use_tools=True`, this will enable ToolMessages.
@@ -1094,7 +1268,9 @@ class OpenAIGPT(LanguageModel):
1094
1268
  prompt = self.config.hf_formatter.format(messages)
1095
1269
  return self.generate(prompt=prompt, max_tokens=max_tokens)
1096
1270
  try:
1097
- return self._chat(messages, max_tokens, functions, function_call)
1271
+ return self._chat(
1272
+ messages, max_tokens, tools, tool_choice, functions, function_call
1273
+ )
1098
1274
  except Exception as e:
1099
1275
  # log and re-raise exception
1100
1276
  logging.error(friendly_error(e, "Error in OpenAIGPT.chat: "))
@@ -1104,16 +1280,18 @@ class OpenAIGPT(LanguageModel):
1104
1280
  self,
1105
1281
  messages: Union[str, List[LLMMessage]],
1106
1282
  max_tokens: int = 200,
1283
+ tools: Optional[List[OpenAIToolSpec]] = None,
1284
+ tool_choice: ToolChoiceTypes | Dict[str, str | Dict[str, str]] = "auto",
1107
1285
  functions: Optional[List[LLMFunctionSpec]] = None,
1108
1286
  function_call: str | Dict[str, str] = "auto",
1109
1287
  ) -> LLMResponse:
1110
1288
  self.run_on_first_use()
1111
1289
 
1112
- if functions is not None and not self.is_openai_chat_model():
1290
+ if [functions, tools] != [None, None] and not self.is_openai_chat_model():
1113
1291
  raise ValueError(
1114
1292
  f"""
1115
- `functions` can only be specified for OpenAI chat models;
1116
- {self.config.chat_model} does not support function-calling.
1293
+ `functions` and `tools` can only be specified for OpenAI chat models;
1294
+ {self.config.chat_model} does not support function-calling or tools.
1117
1295
  Instead, please use Langroid's ToolMessages, which are equivalent.
1118
1296
  In the ChatAgentConfig, set `use_functions_api=False`
1119
1297
  and `use_tools=True`, this will enable ToolMessages.
@@ -1146,7 +1324,14 @@ class OpenAIGPT(LanguageModel):
1146
1324
  prompt = formatter.format(messages)
1147
1325
  return await self.agenerate(prompt=prompt, max_tokens=max_tokens)
1148
1326
  try:
1149
- result = await self._achat(messages, max_tokens, functions, function_call)
1327
+ result = await self._achat(
1328
+ messages,
1329
+ max_tokens,
1330
+ tools,
1331
+ tool_choice,
1332
+ functions,
1333
+ function_call,
1334
+ )
1150
1335
  return result
1151
1336
  except Exception as e:
1152
1337
  # log and re-raise exception
@@ -1209,9 +1394,12 @@ class OpenAIGPT(LanguageModel):
1209
1394
  self,
1210
1395
  messages: Union[str, List[LLMMessage]],
1211
1396
  max_tokens: int,
1397
+ tools: Optional[List[OpenAIToolSpec]] = None,
1398
+ tool_choice: ToolChoiceTypes | Dict[str, str | Dict[str, str]] = "auto",
1212
1399
  functions: Optional[List[LLMFunctionSpec]] = None,
1213
1400
  function_call: str | Dict[str, str] = "auto",
1214
1401
  ) -> Dict[str, Any]:
1402
+ """Prepare args for LLM chat-completion API call"""
1215
1403
  if isinstance(messages, str):
1216
1404
  llm_messages = [
1217
1405
  LLMMessage(role=Role.SYSTEM, content="You are a helpful assistant."),
@@ -1243,6 +1431,19 @@ class OpenAIGPT(LanguageModel):
1243
1431
  function_call=function_call,
1244
1432
  )
1245
1433
  )
1434
+ if tools is not None:
1435
+ args.update(
1436
+ dict(
1437
+ tools=[
1438
+ dict(
1439
+ type="function",
1440
+ function=t.function.dict(),
1441
+ )
1442
+ for t in tools
1443
+ ],
1444
+ tool_choice=tool_choice,
1445
+ )
1446
+ )
1246
1447
  return args
1247
1448
 
1248
1449
  def _process_chat_completion_response(
@@ -1281,6 +1482,7 @@ class OpenAIGPT(LanguageModel):
1281
1482
  """
1282
1483
  message = response["choices"][0]["message"]
1283
1484
  msg = message["content"] or ""
1485
+
1284
1486
  if message.get("function_call") is None:
1285
1487
  fun_call = None
1286
1488
  else:
@@ -1297,10 +1499,24 @@ class OpenAIGPT(LanguageModel):
1297
1499
  args_str = message["function_call"]["arguments"] or ""
1298
1500
  msg_str = message["content"] or ""
1299
1501
  msg = msg_str + args_str
1300
-
1502
+ oai_tool_calls = None
1503
+ if message.get("tool_calls") is not None:
1504
+ oai_tool_calls = []
1505
+ for tool_call_dict in message["tool_calls"]:
1506
+ try:
1507
+ tool_call = OpenAIToolCall.from_dict(tool_call_dict)
1508
+ oai_tool_calls.append(tool_call)
1509
+ except (ValueError, SyntaxError):
1510
+ logging.warning(
1511
+ "Could not parse tool call: "
1512
+ f"{json.dumps(tool_call_dict)} "
1513
+ "treating as normal non-tool message"
1514
+ )
1515
+ msg = msg + "\n" + json.dumps(tool_call_dict)
1301
1516
  return LLMResponse(
1302
1517
  message=msg.strip() if msg is not None else "",
1303
1518
  function_call=fun_call,
1519
+ oai_tool_calls=oai_tool_calls or None, # don't allow empty list [] here
1304
1520
  cached=cached,
1305
1521
  usage=self._get_non_stream_token_usage(cached, response),
1306
1522
  )
@@ -1309,6 +1525,8 @@ class OpenAIGPT(LanguageModel):
1309
1525
  self,
1310
1526
  messages: Union[str, List[LLMMessage]],
1311
1527
  max_tokens: int,
1528
+ tools: Optional[List[OpenAIToolSpec]] = None,
1529
+ tool_choice: ToolChoiceTypes | Dict[str, str | Dict[str, str]] = "auto",
1312
1530
  functions: Optional[List[LLMFunctionSpec]] = None,
1313
1531
  function_call: str | Dict[str, str] = "auto",
1314
1532
  ) -> LLMResponse:
@@ -1333,6 +1551,8 @@ class OpenAIGPT(LanguageModel):
1333
1551
  args = self._prep_chat_completion(
1334
1552
  messages,
1335
1553
  max_tokens,
1554
+ tools,
1555
+ tool_choice,
1336
1556
  functions,
1337
1557
  function_call,
1338
1558
  )
@@ -1351,6 +1571,8 @@ class OpenAIGPT(LanguageModel):
1351
1571
  self,
1352
1572
  messages: Union[str, List[LLMMessage]],
1353
1573
  max_tokens: int,
1574
+ tools: Optional[List[OpenAIToolSpec]] = None,
1575
+ tool_choice: ToolChoiceTypes | Dict[str, str | Dict[str, str]] = "auto",
1354
1576
  functions: Optional[List[LLMFunctionSpec]] = None,
1355
1577
  function_call: str | Dict[str, str] = "auto",
1356
1578
  ) -> LLMResponse:
@@ -1360,6 +1582,8 @@ class OpenAIGPT(LanguageModel):
1360
1582
  args = self._prep_chat_completion(
1361
1583
  messages,
1362
1584
  max_tokens,
1585
+ tools,
1586
+ tool_choice,
1363
1587
  functions,
1364
1588
  function_call,
1365
1589
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langroid
3
- Version: 0.6.7
3
+ Version: 0.8.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -235,6 +235,8 @@ teacher_task.run()
235
235
  <details>
236
236
  <summary> <b>Click to expand</b></summary>
237
237
 
238
+ - **Aug 2024:**
239
+ - **[0.7.0](https://github.com/langroid/langroid/releases/tag/0.7.0)** OpenAI tools API support.
238
240
  - **Jul 2024:**
239
241
  - **[0.3.0](https://github.com/langroid/langroid/releases/tag/0.3.0)**: Added [FastEmbed](https://qdrant.github.io/fastembed/qdrant/Usage_With_Qdrant/) embeddings from Qdrant
240
242
  - **Jun 2024:**
@@ -1,14 +1,14 @@
1
1
  langroid/__init__.py,sha256=z_fCOLQJPOw3LLRPBlFB5-2HyCjpPgQa4m4iY5Fvb8Y,1800
2
2
  langroid/agent/__init__.py,sha256=ll0Cubd2DZ-fsCMl7e10hf9ZjFGKzphfBco396IKITY,786
3
- langroid/agent/base.py,sha256=x6SbInDGJUL_kusr-ligYsCwuaid2CmcRkzlucOXyw0,38999
3
+ langroid/agent/base.py,sha256=EOAdZ2K0Yjjdt3zkjNsUhHgRvYZT-eIgRbY4ldjt6hY,46995
4
4
  langroid/agent/batch.py,sha256=feRA_yRG768ElOQjrKEefcRv6Aefd_yY7qktuYUQDwc,10040
5
5
  langroid/agent/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- langroid/agent/callbacks/chainlit.py,sha256=UKG2_v4ktfkEaGvdouVRHEqQejEYya2Rli8jrP65TmA,22055
7
- langroid/agent/chat_agent.py,sha256=M5tdp1HuFthhMChLNd5XKBWxoiMSTkOuXlM8JoRLiUk,41586
8
- langroid/agent/chat_document.py,sha256=MwtNABK28tfSzqCeQlxoauT8uPn8oldU7dlnrX8aQ10,11232
6
+ langroid/agent/callbacks/chainlit.py,sha256=Qedk1-CBCgo9PdaIa7AboLBFCTgAMg9q5nGmoqpZ378,22050
7
+ langroid/agent/chat_agent.py,sha256=4bgLHBFSxL1dw1UAEF5zfCqnp_ss0MUUTOnjKkfOJRQ,45401
8
+ langroid/agent/chat_document.py,sha256=y3QBdpclTBuqs42c3lLO9HU4s70PyK133HXZxyaxNZ8,16322
9
9
  langroid/agent/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  langroid/agent/junk,sha256=LxfuuW7Cijsg0szAzT81OjWWv1PMNI-6w_-DspVIO2s,339
11
- langroid/agent/openai_assistant.py,sha256=3saI9PwF8IZNJcjqyUy-rj73TInAzdlk14LiOvT_Dkc,33548
11
+ langroid/agent/openai_assistant.py,sha256=TlMi5QecrxxhZ7TW03wB161elSSQYwL7H0xk8g7HawU,33879
12
12
  langroid/agent/special/__init__.py,sha256=gik_Xtm_zV7U9s30Mn8UX3Gyuy4jTjQe9zjiE3HWmEo,1273
13
13
  langroid/agent/special/doc_chat_agent.py,sha256=8NPAhMnHkFUolQ8EHos40tz5Vwuz_m33NjUfjheXWXY,54569
14
14
  langroid/agent/special/lance_doc_chat_agent.py,sha256=Hjpu6u9UPAFMg5J6K97PRFaLbNrGhInC0N9oGi09CeY,10006
@@ -29,16 +29,16 @@ langroid/agent/special/neo4j/utils/system_message.py,sha256=_2NKX2Sx_7nLGNk_0rUy
29
29
  langroid/agent/special/relevance_extractor_agent.py,sha256=zIx8GUdVo1aGW6ASla0NPQjYYIpmriK_TYMijqAx3F8,4796
30
30
  langroid/agent/special/retriever_agent.py,sha256=lvMvf-u9rSosg4YASuFdUbGLgkzLPknXAbJZfZ1LZCc,1868
31
31
  langroid/agent/special/sql/__init__.py,sha256=mWfmm1QpXCezpFOS2eI57M0L_Ok3q5_ukG8tXBnBrEA,319
32
- langroid/agent/special/sql/sql_chat_agent.py,sha256=8ZCKjN8GE4I4_G_YkMoZExT6StOWcXZYD95DQ2yI1ro,14436
32
+ langroid/agent/special/sql/sql_chat_agent.py,sha256=PArNz9up0atw0cJet1LOfWlpW6xgofVBDR7Z3xvpzHk,16592
33
33
  langroid/agent/special/sql/utils/__init__.py,sha256=JFif6CRTrN-bc91uuAI4K9fe2ndIWSNMVxJ0WA68--M,446
34
34
  langroid/agent/special/sql/utils/description_extractors.py,sha256=cX8TIpmTPXZXQTMpIi3OUFwFsPywxFFdurpx717Kq0I,6529
35
35
  langroid/agent/special/sql/utils/populate_metadata.py,sha256=1J22UsyEPKzwK0XlJZtYn9r6kYc0FXIr8-lZrndYlhc,3131
36
36
  langroid/agent/special/sql/utils/system_message.py,sha256=qKLHkvQWRQodTtPLPxr1GSLUYUFASZU8x-ybV67cB68,1885
37
37
  langroid/agent/special/sql/utils/tools.py,sha256=vFYysk6Vi7HJjII8B4RitA3pt_z3gkSglDNdhNVMiFc,1332
38
38
  langroid/agent/special/table_chat_agent.py,sha256=d9v2wsblaRx7oMnKhLV7uO_ujvk9gh59pSGvBXyeyNc,9659
39
- langroid/agent/task.py,sha256=vKM2dmRYSH4i_VA0lf2axUtZcTGU44rVHz6EyxI4kG0,73990
39
+ langroid/agent/task.py,sha256=eCA91yr6DSaRRGteTbSki-liMl6nspzRd_5Gin_ZFYw,75176
40
40
  langroid/agent/team.py,sha256=88VNRSmK35WEl620GfBzuIrBASXYSeBZ8yDKX-nP_Bo,75778
41
- langroid/agent/tool_message.py,sha256=ggxmIZO_wi6x5uD-YWml07Bfgms-ohOSKHyQQdJFi4o,9571
41
+ langroid/agent/tool_message.py,sha256=XPM6whazpUOQu_vM2D4Q_L9tV6Vs9OTXNrGchwcqD_o,9768
42
42
  langroid/agent/tools/__init__.py,sha256=e-63cfwQNk_ftRKQwgDAJQK16QLbRVWDBILeXIc7wLk,402
43
43
  langroid/agent/tools/duckduckgo_search_tool.py,sha256=NhsCaGZkdv28nja7yveAhSK_w6l_Ftym8agbrdzqgfo,1935
44
44
  langroid/agent/tools/extract_tool.py,sha256=u5lL9rKBzaLBOrRyLnTAZ97pQ1uxyLP39XsWMnpaZpw,3789
@@ -48,7 +48,7 @@ langroid/agent/tools/metaphor_search_tool.py,sha256=qj4gt453cLEX3EGW7nVzVu6X7LCd
48
48
  langroid/agent/tools/note_tool.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  langroid/agent/tools/recipient_tool.py,sha256=NrLxIeQT-kbMv7AeYX0uqvGeMK4Q3fIDvG15OVzlgk8,9624
50
50
  langroid/agent/tools/retrieval_tool.py,sha256=2q2pfoYbZNfbWQ0McxrtmfF0ekGglIgRl-6uF26pa-E,871
51
- langroid/agent/tools/rewind_tool.py,sha256=G4DiXuOt2nQ2fU7qvtJMdLyyf-rK7RZwLsFxsAUfk-Y,5606
51
+ langroid/agent/tools/rewind_tool.py,sha256=XAXL3BpNhCmBGYq_qi_sZfHJuIw7NY2jp4wnojJ7WRs,5606
52
52
  langroid/agent/tools/run_python_code.py,sha256=BvoxYzzHijU-p4703n2iVlt5BCieR1oMSy50w0tQZAg,1787
53
53
  langroid/agent/tools/segment_extract_tool.py,sha256=__srZ_VGYLVOdPrITUM8S0HpmX4q7r5FHWMDdHdEv8w,1440
54
54
  langroid/agent_config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -67,12 +67,14 @@ langroid/embedding_models/protoc/embeddings_pb2.pyi,sha256=UkNy7BrNsmQm0vLb3NtGX
67
67
  langroid/embedding_models/protoc/embeddings_pb2_grpc.py,sha256=9dYQqkW3JPyBpSEjeGXTNpSqAkC-6FPtBHyteVob2Y8,2452
68
68
  langroid/embedding_models/remote_embeds.py,sha256=6_kjXByVbqhY9cGwl9R83ZcYC2km-nGieNNAo1McHaY,5151
69
69
  langroid/exceptions.py,sha256=w_Cr41nPAmsa6gW5nNFaO9yDcBCWdQqRspL1jYvZf5w,2209
70
+ langroid/language_models/.chainlit/config.toml,sha256=1t5lHORGzc2E6dkaO9P15jYHu2w-4Kl9pYjpDPc84vs,3716
71
+ langroid/language_models/.chainlit/translations/en-US.json,sha256=DAFz2HjOFFfboCStrUfKFg2BpplJPK_OOtixwF_GivY,9931
70
72
  langroid/language_models/__init__.py,sha256=1sUGobooTqq77XC7LxKsvME0RgSd5GGmeyrPo9SMh4U,940
71
73
  langroid/language_models/azure_openai.py,sha256=G4le3j4YLHV7IwgB2C37hO3MKijZ1KjynbYlEvpIF7Y,6214
72
- langroid/language_models/base.py,sha256=nhY-AdSkfqaW4hzeIekxxZs29AWLd7X7GYhRygU9L74,17527
74
+ langroid/language_models/base.py,sha256=L76syCytos5IaQ5tpgToYJHThch4gA9uyjeMmjWjZ8E,21757
73
75
  langroid/language_models/config.py,sha256=9Q8wk5a7RQr8LGMT_0WkpjY8S4ywK06SalVRjXlfCiI,378
74
- langroid/language_models/mock_lm.py,sha256=qdgj-wtbQBXlibo_0rIRfCt0hGTPRoxy1C4VjN6quI4,2707
75
- langroid/language_models/openai_gpt.py,sha256=BI5q9AVEJA-jA0G0Eg60T4NF1AdNLSd1-sOSHXnxaYU,52428
76
+ langroid/language_models/mock_lm.py,sha256=2Ka05SVGSUy096bsa2AyjaqC5jmcFoe7HycpdnICTIw,3031
77
+ langroid/language_models/openai_gpt.py,sha256=Bv-FCva9q0oO85VSqNpaxEYI8zPwVXpHmmfV7O8QRhU,61325
76
78
  langroid/language_models/prompt_formatter/__init__.py,sha256=2-5cdE24XoFDhifOLl8yiscohil1ogbP1ECkYdBlBsk,372
77
79
  langroid/language_models/prompt_formatter/base.py,sha256=eDS1sgRNZVnoajwV_ZIha6cba5Dt8xjgzdRbPITwx3Q,1221
78
80
  langroid/language_models/prompt_formatter/hf_formatter.py,sha256=TFL6ppmeQWnzr6CKQzRZFYY810zE1mr8DZnhw6i85ok,5217
@@ -134,8 +136,8 @@ langroid/vector_store/meilisearch.py,sha256=6frB7GFWeWmeKzRfLZIvzRjllniZ1cYj3Hmh
134
136
  langroid/vector_store/momento.py,sha256=qR-zBF1RKVHQZPZQYW_7g-XpTwr46p8HJuYPCkfJbM4,10534
135
137
  langroid/vector_store/qdrant_cloud.py,sha256=3im4Mip0QXLkR6wiqVsjV1QvhSElfxdFSuDKddBDQ-4,188
136
138
  langroid/vector_store/qdrantdb.py,sha256=v88lqFkepADvlN6lByUj9I4NEKa9X9lWH16uTPPbYrE,17457
137
- pyproject.toml,sha256=WOkJHLl-xkyt4KNDhhl1B9I5KTg00EuyYcBQ5fgPZa4,7063
138
- langroid-0.6.7.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
139
- langroid-0.6.7.dist-info/METADATA,sha256=KWqO3AOdYeXoUSIJW3hdTkfnzfHwSanXvqZvAsNrtgQ,54402
140
- langroid-0.6.7.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
141
- langroid-0.6.7.dist-info/RECORD,,
139
+ pyproject.toml,sha256=pK1C4vWrb5-NkREBDkFao-3Pi-xXJXMjh_wjedpjFAk,7063
140
+ langroid-0.8.0.dist-info/LICENSE,sha256=EgVbvA6VSYgUlvC3RvPKehSg7MFaxWDsFuzLOsPPfJg,1065
141
+ langroid-0.8.0.dist-info/METADATA,sha256=i2_aKdjkgYcGAYMXEG2F3NC59yVI1w3uidn3edm5wAY,54518
142
+ langroid-0.8.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
143
+ langroid-0.8.0.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langroid"
3
- version = "0.6.7"
3
+ version = "0.8.0"
4
4
  description = "Harness LLMs with Multi-Agent Programming"
5
5
  authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
6
6
  readme = "README.md"