langroid 0.18.3__tar.gz → 0.19.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 (143) hide show
  1. {langroid-0.18.3 → langroid-0.19.0}/PKG-INFO +1 -1
  2. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/base.py +5 -0
  3. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/callbacks/chainlit.py +27 -0
  4. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/chat_agent.py +5 -5
  5. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/base.py +6 -0
  6. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/openai_gpt.py +98 -9
  7. {langroid-0.18.3 → langroid-0.19.0}/pyproject.toml +1 -1
  8. {langroid-0.18.3 → langroid-0.19.0}/LICENSE +0 -0
  9. {langroid-0.18.3 → langroid-0.19.0}/README.md +0 -0
  10. {langroid-0.18.3 → langroid-0.19.0}/langroid/__init__.py +0 -0
  11. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/__init__.py +0 -0
  12. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/batch.py +0 -0
  13. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/callbacks/__init__.py +0 -0
  14. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/chat_document.py +0 -0
  15. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/helpers.py +0 -0
  16. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/junk +0 -0
  17. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/openai_assistant.py +0 -0
  18. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/__init__.py +0 -0
  19. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/doc_chat_agent.py +0 -0
  20. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
  21. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_rag/__init__.py +0 -0
  22. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
  23. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
  24. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
  25. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/lance_tools.py +0 -0
  26. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/neo4j/__init__.py +0 -0
  27. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
  28. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
  29. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/neo4j/utils/__init__.py +0 -0
  30. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/neo4j/utils/system_message.py +0 -0
  31. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/relevance_extractor_agent.py +0 -0
  32. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/retriever_agent.py +0 -0
  33. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/__init__.py +0 -0
  34. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
  35. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/utils/__init__.py +0 -0
  36. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
  37. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
  38. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/utils/system_message.py +0 -0
  39. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/sql/utils/tools.py +0 -0
  40. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/special/table_chat_agent.py +0 -0
  41. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/structured_message.py +0 -0
  42. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/task.py +0 -0
  43. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tool_message.py +0 -0
  44. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/__init__.py +0 -0
  45. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
  46. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/file_tools.py +0 -0
  47. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/google_search_tool.py +0 -0
  48. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/metaphor_search_tool.py +0 -0
  49. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/orchestration.py +0 -0
  50. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/recipient_tool.py +0 -0
  51. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/retrieval_tool.py +0 -0
  52. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/rewind_tool.py +0 -0
  53. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/tools/segment_extract_tool.py +0 -0
  54. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/typed_task.py +0 -0
  55. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent/xml_tool_message.py +0 -0
  56. {langroid-0.18.3 → langroid-0.19.0}/langroid/agent_config.py +0 -0
  57. {langroid-0.18.3 → langroid-0.19.0}/langroid/cachedb/__init__.py +0 -0
  58. {langroid-0.18.3 → langroid-0.19.0}/langroid/cachedb/base.py +0 -0
  59. {langroid-0.18.3 → langroid-0.19.0}/langroid/cachedb/momento_cachedb.py +0 -0
  60. {langroid-0.18.3 → langroid-0.19.0}/langroid/cachedb/redis_cachedb.py +0 -0
  61. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/__init__.py +0 -0
  62. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/base.py +0 -0
  63. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/clustering.py +0 -0
  64. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/models.py +0 -0
  65. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/protoc/__init__.py +0 -0
  66. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/protoc/embeddings.proto +0 -0
  67. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
  68. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
  69. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
  70. {langroid-0.18.3 → langroid-0.19.0}/langroid/embedding_models/remote_embeds.py +0 -0
  71. {langroid-0.18.3 → langroid-0.19.0}/langroid/exceptions.py +0 -0
  72. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/.chainlit/config.toml +0 -0
  73. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/.chainlit/translations/en-US.json +0 -0
  74. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/__init__.py +0 -0
  75. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/azure_openai.py +0 -0
  76. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/config.py +0 -0
  77. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/mock_lm.py +0 -0
  78. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/prompt_formatter/__init__.py +0 -0
  79. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/prompt_formatter/base.py +0 -0
  80. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
  81. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
  82. {langroid-0.18.3 → langroid-0.19.0}/langroid/language_models/utils.py +0 -0
  83. {langroid-0.18.3 → langroid-0.19.0}/langroid/mytypes.py +0 -0
  84. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/__init__.py +0 -0
  85. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/agent_chats.py +0 -0
  86. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/code-parsing.md +0 -0
  87. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/code_parser.py +0 -0
  88. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/config.py +0 -0
  89. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/document_parser.py +0 -0
  90. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/image_text.py +0 -0
  91. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/para_sentence_split.py +0 -0
  92. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/parse_json.py +0 -0
  93. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/parser.py +0 -0
  94. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/repo_loader.py +0 -0
  95. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/routing.py +0 -0
  96. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/search.py +0 -0
  97. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/spider.py +0 -0
  98. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/table_loader.py +0 -0
  99. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/url_loader.py +0 -0
  100. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/url_loader_cookies.py +0 -0
  101. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/urls.py +0 -0
  102. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/utils.py +0 -0
  103. {langroid-0.18.3 → langroid-0.19.0}/langroid/parsing/web_search.py +0 -0
  104. {langroid-0.18.3 → langroid-0.19.0}/langroid/prompts/__init__.py +0 -0
  105. {langroid-0.18.3 → langroid-0.19.0}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
  106. {langroid-0.18.3 → langroid-0.19.0}/langroid/prompts/dialog.py +0 -0
  107. {langroid-0.18.3 → langroid-0.19.0}/langroid/prompts/prompts_config.py +0 -0
  108. {langroid-0.18.3 → langroid-0.19.0}/langroid/prompts/templates.py +0 -0
  109. {langroid-0.18.3 → langroid-0.19.0}/langroid/py.typed +0 -0
  110. {langroid-0.18.3 → langroid-0.19.0}/langroid/pydantic_v1/__init__.py +0 -0
  111. {langroid-0.18.3 → langroid-0.19.0}/langroid/pydantic_v1/main.py +0 -0
  112. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/.chainlit/config.toml +0 -0
  113. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/.chainlit/translations/en-US.json +0 -0
  114. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/__init__.py +0 -0
  115. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/algorithms/__init__.py +0 -0
  116. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/algorithms/graph.py +0 -0
  117. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/configuration.py +0 -0
  118. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/constants.py +0 -0
  119. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/docker.py +0 -0
  120. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/git_utils.py +0 -0
  121. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/globals.py +0 -0
  122. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/llms/__init__.py +0 -0
  123. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/llms/strings.py +0 -0
  124. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/logging.py +0 -0
  125. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/object_registry.py +0 -0
  126. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/output/__init__.py +0 -0
  127. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/output/citations.py +0 -0
  128. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/output/printing.py +0 -0
  129. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/output/status.py +0 -0
  130. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/pandas_utils.py +0 -0
  131. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/pydantic_utils.py +0 -0
  132. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/system.py +0 -0
  133. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/types.py +0 -0
  134. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/web/__init__.py +0 -0
  135. {langroid-0.18.3 → langroid-0.19.0}/langroid/utils/web/login.py +0 -0
  136. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/__init__.py +0 -0
  137. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/base.py +0 -0
  138. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/chromadb.py +0 -0
  139. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/lancedb.py +0 -0
  140. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/meilisearch.py +0 -0
  141. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/momento.py +0 -0
  142. {langroid-0.18.3 → langroid-0.19.0}/langroid/vector_store/qdrant_cloud.py +0 -0
  143. {langroid-0.18.3 → langroid-0.19.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.18.3
3
+ Version: 0.19.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -108,6 +108,10 @@ def noop_fn(*args: List[Any], **kwargs: Dict[str, Any]) -> None:
108
108
  pass
109
109
 
110
110
 
111
+ async def async_noop_fn(*args: List[Any], **kwargs: Dict[str, Any]) -> None:
112
+ pass
113
+
114
+
111
115
  class Agent(ABC):
112
116
  """
113
117
  An Agent is an abstraction that encapsulates mainly two components:
@@ -154,6 +158,7 @@ class Agent(ABC):
154
158
 
155
159
  self.callbacks = SimpleNamespace(
156
160
  start_llm_stream=lambda: noop_fn,
161
+ start_llm_stream_async=async_noop_fn,
157
162
  cancel_llm_stream=noop_fn,
158
163
  finish_llm_stream=noop_fn,
159
164
  show_llm_response=noop_fn,
@@ -234,6 +234,7 @@ class ChainlitAgentCallbacks:
234
234
  so we can alter the display of the first user message.
235
235
  """
236
236
  agent.callbacks.start_llm_stream = self.start_llm_stream
237
+ agent.callbacks.start_llm_stream_async = self.start_llm_stream_async
237
238
  agent.callbacks.cancel_llm_stream = self.cancel_llm_stream
238
239
  agent.callbacks.finish_llm_stream = self.finish_llm_stream
239
240
  agent.callbacks.show_llm_response = self.show_llm_response
@@ -304,6 +305,32 @@ class ChainlitAgentCallbacks:
304
305
 
305
306
  return stream_token
306
307
 
308
+ async def start_llm_stream_async(self) -> Callable[[str], None]:
309
+ """Returns a streaming fn that can be passed to the LLM class"""
310
+ self.stream = cl.Step(
311
+ id=self.curr_step.id if self.curr_step is not None else None,
312
+ name=self._entity_name("llm"),
313
+ type="llm",
314
+ parent_id=self._get_parent_id(),
315
+ )
316
+ self.last_step = self.stream
317
+ self.curr_step = None
318
+ logger.info(
319
+ f"""
320
+ Starting LLM stream for {self.agent.config.name}
321
+ id = {self.stream.id}
322
+ under parent {self._get_parent_id()}
323
+ """
324
+ )
325
+ await self.stream.send() # type: ignore
326
+
327
+ async def stream_token(t: str) -> None:
328
+ if self.stream is None:
329
+ raise ValueError("Stream not initialized")
330
+ await self.stream.stream_token(t)
331
+
332
+ return stream_token
333
+
307
334
  def cancel_llm_stream(self) -> None:
308
335
  """Called when cached response found."""
309
336
  self.last_step = None
@@ -9,7 +9,7 @@ from rich import print
9
9
  from rich.console import Console
10
10
  from rich.markup import escape
11
11
 
12
- from langroid.agent.base import Agent, AgentConfig, noop_fn
12
+ from langroid.agent.base import Agent, AgentConfig, async_noop_fn, noop_fn
13
13
  from langroid.agent.chat_document import ChatDocument
14
14
  from langroid.agent.tool_message import ToolMessage
15
15
  from langroid.agent.xml_tool_message import XMLToolMessage
@@ -969,10 +969,10 @@ class ChatAgent(Agent):
969
969
  functions, fun_call, tools, force_tool = self._function_args()
970
970
  assert self.llm is not None
971
971
 
972
- streamer = noop_fn
972
+ streamer_async = async_noop_fn
973
973
  if self.llm.get_stream():
974
- streamer = self.callbacks.start_llm_stream()
975
- self.llm.config.streamer = streamer
974
+ streamer_async = await self.callbacks.start_llm_stream_async()
975
+ self.llm.config.streamer_async = streamer_async
976
976
 
977
977
  response = await self.llm.achat(
978
978
  messages,
@@ -989,7 +989,7 @@ class ChatAgent(Agent):
989
989
  ChatDocument.from_LLMResponse(response, displayed=True),
990
990
  ),
991
991
  )
