langroid 0.29.0__py3-none-any.whl → 0.30.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.
langroid/agent/team.py DELETED
@@ -1,186 +0,0 @@
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}")