pygeai-orchestration 0.1.0b2__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.
- pygeai_orchestration/__init__.py +99 -0
- pygeai_orchestration/cli/__init__.py +7 -0
- pygeai_orchestration/cli/__main__.py +11 -0
- pygeai_orchestration/cli/commands/__init__.py +13 -0
- pygeai_orchestration/cli/commands/base.py +192 -0
- pygeai_orchestration/cli/error_handler.py +123 -0
- pygeai_orchestration/cli/formatters.py +419 -0
- pygeai_orchestration/cli/geai_orch.py +270 -0
- pygeai_orchestration/cli/interactive.py +265 -0
- pygeai_orchestration/cli/texts/help.py +169 -0
- pygeai_orchestration/core/__init__.py +130 -0
- pygeai_orchestration/core/base/__init__.py +23 -0
- pygeai_orchestration/core/base/agent.py +121 -0
- pygeai_orchestration/core/base/geai_agent.py +144 -0
- pygeai_orchestration/core/base/geai_orchestrator.py +77 -0
- pygeai_orchestration/core/base/orchestrator.py +142 -0
- pygeai_orchestration/core/base/pattern.py +161 -0
- pygeai_orchestration/core/base/tool.py +149 -0
- pygeai_orchestration/core/common/__init__.py +18 -0
- pygeai_orchestration/core/common/context.py +140 -0
- pygeai_orchestration/core/common/memory.py +176 -0
- pygeai_orchestration/core/common/message.py +50 -0
- pygeai_orchestration/core/common/state.py +181 -0
- pygeai_orchestration/core/composition.py +190 -0
- pygeai_orchestration/core/config.py +356 -0
- pygeai_orchestration/core/exceptions.py +400 -0
- pygeai_orchestration/core/handlers.py +380 -0
- pygeai_orchestration/core/utils/__init__.py +37 -0
- pygeai_orchestration/core/utils/cache.py +138 -0
- pygeai_orchestration/core/utils/config.py +94 -0
- pygeai_orchestration/core/utils/logging.py +57 -0
- pygeai_orchestration/core/utils/metrics.py +184 -0
- pygeai_orchestration/core/utils/validators.py +140 -0
- pygeai_orchestration/dev/__init__.py +15 -0
- pygeai_orchestration/dev/debug.py +288 -0
- pygeai_orchestration/dev/templates.py +321 -0
- pygeai_orchestration/dev/testing.py +301 -0
- pygeai_orchestration/patterns/__init__.py +15 -0
- pygeai_orchestration/patterns/multi_agent.py +237 -0
- pygeai_orchestration/patterns/planning.py +219 -0
- pygeai_orchestration/patterns/react.py +221 -0
- pygeai_orchestration/patterns/reflection.py +134 -0
- pygeai_orchestration/patterns/tool_use.py +170 -0
- pygeai_orchestration/tests/__init__.py +1 -0
- pygeai_orchestration/tests/test_base_classes.py +187 -0
- pygeai_orchestration/tests/test_cache.py +184 -0
- pygeai_orchestration/tests/test_cli_formatters.py +232 -0
- pygeai_orchestration/tests/test_common.py +214 -0
- pygeai_orchestration/tests/test_composition.py +265 -0
- pygeai_orchestration/tests/test_config.py +301 -0
- pygeai_orchestration/tests/test_dev_utils.py +337 -0
- pygeai_orchestration/tests/test_exceptions.py +327 -0
- pygeai_orchestration/tests/test_handlers.py +307 -0
- pygeai_orchestration/tests/test_metrics.py +171 -0
- pygeai_orchestration/tests/test_patterns.py +165 -0
- pygeai_orchestration-0.1.0b2.dist-info/METADATA +290 -0
- pygeai_orchestration-0.1.0b2.dist-info/RECORD +61 -0
- pygeai_orchestration-0.1.0b2.dist-info/WHEEL +5 -0
- pygeai_orchestration-0.1.0b2.dist-info/entry_points.txt +2 -0
- pygeai_orchestration-0.1.0b2.dist-info/licenses/LICENSE +8 -0
- pygeai_orchestration-0.1.0b2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""Interactive CLI utilities."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable, Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from pygeai_orchestration.cli.formatters import Color, OutputFormatter, Symbol
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InteractivePrompt:
|
|
9
|
+
"""Interactive prompt utilities."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, formatter: Optional[OutputFormatter] = None):
|
|
12
|
+
"""Initialize interactive prompt.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
formatter: Output formatter
|
|
16
|
+
"""
|
|
17
|
+
self.formatter = formatter or OutputFormatter()
|
|
18
|
+
|
|
19
|
+
def confirm(self, message: str, default: bool = True) -> bool:
|
|
20
|
+
"""Ask yes/no confirmation.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
message: Confirmation message
|
|
24
|
+
default: Default value
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
User confirmation
|
|
28
|
+
"""
|
|
29
|
+
default_str = "Y/n" if default else "y/N"
|
|
30
|
+
prompt = f"{message} [{default_str}]: "
|
|
31
|
+
|
|
32
|
+
while True:
|
|
33
|
+
response = input(prompt).strip().lower()
|
|
34
|
+
|
|
35
|
+
if not response:
|
|
36
|
+
return default
|
|
37
|
+
|
|
38
|
+
if response in ("y", "yes"):
|
|
39
|
+
return True
|
|
40
|
+
elif response in ("n", "no"):
|
|
41
|
+
return False
|
|
42
|
+
else:
|
|
43
|
+
print(self.formatter.error("Please answer yes or no"))
|
|
44
|
+
|
|
45
|
+
def select(
|
|
46
|
+
self,
|
|
47
|
+
message: str,
|
|
48
|
+
choices: List[str],
|
|
49
|
+
default: Optional[int] = None
|
|
50
|
+
) -> int:
|
|
51
|
+
"""Select from list of choices.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
message: Selection message
|
|
55
|
+
choices: List of choices
|
|
56
|
+
default: Default choice index
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Selected index
|
|
60
|
+
"""
|
|
61
|
+
print(f"\n{self.formatter.heading(message, level=2)}\n")
|
|
62
|
+
|
|
63
|
+
for i, choice in enumerate(choices, 1):
|
|
64
|
+
bullet = self.formatter.colorize(Symbol.ARROW.value, Color.BLUE)
|
|
65
|
+
default_mark = " (default)" if default == i - 1 else ""
|
|
66
|
+
print(f"{bullet} {i}. {choice}{default_mark}")
|
|
67
|
+
|
|
68
|
+
while True:
|
|
69
|
+
prompt = "\nEnter choice"
|
|
70
|
+
if default is not None:
|
|
71
|
+
prompt += f" [default: {default + 1}]"
|
|
72
|
+
prompt += ": "
|
|
73
|
+
|
|
74
|
+
response = input(prompt).strip()
|
|
75
|
+
|
|
76
|
+
if not response and default is not None:
|
|
77
|
+
return default
|
|
78
|
+
|
|
79
|
+
try:
|
|
80
|
+
index = int(response) - 1
|
|
81
|
+
if 0 <= index < len(choices):
|
|
82
|
+
return index
|
|
83
|
+
else:
|
|
84
|
+
print(self.formatter.error(f"Please enter a number between 1 and {len(choices)}"))
|
|
85
|
+
except ValueError:
|
|
86
|
+
print(self.formatter.error("Please enter a valid number"))
|
|
87
|
+
|
|
88
|
+
def multiselect(
|
|
89
|
+
self,
|
|
90
|
+
message: str,
|
|
91
|
+
choices: List[str],
|
|
92
|
+
defaults: Optional[List[int]] = None
|
|
93
|
+
) -> List[int]:
|
|
94
|
+
"""Select multiple choices.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
message: Selection message
|
|
98
|
+
choices: List of choices
|
|
99
|
+
defaults: Default choice indices
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
List of selected indices
|
|
103
|
+
"""
|
|
104
|
+
defaults = defaults or []
|
|
105
|
+
|
|
106
|
+
print(f"\n{self.formatter.heading(message, level=2)}\n")
|
|
107
|
+
print(self.formatter.dim("Enter numbers separated by commas, or 'all' for all choices\n"))
|
|
108
|
+
|
|
109
|
+
for i, choice in enumerate(choices, 1):
|
|
110
|
+
bullet = self.formatter.colorize(Symbol.ARROW.value, Color.BLUE)
|
|
111
|
+
default_mark = " (selected)" if i - 1 in defaults else ""
|
|
112
|
+
print(f"{bullet} {i}. {choice}{default_mark}")
|
|
113
|
+
|
|
114
|
+
while True:
|
|
115
|
+
prompt = "\nEnter choices"
|
|
116
|
+
if defaults:
|
|
117
|
+
default_str = ",".join(str(i + 1) for i in defaults)
|
|
118
|
+
prompt += f" [default: {default_str}]"
|
|
119
|
+
prompt += ": "
|
|
120
|
+
|
|
121
|
+
response = input(prompt).strip().lower()
|
|
122
|
+
|
|
123
|
+
if not response and defaults:
|
|
124
|
+
return defaults
|
|
125
|
+
|
|
126
|
+
if response == "all":
|
|
127
|
+
return list(range(len(choices)))
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
indices = [int(x.strip()) - 1 for x in response.split(",")]
|
|
131
|
+
if all(0 <= i < len(choices) for i in indices):
|
|
132
|
+
return indices
|
|
133
|
+
else:
|
|
134
|
+
print(self.formatter.error(f"All numbers must be between 1 and {len(choices)}"))
|
|
135
|
+
except ValueError:
|
|
136
|
+
print(self.formatter.error("Please enter valid numbers separated by commas"))
|
|
137
|
+
|
|
138
|
+
def text_input(
|
|
139
|
+
self,
|
|
140
|
+
message: str,
|
|
141
|
+
default: Optional[str] = None,
|
|
142
|
+
validator: Optional[Callable[[str], bool]] = None,
|
|
143
|
+
error_message: str = "Invalid input"
|
|
144
|
+
) -> str:
|
|
145
|
+
"""Get text input from user.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
message: Input message
|
|
149
|
+
default: Default value
|
|
150
|
+
validator: Validation function
|
|
151
|
+
error_message: Error message for validation failure
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
User input
|
|
155
|
+
"""
|
|
156
|
+
prompt = message
|
|
157
|
+
if default:
|
|
158
|
+
prompt += f" [default: {default}]"
|
|
159
|
+
prompt += ": "
|
|
160
|
+
|
|
161
|
+
while True:
|
|
162
|
+
response = input(prompt).strip()
|
|
163
|
+
|
|
164
|
+
if not response and default:
|
|
165
|
+
return default
|
|
166
|
+
|
|
167
|
+
if not response:
|
|
168
|
+
print(self.formatter.error("Input cannot be empty"))
|
|
169
|
+
continue
|
|
170
|
+
|
|
171
|
+
if validator and not validator(response):
|
|
172
|
+
print(self.formatter.error(error_message))
|
|
173
|
+
continue
|
|
174
|
+
|
|
175
|
+
return response
|
|
176
|
+
|
|
177
|
+
def password_input(self, message: str) -> str:
|
|
178
|
+
"""Get password input (hidden).
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
message: Input message
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
User input
|
|
185
|
+
"""
|
|
186
|
+
import getpass
|
|
187
|
+
return getpass.getpass(f"{message}: ")
|
|
188
|
+
|
|
189
|
+
def menu(
|
|
190
|
+
self,
|
|
191
|
+
title: str,
|
|
192
|
+
options: Dict[str, Callable[[], Any]],
|
|
193
|
+
show_exit: bool = True
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Display interactive menu.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
title: Menu title
|
|
199
|
+
options: Dictionary of option names to handlers
|
|
200
|
+
show_exit: Show exit option
|
|
201
|
+
"""
|
|
202
|
+
choices = list(options.keys())
|
|
203
|
+
if show_exit:
|
|
204
|
+
choices.append("Exit")
|
|
205
|
+
|
|
206
|
+
while True:
|
|
207
|
+
try:
|
|
208
|
+
index = self.select(title, choices)
|
|
209
|
+
|
|
210
|
+
if show_exit and index == len(choices) - 1:
|
|
211
|
+
print(self.formatter.info("Exiting..."))
|
|
212
|
+
break
|
|
213
|
+
|
|
214
|
+
option_name = choices[index]
|
|
215
|
+
handler = options[option_name]
|
|
216
|
+
|
|
217
|
+
result = handler()
|
|
218
|
+
|
|
219
|
+
if result is False:
|
|
220
|
+
break
|
|
221
|
+
|
|
222
|
+
except KeyboardInterrupt:
|
|
223
|
+
print("\n" + self.formatter.info("Interrupted by user"))
|
|
224
|
+
break
|
|
225
|
+
except Exception as e:
|
|
226
|
+
print(self.formatter.error(f"Error: {e}"))
|
|
227
|
+
|
|
228
|
+
def progress_steps(
|
|
229
|
+
self,
|
|
230
|
+
steps: List[str],
|
|
231
|
+
handlers: List[Callable[[], bool]]
|
|
232
|
+
) -> bool:
|
|
233
|
+
"""Execute steps with progress tracking.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
steps: List of step descriptions
|
|
237
|
+
handlers: List of step handlers
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
True if all steps completed successfully
|
|
241
|
+
"""
|
|
242
|
+
if len(steps) != len(handlers):
|
|
243
|
+
raise ValueError("Number of steps and handlers must match")
|
|
244
|
+
|
|
245
|
+
print(f"\n{self.formatter.heading('Progress', level=2)}\n")
|
|
246
|
+
|
|
247
|
+
for i, (step, handler) in enumerate(zip(steps, handlers), 1):
|
|
248
|
+
step_msg = f"Step {i}/{len(steps)}: {step}"
|
|
249
|
+
print(self.formatter.info(step_msg))
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
success = handler()
|
|
253
|
+
|
|
254
|
+
if success:
|
|
255
|
+
print(self.formatter.success(f"Completed: {step}"))
|
|
256
|
+
else:
|
|
257
|
+
print(self.formatter.error(f"Failed: {step}"))
|
|
258
|
+
return False
|
|
259
|
+
|
|
260
|
+
except Exception as e:
|
|
261
|
+
print(self.formatter.error(f"Error in {step}: {e}"))
|
|
262
|
+
return False
|
|
263
|
+
|
|
264
|
+
print(f"\n{self.formatter.success('All steps completed successfully!')}\n")
|
|
265
|
+
return True
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Help text for the geai-orch CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
CLI_USAGE = """
|
|
6
|
+
geai-orch - Agentic AI Orchestration CLI for Globant Enterprise AI
|
|
7
|
+
|
|
8
|
+
USAGE:
|
|
9
|
+
geai-orch [OPTIONS] <COMMAND> [ARGS]
|
|
10
|
+
|
|
11
|
+
OPTIONS:
|
|
12
|
+
-a, --alias <ALIAS> Use a specific credentials profile
|
|
13
|
+
--credentials <FILE> Path to custom credentials file
|
|
14
|
+
-v, --verbose Enable verbose logging
|
|
15
|
+
-h, --help Show help information
|
|
16
|
+
--version Show version information
|
|
17
|
+
|
|
18
|
+
COMMANDS:
|
|
19
|
+
help Show help information
|
|
20
|
+
version Show version information
|
|
21
|
+
reflection Run reflection pattern
|
|
22
|
+
tool-use Execute tool use pattern
|
|
23
|
+
react Run ReAct (Reasoning + Acting) pattern
|
|
24
|
+
planning Execute planning pattern
|
|
25
|
+
multi-agent Run multi-agent coordination pattern
|
|
26
|
+
run Quick run a pattern
|
|
27
|
+
|
|
28
|
+
EXAMPLES:
|
|
29
|
+
# Show help
|
|
30
|
+
geai-orch help
|
|
31
|
+
|
|
32
|
+
# Run reflection pattern
|
|
33
|
+
geai-orch reflection --agent my-agent --iterations 3
|
|
34
|
+
|
|
35
|
+
# Execute ReAct pattern with custom task
|
|
36
|
+
geai-orch react --task "Solve complex problem" --max-steps 10
|
|
37
|
+
|
|
38
|
+
# Multi-agent collaboration
|
|
39
|
+
geai-orch multi-agent --config agents.yaml
|
|
40
|
+
|
|
41
|
+
# Use specific credentials profile
|
|
42
|
+
geai-orch --alias production reflection --agent my-agent
|
|
43
|
+
|
|
44
|
+
For more information, visit: https://github.com/genexus-books/pygeai-orchestration
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
VERSION_TEXT = """
|
|
48
|
+
geai-orch version {version}
|
|
49
|
+
PyGEAI-Orchestration - Agentic AI Orchestration Patterns
|
|
50
|
+
|
|
51
|
+
Copyright © 2026 Globant
|
|
52
|
+
Licensed under the MIT License
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
HELP_REFLECTION = """
|
|
56
|
+
reflection - Run reflection pattern for iterative improvement
|
|
57
|
+
|
|
58
|
+
USAGE:
|
|
59
|
+
geai-orch reflection [OPTIONS]
|
|
60
|
+
|
|
61
|
+
OPTIONS:
|
|
62
|
+
-a, --agent <ID> Agent ID to use for reflection
|
|
63
|
+
-i, --iterations <N> Number of reflection iterations (default: 3)
|
|
64
|
+
-t, --task <TEXT> Task or text to improve
|
|
65
|
+
-o, --output <FILE> Output file for results
|
|
66
|
+
-v, --verbose Show detailed output
|
|
67
|
+
|
|
68
|
+
DESCRIPTION:
|
|
69
|
+
The reflection pattern enables agents to self-critique and iteratively
|
|
70
|
+
improve their outputs through multiple reflection cycles.
|
|
71
|
+
|
|
72
|
+
EXAMPLES:
|
|
73
|
+
geai-orch reflection --agent critic --task "Write a summary" --iterations 5
|
|
74
|
+
geai-orch reflection -a my-agent -t "Improve this code" -o result.txt
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
HELP_TOOL_USE = """
|
|
78
|
+
tool-use - Execute tool use pattern with function calling
|
|
79
|
+
|
|
80
|
+
USAGE:
|
|
81
|
+
geai-orch tool-use [OPTIONS]
|
|
82
|
+
|
|
83
|
+
OPTIONS:
|
|
84
|
+
-a, --agent <ID> Agent ID to use
|
|
85
|
+
-t, --tools <FILE> Tools configuration file (YAML/JSON)
|
|
86
|
+
--task <TEXT> Task description
|
|
87
|
+
-o, --output <FILE> Output file for results
|
|
88
|
+
-v, --verbose Show detailed output
|
|
89
|
+
|
|
90
|
+
DESCRIPTION:
|
|
91
|
+
The tool use pattern integrates function calling and external tool
|
|
92
|
+
execution into agent workflows.
|
|
93
|
+
|
|
94
|
+
EXAMPLES:
|
|
95
|
+
geai-orch tool-use --agent worker --tools tools.yaml --task "Search for info"
|
|
96
|
+
geai-orch tool-use -a my-agent --task "Execute calculation"
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
HELP_REACT = """
|
|
100
|
+
react - Run ReAct (Reasoning + Acting) pattern
|
|
101
|
+
|
|
102
|
+
USAGE:
|
|
103
|
+
geai-orch react [OPTIONS]
|
|
104
|
+
|
|
105
|
+
OPTIONS:
|
|
106
|
+
-a, --agent <ID> Agent ID to use
|
|
107
|
+
-t, --task <TEXT> Task to solve
|
|
108
|
+
--max-steps <N> Maximum reasoning-acting steps (default: 10)
|
|
109
|
+
-o, --output <FILE> Output file for results
|
|
110
|
+
-v, --verbose Show detailed reasoning trace
|
|
111
|
+
|
|
112
|
+
DESCRIPTION:
|
|
113
|
+
The ReAct pattern implements a Reasoning + Acting loop for step-by-step
|
|
114
|
+
problem solving with explicit reasoning traces.
|
|
115
|
+
|
|
116
|
+
EXAMPLES:
|
|
117
|
+
geai-orch react --agent reasoning-agent --task "Research topic" --max-steps 15
|
|
118
|
+
geai-orch react -a solver --task "Multi-step problem" -v
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
HELP_PLANNING = """
|
|
122
|
+
planning - Execute planning pattern for multi-step tasks
|
|
123
|
+
|
|
124
|
+
USAGE:
|
|
125
|
+
geai-orch planning [OPTIONS]
|
|
126
|
+
|
|
127
|
+
OPTIONS:
|
|
128
|
+
-a, --agent <ID> Planner agent ID
|
|
129
|
+
-t, --task <TEXT> Task to plan and execute
|
|
130
|
+
--plan-only Only create plan, don't execute
|
|
131
|
+
-o, --output <FILE> Output file for results
|
|
132
|
+
-v, --verbose Show detailed execution trace
|
|
133
|
+
|
|
134
|
+
DESCRIPTION:
|
|
135
|
+
The planning pattern creates and executes multi-step plans with
|
|
136
|
+
adaptive execution and progress tracking.
|
|
137
|
+
|
|
138
|
+
EXAMPLES:
|
|
139
|
+
geai-orch planning --agent planner --task "Build web app"
|
|
140
|
+
geai-orch planning -a my-planner --task "Complex project" --plan-only
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
HELP_MULTI_AGENT = """
|
|
144
|
+
multi-agent - Run multi-agent coordination pattern
|
|
145
|
+
|
|
146
|
+
USAGE:
|
|
147
|
+
geai-orch multi-agent [OPTIONS]
|
|
148
|
+
|
|
149
|
+
OPTIONS:
|
|
150
|
+
-c, --config <FILE> Agent configuration file (YAML/JSON)
|
|
151
|
+
-t, --task <TEXT> Task for agents to collaborate on
|
|
152
|
+
--strategy <NAME> Coordination strategy (default: sequential)
|
|
153
|
+
-o, --output <FILE> Output file for results
|
|
154
|
+
-v, --verbose Show agent communication details
|
|
155
|
+
|
|
156
|
+
DESCRIPTION:
|
|
157
|
+
The multi-agent pattern coordinates multiple agents working
|
|
158
|
+
collaboratively on complex tasks with defined roles.
|
|
159
|
+
|
|
160
|
+
STRATEGIES:
|
|
161
|
+
sequential - Agents work one after another
|
|
162
|
+
parallel - Agents work simultaneously
|
|
163
|
+
hierarchical - Leader-worker coordination
|
|
164
|
+
consensus - Agents reach consensus
|
|
165
|
+
|
|
166
|
+
EXAMPLES:
|
|
167
|
+
geai-orch multi-agent --config agents.yaml --task "Research report"
|
|
168
|
+
geai-orch multi-agent -c team.yaml -t "Complex analysis" --strategy consensus
|
|
169
|
+
"""
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from .base import (
|
|
2
|
+
BaseAgent,
|
|
3
|
+
AgentConfig,
|
|
4
|
+
BaseOrchestrator,
|
|
5
|
+
OrchestratorConfig,
|
|
6
|
+
BasePattern,
|
|
7
|
+
PatternConfig,
|
|
8
|
+
PatternResult,
|
|
9
|
+
PatternType,
|
|
10
|
+
BaseTool,
|
|
11
|
+
ToolConfig,
|
|
12
|
+
ToolResult,
|
|
13
|
+
ToolCategory,
|
|
14
|
+
GEAIAgent,
|
|
15
|
+
GEAIOrchestrator,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from .common import (
|
|
19
|
+
Message,
|
|
20
|
+
MessageRole,
|
|
21
|
+
Conversation,
|
|
22
|
+
Context,
|
|
23
|
+
ContextManager,
|
|
24
|
+
State,
|
|
25
|
+
StateStatus,
|
|
26
|
+
StateManager,
|
|
27
|
+
Memory,
|
|
28
|
+
MemoryEntry,
|
|
29
|
+
MemoryStore,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
from .utils import (
|
|
33
|
+
OrchestrationLogger,
|
|
34
|
+
get_logger,
|
|
35
|
+
ConfigManager,
|
|
36
|
+
get_config,
|
|
37
|
+
ValidationResult,
|
|
38
|
+
validate_agent_config,
|
|
39
|
+
validate_pattern_config,
|
|
40
|
+
validate_tool_config,
|
|
41
|
+
validate_pydantic_model,
|
|
42
|
+
CacheEntry,
|
|
43
|
+
LRUCache,
|
|
44
|
+
PatternCache,
|
|
45
|
+
Metric,
|
|
46
|
+
MetricType,
|
|
47
|
+
MetricsCollector,
|
|
48
|
+
GlobalMetrics,
|
|
49
|
+
TimerContext,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
from .exceptions import (
|
|
53
|
+
OrchestrationError,
|
|
54
|
+
PatternExecutionError,
|
|
55
|
+
PatternConfigurationError,
|
|
56
|
+
AgentError,
|
|
57
|
+
ToolExecutionError,
|
|
58
|
+
StateError,
|
|
59
|
+
ValidationError,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
from .handlers import (
|
|
63
|
+
ErrorHandler,
|
|
64
|
+
RetryHandler,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
from .composition import (
|
|
68
|
+
CompositionConfig,
|
|
69
|
+
CompositionMode,
|
|
70
|
+
PatternPipeline,
|
|
71
|
+
PatternComposer,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
__all__ = [
|
|
75
|
+
"BaseAgent",
|
|
76
|
+
"AgentConfig",
|
|
77
|
+
"BaseOrchestrator",
|
|
78
|
+
"OrchestratorConfig",
|
|
79
|
+
"BasePattern",
|
|
80
|
+
"PatternConfig",
|
|
81
|
+
"PatternResult",
|
|
82
|
+
"PatternType",
|
|
83
|
+
"BaseTool",
|
|
84
|
+
"ToolConfig",
|
|
85
|
+
"ToolResult",
|
|
86
|
+
"ToolCategory",
|
|
87
|
+
"GEAIAgent",
|
|
88
|
+
"GEAIOrchestrator",
|
|
89
|
+
"Message",
|
|
90
|
+
"MessageRole",
|
|
91
|
+
"Conversation",
|
|
92
|
+
"Context",
|
|
93
|
+
"ContextManager",
|
|
94
|
+
"State",
|
|
95
|
+
"StateStatus",
|
|
96
|
+
"StateManager",
|
|
97
|
+
"Memory",
|
|
98
|
+
"MemoryEntry",
|
|
99
|
+
"MemoryStore",
|
|
100
|
+
"OrchestrationLogger",
|
|
101
|
+
"get_logger",
|
|
102
|
+
"ConfigManager",
|
|
103
|
+
"get_config",
|
|
104
|
+
"ValidationResult",
|
|
105
|
+
"validate_agent_config",
|
|
106
|
+
"validate_pattern_config",
|
|
107
|
+
"validate_tool_config",
|
|
108
|
+
"validate_pydantic_model",
|
|
109
|
+
"OrchestrationError",
|
|
110
|
+
"PatternExecutionError",
|
|
111
|
+
"PatternConfigurationError",
|
|
112
|
+
"AgentError",
|
|
113
|
+
"ToolExecutionError",
|
|
114
|
+
"StateError",
|
|
115
|
+
"ValidationError",
|
|
116
|
+
"ErrorHandler",
|
|
117
|
+
"RetryHandler",
|
|
118
|
+
"CacheEntry",
|
|
119
|
+
"LRUCache",
|
|
120
|
+
"PatternCache",
|
|
121
|
+
"Metric",
|
|
122
|
+
"MetricType",
|
|
123
|
+
"MetricsCollector",
|
|
124
|
+
"GlobalMetrics",
|
|
125
|
+
"TimerContext",
|
|
126
|
+
"CompositionConfig",
|
|
127
|
+
"CompositionMode",
|
|
128
|
+
"PatternPipeline",
|
|
129
|
+
"PatternComposer",
|
|
130
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .agent import BaseAgent, AgentConfig
|
|
2
|
+
from .orchestrator import BaseOrchestrator, OrchestratorConfig
|
|
3
|
+
from .pattern import BasePattern, PatternConfig, PatternResult, PatternType
|
|
4
|
+
from .tool import BaseTool, ToolConfig, ToolResult, ToolCategory
|
|
5
|
+
from .geai_agent import GEAIAgent
|
|
6
|
+
from .geai_orchestrator import GEAIOrchestrator
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"BaseAgent",
|
|
10
|
+
"AgentConfig",
|
|
11
|
+
"BaseOrchestrator",
|
|
12
|
+
"OrchestratorConfig",
|
|
13
|
+
"BasePattern",
|
|
14
|
+
"PatternConfig",
|
|
15
|
+
"PatternResult",
|
|
16
|
+
"PatternType",
|
|
17
|
+
"BaseTool",
|
|
18
|
+
"ToolConfig",
|
|
19
|
+
"ToolResult",
|
|
20
|
+
"ToolCategory",
|
|
21
|
+
"GEAIAgent",
|
|
22
|
+
"GEAIOrchestrator",
|
|
23
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base agent definitions for orchestration agents.
|
|
3
|
+
|
|
4
|
+
This module provides the foundation classes for all agent implementations,
|
|
5
|
+
including configuration and the abstract base agent interface.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AgentConfig(BaseModel):
|
|
14
|
+
"""
|
|
15
|
+
Configuration model for agents.
|
|
16
|
+
|
|
17
|
+
This Pydantic model defines the configuration parameters for agent behavior,
|
|
18
|
+
including model selection, generation parameters, and optional tools.
|
|
19
|
+
|
|
20
|
+
:param name: str - Unique identifier for the agent.
|
|
21
|
+
:param description: Optional[str] - Human-readable description of agent purpose/role.
|
|
22
|
+
:param model: str - Model identifier (e.g., 'gpt-4', 'claude-3-opus').
|
|
23
|
+
:param temperature: float - Sampling temperature (0.0-2.0). Higher = more random.
|
|
24
|
+
:param max_tokens: Optional[int] - Maximum tokens to generate. None means model default.
|
|
25
|
+
:param system_prompt: Optional[str] - System-level instructions for the agent.
|
|
26
|
+
:param tools: List[str] - List of tool names available to this agent.
|
|
27
|
+
:param metadata: Dict[str, Any] - Custom metadata for agent-specific configuration.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
name: str = Field(..., description="Agent name")
|
|
31
|
+
description: Optional[str] = Field(None, description="Agent description")
|
|
32
|
+
model: str = Field(..., description="Model identifier")
|
|
33
|
+
temperature: float = Field(0.7, ge=0.0, le=2.0)
|
|
34
|
+
max_tokens: Optional[int] = Field(None, ge=1)
|
|
35
|
+
system_prompt: Optional[str] = None
|
|
36
|
+
tools: List[str] = Field(default_factory=list)
|
|
37
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class BaseAgent(ABC):
|
|
41
|
+
"""
|
|
42
|
+
Abstract base class for all agent implementations.
|
|
43
|
+
|
|
44
|
+
This class defines the interface that all agent implementations must provide,
|
|
45
|
+
including task execution, text generation, and interaction history management.
|
|
46
|
+
|
|
47
|
+
Agents are the core execution units in orchestration patterns, responsible for:
|
|
48
|
+
- Generating text responses
|
|
49
|
+
- Executing tasks with context
|
|
50
|
+
- Managing conversation/interaction history
|
|
51
|
+
|
|
52
|
+
Subclasses must implement:
|
|
53
|
+
- execute(): Execute a task with optional context
|
|
54
|
+
- generate(): Generate text from a prompt
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(self, config: AgentConfig):
|
|
58
|
+
"""
|
|
59
|
+
Initialize the base agent with configuration.
|
|
60
|
+
|
|
61
|
+
:param config: AgentConfig - Configuration for this agent instance.
|
|
62
|
+
"""
|
|
63
|
+
self.config = config
|
|
64
|
+
self.name = config.name
|
|
65
|
+
self.description = config.description
|
|
66
|
+
self._history: List[Dict[str, Any]] = []
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
async def execute(self, task: str, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
70
|
+
"""
|
|
71
|
+
Execute a task with optional context.
|
|
72
|
+
|
|
73
|
+
This method provides high-level task execution with structured input/output.
|
|
74
|
+
Subclasses implement this to define task processing logic.
|
|
75
|
+
|
|
76
|
+
:param task: str - The task to execute.
|
|
77
|
+
:param context: Optional[Dict[str, Any]] - Additional context for execution.
|
|
78
|
+
:return: Dict[str, Any] - Execution results and metadata.
|
|
79
|
+
"""
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
async def generate(self, prompt: str, **kwargs) -> str:
|
|
84
|
+
"""
|
|
85
|
+
Generate text from a prompt.
|
|
86
|
+
|
|
87
|
+
This is the core text generation method used by patterns. Subclasses
|
|
88
|
+
implement this to interface with language models or other generation backends.
|
|
89
|
+
|
|
90
|
+
:param prompt: str - The prompt to generate from.
|
|
91
|
+
:param kwargs: Additional generation parameters (model-specific).
|
|
92
|
+
:return: str - Generated text response.
|
|
93
|
+
"""
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
def add_to_history(self, entry: Dict[str, Any]) -> None:
|
|
97
|
+
"""
|
|
98
|
+
Add an entry to the agent's interaction history.
|
|
99
|
+
|
|
100
|
+
:param entry: Dict[str, Any] - History entry (e.g., prompt, response, metadata).
|
|
101
|
+
"""
|
|
102
|
+
self._history.append(entry)
|
|
103
|
+
|
|
104
|
+
def get_history(self) -> List[Dict[str, Any]]:
|
|
105
|
+
"""
|
|
106
|
+
Get a copy of the agent's interaction history.
|
|
107
|
+
|
|
108
|
+
:return: List[Dict[str, Any]] - Copy of history entries.
|
|
109
|
+
"""
|
|
110
|
+
return self._history.copy()
|
|
111
|
+
|
|
112
|
+
def clear_history(self) -> None:
|
|
113
|
+
"""
|
|
114
|
+
Clear the agent's interaction history.
|
|
115
|
+
|
|
116
|
+
Removes all history entries to start fresh.
|
|
117
|
+
"""
|
|
118
|
+
self._history.clear()
|
|
119
|
+
|
|
120
|
+
def __repr__(self) -> str:
|
|
121
|
+
return f"<{self.__class__.__name__}(name='{self.name}')>"
|