992
- self.llm.config.streamer = noop_fn
992
+ self.llm.config.streamer_async = async_noop_fn
993
993
  if response.cached:
994
994
  self.callbacks.cancel_llm_stream()
995
995
  self._render_llm_response(response)
@@ -6,6 +6,7 @@ from datetime import datetime
6
6
  from enum import Enum
7
7
  from typing import (
8
8
  Any,
9
+ Awaitable,
9
10
  Callable,
10
11
  Dict,
11
12
  List,
@@ -33,6 +34,10 @@ def noop_fn(*args: List[Any], **kwargs: Dict[str, Any]) -> None:
33
34
  pass
34
35
 
35
36
 
37
+ async def async_noop_fn(*args: List[Any], **kwargs: Dict[str, Any]) -> None:
38
+ pass
39
+
40
+
36
41
  FunctionCallTypes = Literal["none", "auto"]
37
42
  ToolChoiceTypes = Literal["none", "auto", "required"]
38
43
  ToolTypes = Literal["function"]
@@ -45,6 +50,7 @@ class LLMConfig(BaseSettings):
45
50
 
46
51
  type: str = "openai"
47
52
  streamer: Optional[Callable[[Any], None]] = noop_fn
53
+ streamer_async: Optional[Callable[..., Awaitable[None]]] = async_noop_fn
48
54
  api_base: str | None = None
49
55
  formatter: None | str = None
50
56
  timeout: int = 20 # timeout for API requests
@@ -688,7 +688,6 @@ class OpenAIGPT(LanguageModel):
688
688
  completion: str = "",
689
689
  function_args: str = "",
690
690
  function_name: str = "",
691
- is_async: bool = False,
692
691
  ) -> Tuple[bool, bool, str, str]:
