langroid 0.28.7__tar.gz → 0.29.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 (150) hide show
  1. {langroid-0.28.7 → langroid-0.29.0}/PKG-INFO +1 -1
  2. langroid-0.29.0/langroid/agent/team.py +186 -0
  3. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/azure_openai.py +60 -28
  4. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/openai_gpt.py +26 -19
  5. {langroid-0.28.7 → langroid-0.29.0}/pyproject.toml +1 -1
  6. langroid-0.28.7/langroid/agent/team.py +0 -41
  7. {langroid-0.28.7 → langroid-0.29.0}/LICENSE +0 -0
  8. {langroid-0.28.7 → langroid-0.29.0}/README.md +0 -0
  9. {langroid-0.28.7 → langroid-0.29.0}/langroid/__init__.py +0 -0
  10. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/__init__.py +0 -0
  11. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/base.py +0 -0
  12. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/batch.py +0 -0
  13. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/callbacks/__init__.py +0 -0
  14. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/callbacks/chainlit.py +0 -0
  15. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/chat_agent.py +0 -0
  16. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/chat_document.py +0 -0
  17. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/helpers.py +0 -0
  18. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/junk +0 -0
  19. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/openai_assistant.py +0 -0
  20. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/__init__.py +0 -0
  21. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/arangodb/__init__.py +0 -0
  22. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/arangodb/arangodb_agent.py +0 -0
  23. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/arangodb/system_messages.py +0 -0
  24. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/arangodb/tools.py +0 -0
  25. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/arangodb/utils.py +0 -0
  26. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/doc_chat_agent.py +0 -0
  27. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_doc_chat_agent.py +0 -0
  28. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_rag/__init__.py +0 -0
  29. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_rag/critic_agent.py +0 -0
  30. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_rag/lance_rag_task.py +0 -0
  31. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_rag/query_planner_agent.py +0 -0
  32. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/lance_tools.py +0 -0
  33. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/neo4j/__init__.py +0 -0
  34. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/neo4j/csv_kg_chat.py +0 -0
  35. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/neo4j/neo4j_chat_agent.py +0 -0
  36. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/neo4j/system_messages.py +0 -0
  37. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/neo4j/tools.py +0 -0
  38. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/relevance_extractor_agent.py +0 -0
  39. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/retriever_agent.py +0 -0
  40. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/__init__.py +0 -0
  41. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/sql_chat_agent.py +0 -0
  42. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/utils/__init__.py +0 -0
  43. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/utils/description_extractors.py +0 -0
  44. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/utils/populate_metadata.py +0 -0
  45. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/utils/system_message.py +0 -0
  46. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/sql/utils/tools.py +0 -0
  47. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/special/table_chat_agent.py +0 -0
  48. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/structured_message.py +0 -0
  49. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/task.py +0 -0
  50. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tool_message.py +0 -0
  51. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/__init__.py +0 -0
  52. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/duckduckgo_search_tool.py +0 -0
  53. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/file_tools.py +0 -0
  54. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/google_search_tool.py +0 -0
  55. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/metaphor_search_tool.py +0 -0
  56. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/orchestration.py +0 -0
  57. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/recipient_tool.py +0 -0
  58. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/retrieval_tool.py +0 -0
  59. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/rewind_tool.py +0 -0
  60. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/tools/segment_extract_tool.py +0 -0
  61. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/typed_task.py +0 -0
  62. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent/xml_tool_message.py +0 -0
  63. {langroid-0.28.7 → langroid-0.29.0}/langroid/agent_config.py +0 -0
  64. {langroid-0.28.7 → langroid-0.29.0}/langroid/cachedb/__init__.py +0 -0
  65. {langroid-0.28.7 → langroid-0.29.0}/langroid/cachedb/base.py +0 -0
  66. {langroid-0.28.7 → langroid-0.29.0}/langroid/cachedb/momento_cachedb.py +0 -0
  67. {langroid-0.28.7 → langroid-0.29.0}/langroid/cachedb/redis_cachedb.py +0 -0
  68. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/__init__.py +0 -0
  69. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/base.py +0 -0
  70. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/clustering.py +0 -0
  71. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/models.py +0 -0
  72. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/protoc/__init__.py +0 -0
  73. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/protoc/embeddings.proto +0 -0
  74. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/protoc/embeddings_pb2.py +0 -0
  75. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/protoc/embeddings_pb2.pyi +0 -0
  76. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/protoc/embeddings_pb2_grpc.py +0 -0
  77. {langroid-0.28.7 → langroid-0.29.0}/langroid/embedding_models/remote_embeds.py +0 -0
  78. {langroid-0.28.7 → langroid-0.29.0}/langroid/exceptions.py +0 -0
  79. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/.chainlit/config.toml +0 -0
  80. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/.chainlit/translations/en-US.json +0 -0
  81. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/__init__.py +0 -0
  82. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/base.py +0 -0
  83. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/config.py +0 -0
  84. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/mock_lm.py +0 -0
  85. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/prompt_formatter/__init__.py +0 -0
  86. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/prompt_formatter/base.py +0 -0
  87. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/prompt_formatter/hf_formatter.py +0 -0
  88. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/prompt_formatter/llama2_formatter.py +0 -0
  89. {langroid-0.28.7 → langroid-0.29.0}/langroid/language_models/utils.py +0 -0
  90. {langroid-0.28.7 → langroid-0.29.0}/langroid/mytypes.py +0 -0
  91. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/__init__.py +0 -0
  92. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/agent_chats.py +0 -0
  93. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/code-parsing.md +0 -0
  94. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/code_parser.py +0 -0
  95. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/config.py +0 -0
  96. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/document_parser.py +0 -0
  97. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/image_text.py +0 -0
  98. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/para_sentence_split.py +0 -0
  99. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/parse_json.py +0 -0
  100. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/parser.py +0 -0
  101. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/repo_loader.py +0 -0
  102. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/routing.py +0 -0
  103. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/search.py +0 -0
  104. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/spider.py +0 -0
  105. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/table_loader.py +0 -0
  106. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/url_loader.py +0 -0
  107. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/url_loader_cookies.py +0 -0
  108. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/urls.py +0 -0
  109. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/utils.py +0 -0
  110. {langroid-0.28.7 → langroid-0.29.0}/langroid/parsing/web_search.py +0 -0
  111. {langroid-0.28.7 → langroid-0.29.0}/langroid/prompts/__init__.py +0 -0
  112. {langroid-0.28.7 → langroid-0.29.0}/langroid/prompts/chat-gpt4-system-prompt.md +0 -0
  113. {langroid-0.28.7 → langroid-0.29.0}/langroid/prompts/dialog.py +0 -0
  114. {langroid-0.28.7 → langroid-0.29.0}/langroid/prompts/prompts_config.py +0 -0
  115. {langroid-0.28.7 → langroid-0.29.0}/langroid/prompts/templates.py +0 -0
  116. {langroid-0.28.7 → langroid-0.29.0}/langroid/py.typed +0 -0
  117. {langroid-0.28.7 → langroid-0.29.0}/langroid/pydantic_v1/__init__.py +0 -0
  118. {langroid-0.28.7 → langroid-0.29.0}/langroid/pydantic_v1/main.py +0 -0
  119. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/.chainlit/config.toml +0 -0
  120. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/.chainlit/translations/en-US.json +0 -0
  121. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/__init__.py +0 -0
  122. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/algorithms/__init__.py +0 -0
  123. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/algorithms/graph.py +0 -0
  124. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/configuration.py +0 -0
  125. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/constants.py +0 -0
  126. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/docker.py +0 -0
  127. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/git_utils.py +0 -0
  128. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/globals.py +0 -0
  129. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/llms/__init__.py +0 -0
  130. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/llms/strings.py +0 -0
  131. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/logging.py +0 -0
  132. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/object_registry.py +0 -0
  133. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/output/__init__.py +0 -0
  134. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/output/citations.py +0 -0
  135. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/output/printing.py +0 -0
  136. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/output/status.py +0 -0
  137. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/pandas_utils.py +0 -0
  138. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/pydantic_utils.py +0 -0
  139. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/system.py +0 -0
  140. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/types.py +0 -0
  141. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/web/__init__.py +0 -0
  142. {langroid-0.28.7 → langroid-0.29.0}/langroid/utils/web/login.py +0 -0
  143. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/__init__.py +0 -0
  144. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/base.py +0 -0
  145. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/chromadb.py +0 -0
  146. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/lancedb.py +0 -0
  147. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/meilisearch.py +0 -0
  148. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/momento.py +0 -0
  149. {langroid-0.28.7 → langroid-0.29.0}/langroid/vector_store/qdrant_cloud.py +0 -0
  150. {langroid-0.28.7 → langroid-0.29.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.28.7
3
+ Version: 0.29.0
4
4
  Summary: Harness LLMs with Multi-Agent Programming
5
5
  License: MIT
6
6
  Author: Prasad Chalasani
@@ -0,0 +1,186 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, List
3
+
4
+ import langroid as lr
5
+ from langroid import ChatDocument
6
+
7
+
8
+ class InputContext:
9
+ def __init__(self):
10
+ self.messages: List[lr.ChatDocument] = []
11
+
12
+ def add(self, results: List[lr.ChatDocument]):
13
+ self.messages.extend(results)
14
+
15
+ def clear(self):
16
+ self.messages.clear()
17
+
18
+
19
+ class Scheduler(ABC):
20
+ @abstractmethod
21
+ def step(self) -> None:
22
+ pass
23
+
24
+ @abstractmethod
25
+ def done(self) -> bool:
26
+ pass
27
+
28
+ @abstractmethod
29
+ def result(self) -> lr.ChatDocument:
30
+ pass
31
+
32
+ def run(self):
33
+ while not self.done():
34
+ self.step()
35
+ return self.result()
36
+
37
+
38
+ class Component(ABC):
39
+ def __init__(self):
40
+ self.input = InputContext()
41
+
42
+ @abstractmethod
43
+ def run(self, inputs: List[Any]) -> Any:
44
+ pass
45
+
46
+ def listen(self, component: Component | List[Component]):
47
+ if isinstance(component, list):
48
+ for comp in component:
49
+ comp.listeners.append(self)
50
+ else:
51
+ component.listeners.append(self)
52
+
53
+ @property
54
+ def listeners(self) -> List["Component"]:
55
+ if not hasattr(self, "_listeners"):
56
+ self._listeners = []
57
+ return self._listeners
58
+
59
+
60
+ class SimpleScheduler(Scheduler):
61
+ def __init__(
62
+ self, components: List[Component], inputs: List[lr.ChatDocument] = None
63
+ ):
64
+ self.components: List[Component] = components
65
+ self.inputs: List[lr.ChatDocument] = inputs or []
66
+ self.current_results: List[lr.ChatDocument] = []
67
+ self.stepped: bool = False
68
+
69
+ def step(self):
70
+ self.current_results = [comp.run(self.inputs) for comp in self.components]
71
+ self.stepped = True
72
+
73
+ def done(self):
74
+ return self.stepped # Now returns True only after stepping
75
+
76
+ def result(self):
77
+ return self.current_results
78
+
79
+
80
+ class OrElseScheduler(Scheduler):
81
+ def __init__(self, components, inputs=None):
82
+ self.components = components
83
+ self.inputs = inputs or []
84
+ self.current_result = None
85
+ self.done_flag = False
86
+
87
+ def is_valid(self, result) -> bool:
88
+ return result is not None and result != ""
89
+
90
+ def step(self):
91
+ for comp in self.components:
92
+ result = comp.run(comp.input.messages)
93
+ if self.is_valid(result):
94
+ self.current_result = result
95
+ self.done_flag = True
96
+ return
97
+ self.done_flag = True
98
+
99
+ def done(self):
100
+ return self.done_flag
101
+
102
+ def result(self):
103
+ return self.current_result
104
+
105
+
106
+ class Team(Component):
107
+ def __init__(self, name: str, scheduler_class=SimpleScheduler):
108
+ super().__init__()
109
+ self.name = name
110
+ self.components = []
111
+ self.scheduler_class = scheduler_class
112
+
113
+ def add(self, component: Union[Component, List[Component]]):
114
+ if isinstance(component, list):
115
+ self.components.extend(component)
116
+ else:
117
+ self.components.append(component)
118
+
119
+ def listen(self, team: "Team"):
120
+ # TODO Can a team listen to a component outside of itself?
121
+ team.listeners.append(self)
122
+
123
+ def run(self, inputs=None) -> Any:
124
+ all_inputs = inputs or self.input.messages
125
+ scheduler = self.scheduler_class(self.components, inputs=all_inputs)
126
+ result = scheduler.run()
127
+ self._notify(result)
128
+ self.input.clear()
129
+ return result
130
+
131
+ def _notify(self, results: List[Any]):
132
+ for listener in self.listeners:
133
+ listener.input.add(results)
134
+
135
+
136
+ # Example of existing agent class
137
+ class DummyAgent:
138
+ def __init__(self, name):
139
+ self.name = name
140
+
141
+ def process(self, data):
142
+ return f"{self.name} processed: {data}"
143
+
144
+
145
+ # Adapter for existing agent
146
+ class AgentAdapter(Component):
147
+ def __init__(self, agent: DummyAgent):
148
+ super().__init__()
149
+ self.agent = agent
150
+
151
+ def run(self, inputs: List[Any]) -> str:
152
+ input_str = ", ".join(str(x) for x in inputs) if inputs else "no input"
153
+ return self.agent.process(input_str)
154
+
155
+
156
+ if __name__ == "__main__":
157
+ # Create agents
158
+ agent1 = AgentAdapter(DummyAgent("Agent1"))
159
+ agent2 = AgentAdapter(DummyAgent("Agent2"))
160
+ agent3 = AgentAdapter(DummyAgent("Agent3"))
161
+
162
+ # Create teams
163
+ team1 = Team("Team1")
164
+ team2 = Team("Team2")
165
+
166
+ # Build hierarchy
167
+ team1.add([agent1, agent2])
168
+ team2.add(agent3)
169
+
170
+ # Set up listening
171
+ team2.listen(team1)
172
+ agent1.listen(agent2)
173
+ agent2.listen(agent1)
174
+
175
+ #TODO - who will orchestrate team1 + team2 ?
176
+ # Run scenarios
177
+ print("Running team1...")
178
+ result1 = team1.run(["Start discussion"])
179
+ print(f"Team1 result: {result1}")
180
+ print(f"Agent1's inputs: {agent1.input.messages}")
181
+ print(f"Agent2's inputs: {agent2.input.messages}")
182
+
183
+ print("\nRunning team2...")
184
+ result2 = team2.run()
185
+ print(f"Agent3's inputs from agent1: {agent3.input.messages}")
186
+ print(f"Team2 result: {result2}")
@@ -1,3 +1,6 @@
1
+ import logging
2
+ from typing import Callable
3
+
1
4
  from dotenv import load_dotenv
2
5
  from httpx import Timeout
3
6
  from openai import AsyncAzureOpenAI, AzureOpenAI
@@ -15,6 +18,8 @@ azureStructuredOutputList = [
15
18
 
16
19
  azureStructuredOutputAPIMin = "2024-08-01-preview"
17
20
 
21
+ logger = logging.getLogger(__name__)
22
+
18
23
 
19
24
  class AzureConfig(OpenAIGPTConfig):
20
25
  """
@@ -42,6 +47,10 @@ class AzureConfig(OpenAIGPTConfig):
42
47
  model_version: str = "" # is used to determine the cost of using the model
43
48
  api_base: str = ""
44
49
 
50
+ # Alternatively, bring your own clients:
51
+ azure_openai_client_provider: Callable[[], AzureOpenAI] | None = None
52
+ azure_openai_async_client_provider: Callable[[], AsyncAzureOpenAI] | None = None
53
+
45
54
  # all of the vars above can be set via env vars,
46
55
  # by upper-casing the name and prefixing with `env_prefix`, e.g.
47
56
  # AZURE_OPENAI_API_VERSION=2023-05-15
@@ -69,20 +78,6 @@ class AzureGPT(OpenAIGPT):
69
78
  load_dotenv()
70
79
  super().__init__(config)
71
80
  self.config: AzureConfig = config
72
- if self.config.api_key == "":
73
- raise ValueError(
74
- """
75
- AZURE_OPENAI_API_KEY not set in .env file,
76
- please set it to your Azure API key."""
77
- )
78
-
79
- if self.config.api_base == "":
80
- raise ValueError(
81
- """
82
- AZURE_OPENAI_API_BASE not set in .env file,
83
- please set it to your Azure API key."""
84
- )
85
-
86
81
  if self.config.deployment_name == "":
87
82
  raise ValueError(
88
83
  """
@@ -98,6 +93,57 @@ class AzureGPT(OpenAIGPT):
98
93
  please set it to chat model name in your deployment."""
99
94
  )
100
95
 
96
+ if (
97
+ self.config.azure_openai_client_provider
98
+ or self.config.azure_openai_async_client_provider
99
+ ):
100
+ if not self.config.azure_openai_client_provider:
101
+ self.client = None
102
+ logger.warning(
103
+ "Using user-provided Azure OpenAI client, but only async "
104
+ "client has been provided. Synchronous calls will fail."
105
+ )
106
+ if not self.config.azure_openai_async_client_provider:
107
+ self.async_client = None
108
+ logger.warning(
109
+ "Using user-provided Azure OpenAI client, but no async "
110
+ "client has been provided. Asynchronous calls will fail."
111
+ )
112
+
113
+ if self.config.azure_openai_client_provider:
114
+ self.client = self.config.azure_openai_client_provider()
115
+ if self.config.azure_openai_async_client_provider:
116
+ self.async_client = self.config.azure_openai_async_client_provider()
117
+ self.async_client.timeout = Timeout(self.config.timeout)
118
+ else:
119
+ if self.config.api_key == "":
120
+ raise ValueError(
121
+ """
122
+ AZURE_OPENAI_API_KEY not set in .env file,
123
+ please set it to your Azure API key."""
124
+ )
125
+
126
+ if self.config.api_base == "":
127
+ raise ValueError(
128
+ """
129
+ AZURE_OPENAI_API_BASE not set in .env file,
130
+ please set it to your Azure API key."""
131
+ )
132
+
133
+ self.client = AzureOpenAI(
134
+ api_key=self.config.api_key,
135
+ azure_endpoint=self.config.api_base,
136
+ api_version=self.config.api_version,
137
+ azure_deployment=self.config.deployment_name,
138
+ )
139
+ self.async_client = AsyncAzureOpenAI(
140
+ api_key=self.config.api_key,
141
+ azure_endpoint=self.config.api_base,
142
+ api_version=self.config.api_version,
143
+ azure_deployment=self.config.deployment_name,
144
+ timeout=Timeout(self.config.timeout),
145
+ )
146
+
101
147
  # set the chat model to be the same as the model_name
102
148
  # This corresponds to the gpt model you chose for your deployment
103
149
  # when you deployed a model
@@ -108,20 +154,6 @@ class AzureGPT(OpenAIGPT):
108
154
  and self.config.model_version in azureStructuredOutputList
109
155
  )
110
156
 
111
- self.client = AzureOpenAI(
112
- api_key=self.config.api_key,
113
- azure_endpoint=self.config.api_base,
114
- api_version=self.config.api_version,
115
- azure_deployment=self.config.deployment_name,
116
- )
117
- self.async_client = AsyncAzureOpenAI(
118
- api_key=self.config.api_key,
119
- azure_endpoint=self.config.api_base,
120
- api_version=self.config.api_version,
121
- azure_deployment=self.config.deployment_name,
122
- timeout=Timeout(self.config.timeout),
123
- )
124
-
125
157
  def set_chat_model(self) -> None:
126
158
  """
127
159
  Sets the chat model configuration based on the model name specified in the
@@ -432,8 +432,8 @@ class OpenAIGPT(LanguageModel):
432
432
  Class for OpenAI LLMs
433
433
  """
434
434
 
435
- client: OpenAI | Groq | Cerebras
436
- async_client: AsyncOpenAI | AsyncGroq | AsyncCerebras
435
+ client: OpenAI | Groq | Cerebras | None
436
+ async_client: AsyncOpenAI | AsyncGroq | AsyncCerebras | None
437
437
 
438
438
  def __init__(self, config: OpenAIGPTConfig = OpenAIGPTConfig()):
439
439
  """
@@ -1375,12 +1375,15 @@ class OpenAIGPT(LanguageModel):
1375
1375
  else:
1376
1376
  if self.config.litellm:
1377
1377
  from litellm import completion as litellm_completion
1378
- assert isinstance(self.client, OpenAI)
1379
- completion_call = (
1380
- litellm_completion
1381
- if self.config.litellm
1382
- else self.client.completions.create
1383
- )
1378
+
1379
+ completion_call = litellm_completion
1380
+ else:
1381
+ if self.client is None:
1382
+ raise ValueError(
1383
+ "OpenAI/equivalent chat-completion client not set"
1384
+ )
1385
+ assert isinstance(self.client, OpenAI)
1386
+ completion_call = self.client.completions.create
1384
1387
  if self.config.litellm and settings.debug:
1385
1388
  kwargs["logger_fn"] = litellm_logging_fn
1386
1389
  # If it's not in the cache, call the API
@@ -1619,14 +1622,15 @@ class OpenAIGPT(LanguageModel):
1619
1622
  if settings.debug:
1620
1623
  print("[grey37]CACHED[/grey37]")
1621
1624
  else:
1625
+ # If it's not in the cache, call the API
1622
1626
  if self.config.litellm:
1623
1627
  from litellm import completion as litellm_completion
1624
- # If it's not in the cache, call the API
1625
- completion_call = (
1626
- litellm_completion
1627
- if self.config.litellm
1628
- else self.client.chat.completions.create
1629
- )
1628
+
1629
+ completion_call = litellm_completion
1630
+ else:
1631
+ if self.client is None:
1632
+ raise ValueError("OpenAI/equivalent chat-completion client not set")
1633
+ completion_call = self.client.chat.completions.create
1630
1634
  if self.config.litellm and settings.debug:
1631
1635
  kwargs["logger_fn"] = litellm_logging_fn
1632
1636
  result = completion_call(**kwargs)
@@ -1649,11 +1653,14 @@ class OpenAIGPT(LanguageModel):
1649
1653
  else:
1650
1654
  if self.config.litellm:
1651
1655
  from litellm import acompletion as litellm_acompletion
1652
- acompletion_call = (
1653
- litellm_acompletion
1654
- if self.config.litellm
1655
- else self.async_client.chat.completions.create
1656
- )
1656
+
1657
+ acompletion_call = litellm_acompletion
1658
+ else:
1659
+ if self.async_client is None:
1660
+ raise ValueError(
1661
+ "OpenAI/equivalent async chat-completion client not set"
1662
+ )
1663
+ acompletion_call = self.async_client.chat.completions.create
1657
1664
  if self.config.litellm and settings.debug:
1658
1665
  kwargs["logger_fn"] = litellm_logging_fn
1659
1666
  # If it's not in the cache, call the API
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langroid"
3
- version = "0.28.7"
3
+ version = "0.29.0"
4
4
  description = "Harness LLMs with Multi-Agent Programming"
5
5
  authors = ["Prasad Chalasani <pchalasani@gmail.com>"]
6
6
  readme = "README.md"
@@ -1,41 +0,0 @@
1
- from abc import ABC, abstractmethod
2
-
3
- class TeamComponent(ABC):
4
- @abstractmethod
5
- def run(self, msg):
6
- pass
7
-
8
- class Team(TeamComponent):
9
- def __init__(self):
10
- self.components = []
11
- self.input_port = []
12
- self.followers = []
13
- self.scheduler = None
14
-
15
- def follow(self, team):
16
- team.followers.append(self)
17
-
18
- def add_component(self, component):
19
- self.components.append(component)
20
-
21
- def notify_followers(self, result):
22
- for follower in self.followers:
23
- follower.input_port.append(result)
24
-
25
- def run(self, msg):
26
- if self.scheduler:
27
- return self.scheduler.run(self.components, msg)
28
- # Default sequential execution
29
- result = ""
30
- for component in self.components:
31
- result += component.run(msg)
32
- self.notify_followers(result)
33
- return result
34
-
35
- class Agent(TeamComponent):
36
- def __init__(self, name):
37
- self.name = name
38
-
39
- def run(self, msg):
40
- result = f"Agent {self.name} processed: {msg}"
41
- return result
File without changes
File without changes
File without changes
File without changes
File without changes