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,144 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyGEAI-based agent implementation.
|
|
3
|
+
|
|
4
|
+
This module provides a concrete agent implementation using the PyGEAI SDK,
|
|
5
|
+
enabling AI-powered task execution with GeneXus Enterprise AI.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
from .agent import BaseAgent, AgentConfig
|
|
10
|
+
from ..utils import get_logger
|
|
11
|
+
|
|
12
|
+
logger = get_logger()
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from pygeai import Session
|
|
16
|
+
|
|
17
|
+
PYGEAI_AVAILABLE = True
|
|
18
|
+
except ImportError:
|
|
19
|
+
PYGEAI_AVAILABLE = False
|
|
20
|
+
logger.warning("PyGEAI not available. GEAIAgent will have limited functionality.")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GEAIAgent(BaseAgent):
|
|
24
|
+
"""
|
|
25
|
+
Agent implementation using PyGEAI SDK.
|
|
26
|
+
|
|
27
|
+
This agent leverages the PyGEAI SDK to execute tasks using GeneXus
|
|
28
|
+
Enterprise AI models, providing AI-powered reasoning and generation.
|
|
29
|
+
|
|
30
|
+
The agent:
|
|
31
|
+
- Integrates with PyGEAI Session and Agent resources
|
|
32
|
+
- Supports custom system prompts and model configuration
|
|
33
|
+
- Automatically manages agent resource creation
|
|
34
|
+
- Maintains execution history
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, config: AgentConfig, session=None, alias: Optional[str] = None):
|
|
38
|
+
"""
|
|
39
|
+
Initialize the GEAI agent with PyGEAI session.
|
|
40
|
+
|
|
41
|
+
:param config: AgentConfig - Agent configuration.
|
|
42
|
+
:param session: Optional PyGEAI Session - Existing session to use.
|
|
43
|
+
:param alias: Optional[str] - Session alias if creating new session.
|
|
44
|
+
:raises ImportError: If PyGEAI is not installed.
|
|
45
|
+
"""
|
|
46
|
+
super().__init__(config)
|
|
47
|
+
if not PYGEAI_AVAILABLE:
|
|
48
|
+
raise ImportError("PyGEAI is required for GEAIAgent but is not installed")
|
|
49
|
+
self._session = session or Session(alias=alias)
|
|
50
|
+
self._agent_resource = None
|
|
51
|
+
|
|
52
|
+
async def execute(self, task: str, context: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
53
|
+
"""
|
|
54
|
+
Execute a task using PyGEAI generation.
|
|
55
|
+
|
|
56
|
+
:param task: str - Task description or instruction.
|
|
57
|
+
:param context: Optional[Dict[str, Any]] - Execution context.
|
|
58
|
+
:return: Dict[str, Any] - Execution result with success status and output.
|
|
59
|
+
"""
|
|
60
|
+
logger.debug(f"GEAIAgent '{self.name}' executing task")
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
result = await self.generate(task, context=context)
|
|
64
|
+
|
|
65
|
+
execution_result = {
|
|
66
|
+
"success": True,
|
|
67
|
+
"result": result,
|
|
68
|
+
"agent": self.name,
|
|
69
|
+
"metadata": context or {},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
self.add_to_history(execution_result)
|
|
73
|
+
return execution_result
|
|
74
|
+
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.error(f"GEAIAgent execution failed: {str(e)}")
|
|
77
|
+
error_result = {"success": False, "result": None, "error": str(e), "agent": self.name}
|
|
78
|
+
self.add_to_history(error_result)
|
|
79
|
+
return error_result
|
|
80
|
+
|
|
81
|
+
async def generate(self, prompt: str, **kwargs) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Generate a response using PyGEAI chat completion.
|
|
84
|
+
|
|
85
|
+
:param prompt: str - Input prompt for generation.
|
|
86
|
+
:param kwargs: Additional generation parameters (messages, etc.).
|
|
87
|
+
:return: str - Generated text response.
|
|
88
|
+
:raises Exception: If generation fails.
|
|
89
|
+
"""
|
|
90
|
+
try:
|
|
91
|
+
self._get_or_create_agent()
|
|
92
|
+
|
|
93
|
+
messages = kwargs.get("messages", [])
|
|
94
|
+
if not messages:
|
|
95
|
+
messages = [{"role": "user", "content": prompt}]
|
|
96
|
+
|
|
97
|
+
if self.config.system_prompt:
|
|
98
|
+
messages.insert(0, {"role": "system", "content": self.config.system_prompt})
|
|
99
|
+
|
|
100
|
+
chat = self._session.chats.create(
|
|
101
|
+
messages=messages,
|
|
102
|
+
model=self.config.model,
|
|
103
|
+
temperature=self.config.temperature,
|
|
104
|
+
max_tokens=self.config.max_tokens,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
response = chat.choices[0].message.content
|
|
108
|
+
|
|
109
|
+
self.add_to_history({"type": "generation", "prompt": prompt, "response": response})
|
|
110
|
+
|
|
111
|
+
return response
|
|
112
|
+
|
|
113
|
+
except Exception as e:
|
|
114
|
+
logger.error(f"Generation failed: {str(e)}")
|
|
115
|
+
raise
|
|
116
|
+
|
|
117
|
+
def _get_or_create_agent(self):
|
|
118
|
+
"""
|
|
119
|
+
Get or create PyGEAI agent resource.
|
|
120
|
+
|
|
121
|
+
Lazily creates an agent resource in PyGEAI if not already created,
|
|
122
|
+
or reuses existing agent with matching name.
|
|
123
|
+
|
|
124
|
+
:return: PyGEAI Agent resource.
|
|
125
|
+
"""
|
|
126
|
+
if self._agent_resource is None:
|
|
127
|
+
try:
|
|
128
|
+
agents = self._session.agents.list()
|
|
129
|
+
for agent in agents.data:
|
|
130
|
+
if agent.name == self.name:
|
|
131
|
+
self._agent_resource = agent
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
if self._agent_resource is None:
|
|
135
|
+
logger.debug(f"Creating new agent resource: {self.name}")
|
|
136
|
+
self._agent_resource = self._session.agents.create(
|
|
137
|
+
name=self.name,
|
|
138
|
+
model=self.config.model,
|
|
139
|
+
description=self.config.description or f"Orchestration agent: {self.name}",
|
|
140
|
+
)
|
|
141
|
+
except Exception as e:
|
|
142
|
+
logger.warning(f"Could not create agent resource: {str(e)}")
|
|
143
|
+
|
|
144
|
+
return self._agent_resource
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
|
+
from .orchestrator import BaseOrchestrator, OrchestratorConfig
|
|
3
|
+
from .pattern import PatternResult
|
|
4
|
+
from ..utils import get_logger
|
|
5
|
+
|
|
6
|
+
logger = get_logger()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GEAIOrchestrator(BaseOrchestrator):
|
|
10
|
+
def __init__(self, config: OrchestratorConfig):
|
|
11
|
+
super().__init__(config)
|
|
12
|
+
self._execution_history: List[Dict[str, Any]] = []
|
|
13
|
+
|
|
14
|
+
async def orchestrate(
|
|
15
|
+
self, task: str, pattern: str, context: Optional[Dict[str, Any]] = None
|
|
16
|
+
) -> PatternResult:
|
|
17
|
+
logger.info(f"Orchestrating task with pattern '{pattern}': {task[:50]}...")
|
|
18
|
+
|
|
19
|
+
pattern_instance = self.get_pattern(pattern)
|
|
20
|
+
if pattern_instance is None:
|
|
21
|
+
error_msg = f"Pattern '{pattern}' not found. Available: {self.list_patterns()}"
|
|
22
|
+
logger.error(error_msg)
|
|
23
|
+
return PatternResult(success=False, result=None, iterations=0, error=error_msg)
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
result = await pattern_instance.execute(task, context)
|
|
27
|
+
|
|
28
|
+
self._execution_history.append(
|
|
29
|
+
{
|
|
30
|
+
"task": task,
|
|
31
|
+
"pattern": pattern,
|
|
32
|
+
"success": result.success,
|
|
33
|
+
"iterations": result.iterations,
|
|
34
|
+
"result": result.result,
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
logger.info(
|
|
39
|
+
f"Orchestration {'succeeded' if result.success else 'failed'} "
|
|
40
|
+
f"after {result.iterations} iterations"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return result
|
|
44
|
+
|
|
45
|
+
except Exception as e:
|
|
46
|
+
logger.error(f"Orchestration error: {str(e)}")
|
|
47
|
+
return PatternResult(success=False, result=None, iterations=0, error=str(e))
|
|
48
|
+
|
|
49
|
+
async def coordinate_agents(self, agents: List[str], task: str) -> Dict[str, Any]:
|
|
50
|
+
logger.info(f"Coordinating {len(agents)} agents for task: {task[:50]}...")
|
|
51
|
+
|
|
52
|
+
results = {}
|
|
53
|
+
|
|
54
|
+
for agent_name in agents:
|
|
55
|
+
agent = self.get_agent(agent_name)
|
|
56
|
+
if agent is None:
|
|
57
|
+
logger.warning(f"Agent '{agent_name}' not found, skipping")
|
|
58
|
+
continue
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
result = await agent.execute(task)
|
|
62
|
+
results[agent_name] = result
|
|
63
|
+
except Exception as e:
|
|
64
|
+
logger.error(f"Agent '{agent_name}' failed: {str(e)}")
|
|
65
|
+
results[agent_name] = {"success": False, "error": str(e)}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
"success": len(results) > 0,
|
|
69
|
+
"results": results,
|
|
70
|
+
"agents_executed": list(results.keys()),
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
def get_execution_history(self) -> List[Dict[str, Any]]:
|
|
74
|
+
return self._execution_history.copy()
|
|
75
|
+
|
|
76
|
+
def clear_history(self) -> None:
|
|
77
|
+
self._execution_history.clear()
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Orchestrator base classes for managing agents and patterns.
|
|
3
|
+
|
|
4
|
+
This module provides the foundation for orchestrating multiple agents
|
|
5
|
+
and patterns, including registration, coordination, and task delegation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from .agent import BaseAgent
|
|
13
|
+
from .pattern import BasePattern, PatternResult
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OrchestratorConfig(BaseModel):
|
|
17
|
+
"""
|
|
18
|
+
Configuration model for orchestrators.
|
|
19
|
+
|
|
20
|
+
This Pydantic model defines orchestrator behavior including
|
|
21
|
+
concurrency limits, timeouts, and retry policies.
|
|
22
|
+
|
|
23
|
+
:param name: str - Unique identifier for the orchestrator.
|
|
24
|
+
:param max_concurrent_tasks: int - Maximum number of tasks to run concurrently.
|
|
25
|
+
:param timeout: Optional[float] - Global timeout in seconds. None means no timeout.
|
|
26
|
+
:param retry_attempts: int - Number of retry attempts on task failure.
|
|
27
|
+
:param metadata: Dict[str, Any] - Custom metadata for orchestrator configuration.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
name: str = Field(..., description="Orchestrator name")
|
|
31
|
+
max_concurrent_tasks: int = Field(5, ge=1, description="Max concurrent tasks")
|
|
32
|
+
timeout: Optional[float] = Field(None, ge=0.0, description="Global timeout in seconds")
|
|
33
|
+
retry_attempts: int = Field(3, ge=0, description="Number of retry attempts on failure")
|
|
34
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class BaseOrchestrator(ABC):
|
|
38
|
+
"""
|
|
39
|
+
Abstract base class for orchestrator implementations.
|
|
40
|
+
|
|
41
|
+
This class defines the interface for orchestrating multiple agents
|
|
42
|
+
and patterns, enabling complex multi-agent workflows and pattern chaining.
|
|
43
|
+
|
|
44
|
+
Orchestrators manage:
|
|
45
|
+
- Agent registration and retrieval
|
|
46
|
+
- Pattern registration and selection
|
|
47
|
+
- Task delegation and coordination
|
|
48
|
+
- Multi-agent collaboration
|
|
49
|
+
|
|
50
|
+
Subclasses must implement:
|
|
51
|
+
- orchestrate(): Execute a task using a specific pattern
|
|
52
|
+
- coordinate_agents(): Coordinate multiple agents on a task
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, config: OrchestratorConfig):
|
|
56
|
+
"""
|
|
57
|
+
Initialize the orchestrator with configuration.
|
|
58
|
+
|
|
59
|
+
:param config: OrchestratorConfig - Configuration for this orchestrator.
|
|
60
|
+
"""
|
|
61
|
+
self.config = config
|
|
62
|
+
self.name = config.name
|
|
63
|
+
self._agents: Dict[str, BaseAgent] = {}
|
|
64
|
+
self._patterns: Dict[str, BasePattern] = {}
|
|
65
|
+
|
|
66
|
+
def register_agent(self, agent: BaseAgent) -> None:
|
|
67
|
+
"""
|
|
68
|
+
Register an agent with this orchestrator.
|
|
69
|
+
|
|
70
|
+
:param agent: BaseAgent - Agent to register.
|
|
71
|
+
"""
|
|
72
|
+
self._agents[agent.name] = agent
|
|
73
|
+
|
|
74
|
+
def register_pattern(self, pattern: BasePattern) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Register a pattern with this orchestrator.
|
|
77
|
+
|
|
78
|
+
:param pattern: BasePattern - Pattern to register.
|
|
79
|
+
"""
|
|
80
|
+
self._patterns[pattern.name] = pattern
|
|
81
|
+
|
|
82
|
+
def get_agent(self, name: str) -> Optional[BaseAgent]:
|
|
83
|
+
"""
|
|
84
|
+
Retrieve a registered agent by name.
|
|
85
|
+
|
|
86
|
+
:param name: str - Agent name.
|
|
87
|
+
:return: Optional[BaseAgent] - The agent if found, None otherwise.
|
|
88
|
+
"""
|
|
89
|
+
return self._agents.get(name)
|
|
90
|
+
|
|
91
|
+
def get_pattern(self, name: str) -> Optional[BasePattern]:
|
|
92
|
+
"""
|
|
93
|
+
Retrieve a registered pattern by name.
|
|
94
|
+
|
|
95
|
+
:param name: str - Pattern name.
|
|
96
|
+
:return: Optional[BasePattern] - The pattern if found, None otherwise.
|
|
97
|
+
"""
|
|
98
|
+
return self._patterns.get(name)
|
|
99
|
+
|
|
100
|
+
def list_agents(self) -> List[str]:
|
|
101
|
+
"""
|
|
102
|
+
List all registered agent names.
|
|
103
|
+
|
|
104
|
+
:return: List[str] - Agent names.
|
|
105
|
+
"""
|
|
106
|
+
return list(self._agents.keys())
|
|
107
|
+
|
|
108
|
+
def list_patterns(self) -> List[str]:
|
|
109
|
+
"""
|
|
110
|
+
List all registered pattern names.
|
|
111
|
+
|
|
112
|
+
:return: List[str] - Pattern names.
|
|
113
|
+
"""
|
|
114
|
+
return list(self._patterns.keys())
|
|
115
|
+
|
|
116
|
+
@abstractmethod
|
|
117
|
+
async def orchestrate(
|
|
118
|
+
self, task: str, pattern: str, context: Optional[Dict[str, Any]] = None
|
|
119
|
+
) -> PatternResult:
|
|
120
|
+
"""
|
|
121
|
+
Execute a task using a specified pattern.
|
|
122
|
+
|
|
123
|
+
:param task: str - Task description or instruction.
|
|
124
|
+
:param pattern: str - Name of the pattern to use.
|
|
125
|
+
:param context: Optional[Dict[str, Any]] - Execution context.
|
|
126
|
+
:return: PatternResult - Execution result.
|
|
127
|
+
"""
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
@abstractmethod
|
|
131
|
+
async def coordinate_agents(self, agents: List[str], task: str) -> Dict[str, Any]:
|
|
132
|
+
"""
|
|
133
|
+
Coordinate multiple agents to complete a task.
|
|
134
|
+
|
|
135
|
+
:param agents: List[str] - Names of agents to coordinate.
|
|
136
|
+
:param task: str - Task description or instruction.
|
|
137
|
+
:return: Dict[str, Any] - Coordination results.
|
|
138
|
+
"""
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
def __repr__(self) -> str:
|
|
142
|
+
return f"<{self.__class__.__name__}(name='{self.name}', agents={len(self._agents)}, patterns={len(self._patterns)})>"
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base pattern definitions for orchestration patterns.
|
|
3
|
+
|
|
4
|
+
This module provides the foundation classes for all orchestration patterns,
|
|
5
|
+
including configuration, results, and the abstract base pattern interface.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
from enum import Enum
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class PatternType(str, Enum):
|
|
15
|
+
"""
|
|
16
|
+
Enumeration of available orchestration pattern types.
|
|
17
|
+
|
|
18
|
+
Each pattern type represents a distinct approach to agentic AI orchestration:
|
|
19
|
+
- REFLECTION: Iterative self-critique and refinement
|
|
20
|
+
- TOOL_USE: External tool integration and execution
|
|
21
|
+
- REACT: Reasoning and acting with thought traces
|
|
22
|
+
- PLANNING: Task decomposition and sequential execution
|
|
23
|
+
- MULTI_AGENT: Collaborative multi-agent problem solving
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
REFLECTION = "reflection"
|
|
27
|
+
TOOL_USE = "tool_use"
|
|
28
|
+
REACT = "react"
|
|
29
|
+
PLANNING = "planning"
|
|
30
|
+
MULTI_AGENT = "multi_agent"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PatternConfig(BaseModel):
|
|
34
|
+
"""
|
|
35
|
+
Configuration model for orchestration patterns.
|
|
36
|
+
|
|
37
|
+
This Pydantic model defines the configuration parameters that control
|
|
38
|
+
pattern execution behavior, including iteration limits, timeouts, and
|
|
39
|
+
custom metadata.
|
|
40
|
+
|
|
41
|
+
:param name: str - Unique identifier for the pattern instance.
|
|
42
|
+
:param pattern_type: PatternType - The type of orchestration pattern.
|
|
43
|
+
:param max_iterations: int - Maximum number of iterations allowed (minimum 1).
|
|
44
|
+
:param timeout: Optional[float] - Execution timeout in seconds. None means no timeout.
|
|
45
|
+
:param verbose: bool - Enable detailed logging output. Defaults to False.
|
|
46
|
+
:param metadata: Dict[str, Any] - Custom metadata for pattern-specific configuration.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
name: str = Field(..., description="Pattern name")
|
|
50
|
+
pattern_type: PatternType = Field(..., description="Type of orchestration pattern")
|
|
51
|
+
max_iterations: int = Field(10, ge=1, description="Maximum iterations")
|
|
52
|
+
timeout: Optional[float] = Field(None, ge=0.0, description="Timeout in seconds")
|
|
53
|
+
verbose: bool = Field(False, description="Enable verbose output")
|
|
54
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class PatternResult(BaseModel):
|
|
58
|
+
"""
|
|
59
|
+
Result model for pattern execution outcomes.
|
|
60
|
+
|
|
61
|
+
This Pydantic model encapsulates the results of pattern execution,
|
|
62
|
+
including success status, output data, iteration count, errors, and
|
|
63
|
+
execution metadata.
|
|
64
|
+
|
|
65
|
+
:param success: bool - Whether the pattern execution succeeded.
|
|
66
|
+
:param result: Any - The final output or answer from pattern execution.
|
|
67
|
+
:param iterations: int - Number of iterations executed (minimum 0).
|
|
68
|
+
:param error: Optional[str] - Error message if execution failed. None on success.
|
|
69
|
+
:param metadata: Dict[str, Any] - Additional execution metadata (e.g., intermediate results, timing).
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
success: bool = Field(..., description="Whether pattern execution succeeded")
|
|
73
|
+
result: Any = Field(None, description="Pattern execution result")
|
|
74
|
+
iterations: int = Field(0, ge=0, description="Number of iterations executed")
|
|
75
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
76
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class BasePattern(ABC):
|
|
80
|
+
"""
|
|
81
|
+
Abstract base class for all orchestration patterns.
|
|
82
|
+
|
|
83
|
+
This class defines the interface that all orchestration patterns must implement,
|
|
84
|
+
including the core execute() and step() methods. It provides common functionality
|
|
85
|
+
for iteration tracking and state management.
|
|
86
|
+
|
|
87
|
+
Subclasses must implement:
|
|
88
|
+
- execute(): Main entry point for pattern execution
|
|
89
|
+
- step(): Single iteration/step logic
|
|
90
|
+
|
|
91
|
+
The base class handles iteration counting and provides lifecycle hooks for
|
|
92
|
+
pattern initialization and reset.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, config: PatternConfig):
|
|
96
|
+
"""
|
|
97
|
+
Initialize the base pattern with configuration.
|
|
98
|
+
|
|
99
|
+
:param config: PatternConfig - Configuration for this pattern instance.
|
|
100
|
+
"""
|
|
101
|
+
self.config = config
|
|
102
|
+
self.name = config.name
|
|
103
|
+
self.pattern_type = config.pattern_type
|
|
104
|
+
self._iteration_count = 0
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
async def execute(self, task: str, context: Optional[Dict[str, Any]] = None) -> PatternResult:
|
|
108
|
+
"""
|
|
109
|
+
Execute the orchestration pattern on the given task.
|
|
110
|
+
|
|
111
|
+
This is the main entry point for pattern execution. Subclasses must
|
|
112
|
+
implement this method to define their specific orchestration logic.
|
|
113
|
+
|
|
114
|
+
:param task: str - The task or question to execute.
|
|
115
|
+
:param context: Optional[Dict[str, Any]] - Additional context for execution.
|
|
116
|
+
:return: PatternResult - Execution results including success status and output.
|
|
117
|
+
"""
|
|
118
|
+
pass
|
|
119
|
+
|
|
120
|
+
@abstractmethod
|
|
121
|
+
async def step(self, state: Dict[str, Any]) -> Dict[str, Any]:
|
|
122
|
+
"""
|
|
123
|
+
Execute a single iteration step of the pattern.
|
|
124
|
+
|
|
125
|
+
This method defines the logic for one iteration of the pattern's execution
|
|
126
|
+
loop. Subclasses implement this to define step-level behavior.
|
|
127
|
+
|
|
128
|
+
:param state: Dict[str, Any] - Current state including iteration count, history, etc.
|
|
129
|
+
:return: Dict[str, Any] - Step results and updated state information.
|
|
130
|
+
"""
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
def reset(self) -> None:
|
|
134
|
+
"""
|
|
135
|
+
Reset the pattern state for a new execution.
|
|
136
|
+
|
|
137
|
+
Clears iteration count and any other stateful information to prepare
|
|
138
|
+
for a fresh pattern execution.
|
|
139
|
+
"""
|
|
140
|
+
self._iteration_count = 0
|
|
141
|
+
|
|
142
|
+
def increment_iteration(self) -> int:
|
|
143
|
+
"""
|
|
144
|
+
Increment the iteration counter and return the new count.
|
|
145
|
+
|
|
146
|
+
:return: int - The new iteration count after incrementing.
|
|
147
|
+
"""
|
|
148
|
+
self._iteration_count += 1
|
|
149
|
+
return self._iteration_count
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def current_iteration(self) -> int:
|
|
153
|
+
"""
|
|
154
|
+
Get the current iteration count.
|
|
155
|
+
|
|
156
|
+
:return: int - Current iteration number (0-indexed).
|
|
157
|
+
"""
|
|
158
|
+
return self._iteration_count
|
|
159
|
+
|
|
160
|
+
def __repr__(self) -> str:
|
|
161
|
+
return f"<{self.__class__.__name__}(name='{self.name}', type='{self.pattern_type.value}')>"
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base tool definitions for orchestration tools.
|
|
3
|
+
|
|
4
|
+
This module provides the foundation classes for all tool implementations,
|
|
5
|
+
including configuration, results, and the abstract base tool interface.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
from enum import Enum
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ToolCategory(str, Enum):
|
|
15
|
+
"""
|
|
16
|
+
Enumeration of tool categories.
|
|
17
|
+
|
|
18
|
+
Categories help organize and classify tools by their primary function:
|
|
19
|
+
- SEARCH: Web search, knowledge retrieval
|
|
20
|
+
- COMPUTATION: Calculators, data processing, algorithms
|
|
21
|
+
- DATA_ACCESS: Database queries, file access, API calls
|
|
22
|
+
- COMMUNICATION: Email, messaging, notifications
|
|
23
|
+
- CUSTOM: User-defined or specialized tools
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
SEARCH = "search"
|
|
27
|
+
COMPUTATION = "computation"
|
|
28
|
+
DATA_ACCESS = "data_access"
|
|
29
|
+
COMMUNICATION = "communication"
|
|
30
|
+
CUSTOM = "custom"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ToolConfig(BaseModel):
|
|
34
|
+
"""
|
|
35
|
+
Configuration model for tools.
|
|
36
|
+
|
|
37
|
+
This Pydantic model defines the configuration parameters for tool behavior,
|
|
38
|
+
including metadata, parameter schemas, and execution limits.
|
|
39
|
+
|
|
40
|
+
:param name: str - Unique identifier for the tool.
|
|
41
|
+
:param description: str - Human-readable description of tool functionality.
|
|
42
|
+
:param category: ToolCategory - Category classification for the tool.
|
|
43
|
+
:param parameters_schema: Dict[str, Any] - JSON schema for tool parameters.
|
|
44
|
+
:param timeout: Optional[float] - Execution timeout in seconds. None means no timeout.
|
|
45
|
+
:param metadata: Dict[str, Any] - Custom metadata for tool-specific configuration.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
name: str = Field(..., description="Tool name")
|
|
49
|
+
description: str = Field(..., description="Tool description")
|
|
50
|
+
category: ToolCategory = Field(ToolCategory.CUSTOM, description="Tool category")
|
|
51
|
+
parameters_schema: Dict[str, Any] = Field(default_factory=dict)
|
|
52
|
+
timeout: Optional[float] = Field(None, ge=0.0, description="Tool execution timeout")
|
|
53
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ToolResult(BaseModel):
|
|
57
|
+
"""
|
|
58
|
+
Result model for tool execution outcomes.
|
|
59
|
+
|
|
60
|
+
This Pydantic model encapsulates the results of tool execution,
|
|
61
|
+
including success status, output data, errors, and execution metrics.
|
|
62
|
+
|
|
63
|
+
:param success: bool - Whether the tool execution succeeded.
|
|
64
|
+
:param result: Any - The output data from tool execution.
|
|
65
|
+
:param error: Optional[str] - Error message if execution failed. None on success.
|
|
66
|
+
:param execution_time: Optional[float] - Time taken to execute in seconds.
|
|
67
|
+
:param metadata: Dict[str, Any] - Additional execution metadata.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
success: bool = Field(..., description="Whether tool execution succeeded")
|
|
71
|
+
result: Any = Field(None, description="Tool execution result")
|
|
72
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
73
|
+
execution_time: Optional[float] = Field(None, description="Execution time in seconds")
|
|
74
|
+
metadata: Dict[str, Any] = Field(default_factory=dict)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class BaseTool(ABC):
|
|
78
|
+
"""
|
|
79
|
+
Abstract base class for all tool implementations.
|
|
80
|
+
|
|
81
|
+
This class defines the interface that all tool implementations must provide,
|
|
82
|
+
including execution, parameter validation, and schema retrieval.
|
|
83
|
+
|
|
84
|
+
Tools extend agent capabilities by providing access to:
|
|
85
|
+
- External APIs and services
|
|
86
|
+
- Computational operations
|
|
87
|
+
- Data retrieval and manipulation
|
|
88
|
+
- Communication channels
|
|
89
|
+
|
|
90
|
+
Subclasses must implement:
|
|
91
|
+
- execute(): Perform the tool's primary function
|
|
92
|
+
- validate_parameters(): Validate input parameters before execution
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, config: ToolConfig):
|
|
96
|
+
"""
|
|
97
|
+
Initialize the base tool with configuration.
|
|
98
|
+
|
|
99
|
+
:param config: ToolConfig - Configuration for this tool instance.
|
|
100
|
+
"""
|
|
101
|
+
self.config = config
|
|
102
|
+
self.name = config.name
|
|
103
|
+
self.description = config.description
|
|
104
|
+
self.category = config.category
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
async def execute(self, **kwargs) -> ToolResult:
|
|
108
|
+
"""
|
|
109
|
+
Execute the tool with the given parameters.
|
|
110
|
+
|
|
111
|
+
This is the main entry point for tool execution. Subclasses implement
|
|
112
|
+
this method to define their specific functionality.
|
|
113
|
+
|
|
114
|
+
:param kwargs: Tool-specific parameters.
|
|
115
|
+
:return: ToolResult - Execution results including success status and output.
|
|
116
|
+
"""
|
|
117
|
+
pass
|
|
118
|
+
|
|
119
|
+
@abstractmethod
|
|
120
|
+
def validate_parameters(self, parameters: Dict[str, Any]) -> bool:
|
|
121
|
+
"""
|
|
122
|
+
Validate parameters before execution.
|
|
123
|
+
|
|
124
|
+
Subclasses implement this to check parameter correctness, types,
|
|
125
|
+
and required fields before attempting execution.
|
|
126
|
+
|
|
127
|
+
:param parameters: Dict[str, Any] - Parameters to validate.
|
|
128
|
+
:return: bool - True if valid, False otherwise.
|
|
129
|
+
"""
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
def get_schema(self) -> Dict[str, Any]:
|
|
133
|
+
"""
|
|
134
|
+
Get the tool's schema definition.
|
|
135
|
+
|
|
136
|
+
Returns a structured representation of the tool including name,
|
|
137
|
+
description, category, and parameter schema for agent introspection.
|
|
138
|
+
|
|
139
|
+
:return: Dict[str, Any] - Tool schema with metadata and parameter definitions.
|
|
140
|
+
"""
|
|
141
|
+
return {
|
|
142
|
+
"name": self.name,
|
|
143
|
+
"description": self.description,
|
|
144
|
+
"category": self.category.value,
|
|
145
|
+
"parameters": self.config.parameters_schema,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
def __repr__(self) -> str:
|
|
149
|
+
return f"<{self.__class__.__name__}(name='{self.name}', category='{self.category.value}')>"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from .message import Message, MessageRole, Conversation
|
|
2
|
+
from .context import Context, ContextManager
|
|
3
|
+
from .state import State, StateStatus, StateManager
|
|
4
|
+
from .memory import Memory, MemoryEntry, MemoryStore
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"Message",
|
|
8
|
+
"MessageRole",
|
|
9
|
+
"Conversation",
|
|
10
|
+
"Context",
|
|
11
|
+
"ContextManager",
|
|
12
|
+
"State",
|
|
13
|
+
"StateStatus",
|
|
14
|
+
"StateManager",
|
|
15
|
+
"Memory",
|
|
16
|
+
"MemoryEntry",
|
|
17
|
+
"MemoryStore",
|
|
18
|
+
]
|