693
692
  """Process state vars while processing a streaming API response.
694
693
  Returns a tuple consisting of:
@@ -708,7 +707,98 @@ class OpenAIGPT(LanguageModel):
708
707
  event_args = ""
709
708
  event_fn_name = ""
710
709
  event_tool_deltas: Optional[List[Dict[str, Any]]] = None
711
- silent = is_async and self.config.async_stream_quiet
710
+ # The first two events in the stream of Azure OpenAI is useless.
711
+ # In the 1st: choices list is empty, in the 2nd: the dict delta has null content
712
+ if chat:
713
+ delta = choices[0].get("delta", {})
714
+ event_text = delta.get("content", "")
715
+ if "function_call" in delta and delta["function_call"] is not None:
716
+ if "name" in delta["function_call"]:
717
+ event_fn_name = delta["function_call"]["name"]
718
+ if "arguments" in delta["function_call"]:
719
+ event_args = delta["function_call"]["arguments"]
720
+ if "tool_calls" in delta and delta["tool_calls"] is not None:
721
+ # it's a list of deltas, usually just one
722
+ event_tool_deltas = delta["tool_calls"]
723
+ tool_deltas += event_tool_deltas
724
+ else:
725
+ event_text = choices[0]["text"]
726
+ if event_text:
727
+ completion += event_text
728
+ sys.stdout.write(Colors().GREEN + event_text)
729
+ sys.stdout.flush()
730
+ self.config.streamer(event_text)
731
+ if event_fn_name:
732
+ function_name = event_fn_name
733
+ has_function = True
734
+ sys.stdout.write(Colors().GREEN + "FUNC: " + event_fn_name + ": ")
735
+ sys.stdout.flush()
736
+ self.config.streamer(event_fn_name)
737
+
738
+ if event_args:
739
+ function_args += event_args
740
+ sys.stdout.write(Colors().GREEN + event_args)
741
+ sys.stdout.flush()
742
+ self.config.streamer(event_args)
743
+
744
+ if event_tool_deltas is not None:
745
+ # print out streaming tool calls, if not async
746
+ for td in event_tool_deltas:
747
+ if td["function"]["name"] is not None:
748
+ tool_fn_name = td["function"]["name"]
749
+ sys.stdout.write(
750
+ Colors().GREEN + "OAI-TOOL: " + tool_fn_name + ": "
751
+ )
752
+ sys.stdout.flush()
753
+ self.config.streamer(tool_fn_name)
754
+ if td["function"]["arguments"] != "":
755
+ tool_fn_args = td["function"]["arguments"]
756
+ sys.stdout.write(Colors().GREEN + tool_fn_args)
757
+ sys.stdout.flush()
758
+ self.config.streamer(tool_fn_args)
759
+
760
+ # show this delta in the stream
761
+ if choices[0].get("finish_reason", "") in [
762
+ "stop",
763
+ "function_call",
764
+ "tool_calls",
765
+ ]:
766
+ # for function_call, finish_reason does not necessarily
767
+ # contain "function_call" as mentioned in the docs.
768
+ # So we check for "stop" or "function_call" here.
769
+ return True, has_function, function_name, function_args, completion
770
+ return False, has_function, function_name, function_args, completion
771
+
772
+ @no_type_check
773
+ async def _process_stream_event_async(
774
+ self,
775
+ event,
776
+ chat: bool = False,
777
+ tool_deltas: List[Dict[str, Any]] = [],
778
+ has_function: bool = False,
779
+ completion: str = "",
780
+ function_args: str = "",
781
+ function_name: str = "",
782
+ ) -> Tuple[bool, bool, str, str]:
783
+ """Process state vars while processing a streaming API response.
784
+ Returns a tuple consisting of:
785
+ - is_break: whether to break out of the loop
786
+ - has_function: whether the response contains a function_call
787
+ - function_name: name of the function
788
+ - function_args: args of the function
789
+ """
790
+ # convert event obj (of type ChatCompletionChunk) to dict so rest of code,
791
+ # which expects dicts, works as it did before switching to openai v1.x
792
+ if not isinstance(event, dict):
793
+ event = event.model_dump()
794
+
795
+ choices = event.get("choices", [{}])
796
+ if len(choices) == 0:
797
+ choices = [{}]
798
+ event_args = ""
799
+ event_fn_name = ""
800
+ event_tool_deltas: Optional[List[Dict[str, Any]]] = None
801
+ silent = self.config.async_stream_quiet
712
802
  # The first two events in the stream of Azure OpenAI is useless.
713
803
  # In the 1st: choices list is empty, in the 2nd: the dict delta has null content
714
804
  if chat:
@@ -730,21 +820,21 @@ class OpenAIGPT(LanguageModel):
730
820
  if not silent:
731
821
  sys.stdout.write(Colors().GREEN + event_text)
732
822
  sys.stdout.flush()
733
- self.config.streamer(event_text)
823
+ await self.config.streamer_async(event_text)
734
824
  if event_fn_name:
735
825
  function_name = event_fn_name
736
826
  has_function = True
737
827
  if not silent:
738
828
  sys.stdout.write(Colors().GREEN + "FUNC: " + event_fn_name + ": ")
739
829
  sys.stdout.flush()
740
- self.config.streamer(event_fn_name)
830
+ await self.config.streamer_async(event_fn_name)
741
831
 
742
832
  if event_args:
743
833
  function_args += event_args
744
834
  if not silent:
745
835
  sys.stdout.write(Colors().GREEN + event_args)
746
836
  sys.stdout.flush()
747
- self.config.streamer(event_args)
837
+ await self.config.streamer_async(event_args)
748
838
 
749
839
  if event_tool_deltas is not None and not silent:
750
840
  # print out streaming tool calls, if not async
@@ -755,12 +845,12 @@ class OpenAIGPT(LanguageModel):
755
845
  Colors().GREEN + "OAI-TOOL: " + tool_fn_name + ": "
756
846
  )
757
847
  sys.stdout.flush()
758
- self.config.streamer(tool_fn_name)
848
+ await self.config.streamer_async(tool_fn_name)
759
849
  if td["function"]["arguments"] != "":
760
850
  tool_fn_args = td["function"]["arguments"]
761
851
  sys.stdout.write(Colors().GREEN + tool_fn_args)
762
852
  sys.stdout.flush()
763
- self.config.streamer(tool_fn_args)
853
+ await self.config.streamer_async(tool_fn_args)
764
854
 
765
855
  # show this delta in the stream
766
856
  if choices[0].get("finish_reason", "") in [
@@ -862,7 +952,7 @@ class OpenAIGPT(LanguageModel):
862
952
  function_name,
863
953
  function_args,
864
954
  completion,
865
- ) = self._process_stream_event(
955
+ ) = await self._process_stream_event_async(
866
956
  event,
867
957
  chat=chat,
868
958
  tool_deltas=tool_deltas,
@@ -870,7 +960,6 @@ class OpenAIGPT(LanguageModel):
870
960
  completion=completion,
871
961
  function_args=function_args,
872
962
  function_name=function_name,
873
- is_async=True,
874
963
  )
875
964
  if is_break:
876
965
  break
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langroid"
3
- version = "0.18.3"
3
+ version = "0.19.0"
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
File without changes