aiecs 1.3.8__py3-none-any.whl → 1.4.1__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.

Potentially problematic release.


This version of aiecs might be problematic. Click here for more details.

Files changed (37) hide show
  1. aiecs/__init__.py +1 -1
  2. aiecs/domain/__init__.py +120 -0
  3. aiecs/domain/agent/__init__.py +184 -0
  4. aiecs/domain/agent/base_agent.py +691 -0
  5. aiecs/domain/agent/exceptions.py +99 -0
  6. aiecs/domain/agent/hybrid_agent.py +495 -0
  7. aiecs/domain/agent/integration/__init__.py +23 -0
  8. aiecs/domain/agent/integration/context_compressor.py +219 -0
  9. aiecs/domain/agent/integration/context_engine_adapter.py +258 -0
  10. aiecs/domain/agent/integration/retry_policy.py +228 -0
  11. aiecs/domain/agent/integration/role_config.py +217 -0
  12. aiecs/domain/agent/lifecycle.py +298 -0
  13. aiecs/domain/agent/llm_agent.py +309 -0
  14. aiecs/domain/agent/memory/__init__.py +13 -0
  15. aiecs/domain/agent/memory/conversation.py +216 -0
  16. aiecs/domain/agent/migration/__init__.py +15 -0
  17. aiecs/domain/agent/migration/conversion.py +171 -0
  18. aiecs/domain/agent/migration/legacy_wrapper.py +97 -0
  19. aiecs/domain/agent/models.py +263 -0
  20. aiecs/domain/agent/observability.py +443 -0
  21. aiecs/domain/agent/persistence.py +287 -0
  22. aiecs/domain/agent/prompts/__init__.py +25 -0
  23. aiecs/domain/agent/prompts/builder.py +164 -0
  24. aiecs/domain/agent/prompts/formatters.py +192 -0
  25. aiecs/domain/agent/prompts/template.py +264 -0
  26. aiecs/domain/agent/registry.py +261 -0
  27. aiecs/domain/agent/tool_agent.py +267 -0
  28. aiecs/domain/agent/tools/__init__.py +13 -0
  29. aiecs/domain/agent/tools/schema_generator.py +222 -0
  30. aiecs/main.py +2 -2
  31. aiecs/tools/search_tool/__init__.py +1 -0
  32. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/METADATA +1 -1
  33. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/RECORD +37 -10
  34. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/WHEEL +0 -0
  35. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/entry_points.txt +0 -0
  36. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/licenses/LICENSE +0 -0
  37. {aiecs-1.3.8.dist-info → aiecs-1.4.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,171 @@
1
+ """
2
+ Conversion Utilities
3
+
4
+ Convert legacy configurations and prompts to new format.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any, Optional
9
+ import re
10
+
11
+ from ..models import AgentConfiguration
12
+ from ..prompts import PromptTemplate, ChatPromptTemplate, MessageTemplate
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def convert_legacy_config(legacy_config: Dict[str, Any]) -> AgentConfiguration:
18
+ """
19
+ Convert legacy agent configuration to AgentConfiguration.
20
+
21
+ Args:
22
+ legacy_config: Legacy configuration dictionary
23
+
24
+ Returns:
25
+ AgentConfiguration instance
26
+ """
27
+ # Map legacy fields to new fields
28
+ field_mapping = {
29
+ # Common legacy field names
30
+ "model": "llm_model",
31
+ "model_name": "llm_model",
32
+ "temp": "temperature",
33
+ "max_output_tokens": "max_tokens",
34
+ "enable_memory": "memory_enabled",
35
+ "verbose": "verbose",
36
+ }
37
+
38
+ converted = {}
39
+ for old_field, value in legacy_config.items():
40
+ new_field = field_mapping.get(old_field, old_field)
41
+ converted[new_field] = value
42
+
43
+ # Create AgentConfiguration
44
+ try:
45
+ config = AgentConfiguration(**converted)
46
+ logger.info("Legacy configuration converted successfully")
47
+ return config
48
+ except Exception as e:
49
+ logger.error(f"Failed to convert legacy config: {e}")
50
+ # Return default config with available fields
51
+ return AgentConfiguration(
52
+ llm_model=converted.get("llm_model"),
53
+ temperature=converted.get("temperature", 0.7),
54
+ max_tokens=converted.get("max_tokens"),
55
+ )
56
+
57
+
58
+ def convert_langchain_prompt(langchain_prompt: str) -> PromptTemplate:
59
+ """
60
+ Convert LangChain prompt template to native PromptTemplate.
61
+
62
+ LangChain uses {variable} syntax, which is compatible with our format.
63
+
64
+ Args:
65
+ langchain_prompt: LangChain prompt string
66
+
67
+ Returns:
68
+ PromptTemplate instance
69
+ """
70
+ # LangChain and our template use same {variable} syntax
71
+ # Just need to extract variables
72
+ pattern = r'\{(\w+)\}'
73
+ variables = re.findall(pattern, langchain_prompt)
74
+
75
+ return PromptTemplate(
76
+ template=langchain_prompt,
77
+ required_variables=variables
78
+ )
79
+
80
+
81
+ def convert_langchain_chat_prompt(
82
+ messages: list
83
+ ) -> ChatPromptTemplate:
84
+ """
85
+ Convert LangChain chat prompt to ChatPromptTemplate.
86
+
87
+ Args:
88
+ messages: List of (role, template) tuples
89
+
90
+ Returns:
91
+ ChatPromptTemplate instance
92
+ """
93
+ message_templates = []
94
+
95
+ for item in messages:
96
+ if isinstance(item, tuple):
97
+ role, template = item
98
+ elif isinstance(item, dict):
99
+ role = item.get('role', 'user')
100
+ template = item.get('content', '')
101
+ else:
102
+ logger.warning(f"Unknown message format: {item}")
103
+ continue
104
+
105
+ message_templates.append(MessageTemplate(role=role, content=template))
106
+
107
+ return ChatPromptTemplate(messages=message_templates)
108
+
109
+
110
+ def migrate_agent_state(
111
+ legacy_state: Dict[str, Any]
112
+ ) -> Dict[str, Any]:
113
+ """
114
+ Migrate legacy agent state to new format.
115
+
116
+ Args:
117
+ legacy_state: Legacy state dictionary
118
+
119
+ Returns:
120
+ New state dictionary
121
+ """
122
+ # Map legacy state fields
123
+ state_mapping = {
124
+ "status": "state",
125
+ "task_history": "interactions",
126
+ "memory": "memory",
127
+ }
128
+
129
+ migrated = {}
130
+ for old_field, value in legacy_state.items():
131
+ new_field = state_mapping.get(old_field, old_field)
132
+ migrated[new_field] = value
133
+
134
+ logger.info("Agent state migrated")
135
+ return migrated
136
+
137
+
138
+ def validate_migration(
139
+ legacy_agent: Any,
140
+ new_agent: Any
141
+ ) -> Dict[str, Any]:
142
+ """
143
+ Validate migration by comparing legacy and new agent behavior.
144
+
145
+ Args:
146
+ legacy_agent: Legacy agent instance
147
+ new_agent: New agent instance
148
+
149
+ Returns:
150
+ Validation report
151
+ """
152
+ report = {
153
+ "compatible": True,
154
+ "warnings": [],
155
+ "errors": [],
156
+ }
157
+
158
+ # Check for required methods
159
+ required_methods = ['execute_task']
160
+ for method in required_methods:
161
+ if not hasattr(new_agent, method):
162
+ report["compatible"] = False
163
+ report["errors"].append(f"Missing required method: {method}")
164
+
165
+ # Check configuration compatibility
166
+ if hasattr(legacy_agent, 'config') and hasattr(new_agent, '_config'):
167
+ # Basic compatibility check
168
+ logger.info("Configuration validated")
169
+
170
+ return report
171
+
@@ -0,0 +1,97 @@
1
+ """
2
+ Legacy Agent Wrapper
3
+
4
+ Compatibility wrapper for gradual migration from legacy agents.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any, Optional
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class LegacyAgentWrapper:
14
+ """
15
+ Wrapper for legacy agents to work with BaseAIAgent interface.
16
+
17
+ This enables gradual migration without breaking existing code.
18
+
19
+ Example:
20
+ legacy_agent = SomeLegacyAgent()
21
+ wrapped = LegacyAgentWrapper(legacy_agent)
22
+ result = await wrapped.execute_task(task, context)
23
+ """
24
+
25
+ def __init__(self, legacy_agent: Any):
26
+ """
27
+ Initialize wrapper.
28
+
29
+ Args:
30
+ legacy_agent: Legacy agent instance
31
+ """
32
+ self.legacy_agent = legacy_agent
33
+ self._is_wrapped = True
34
+ logger.info(f"Legacy agent wrapped: {type(legacy_agent).__name__}")
35
+
36
+ async def execute_task(
37
+ self,
38
+ task: Dict[str, Any],
39
+ context: Dict[str, Any]
40
+ ) -> Dict[str, Any]:
41
+ """
42
+ Execute task using legacy agent.
43
+
44
+ Args:
45
+ task: Task specification
46
+ context: Execution context
47
+
48
+ Returns:
49
+ Result dictionary
50
+ """
51
+ # Try various legacy interfaces
52
+ if hasattr(self.legacy_agent, 'execute_task'):
53
+ return await self.legacy_agent.execute_task(task, context)
54
+ elif hasattr(self.legacy_agent, 'run'):
55
+ result = await self.legacy_agent.run(task.get('description', ''))
56
+ return {"output": result, "success": True}
57
+ elif hasattr(self.legacy_agent, 'process'):
58
+ result = await self.legacy_agent.process(task)
59
+ return {"output": result, "success": True}
60
+ else:
61
+ raise NotImplementedError(
62
+ f"Legacy agent {type(self.legacy_agent).__name__} has no compatible interface"
63
+ )
64
+
65
+ async def process_message(
66
+ self,
67
+ message: str,
68
+ sender_id: Optional[str] = None
69
+ ) -> Dict[str, Any]:
70
+ """
71
+ Process message using legacy agent.
72
+
73
+ Args:
74
+ message: Message content
75
+ sender_id: Optional sender ID
76
+
77
+ Returns:
78
+ Response dictionary
79
+ """
80
+ if hasattr(self.legacy_agent, 'process_message'):
81
+ return await self.legacy_agent.process_message(message, sender_id)
82
+ elif hasattr(self.legacy_agent, 'chat'):
83
+ response = await self.legacy_agent.chat(message)
84
+ return {"response": response}
85
+ else:
86
+ # Fallback to execute_task
87
+ task = {"description": message}
88
+ result = await self.execute_task(task, {"sender_id": sender_id})
89
+ return {"response": result.get("output")}
90
+
91
+ def __getattr__(self, name: str):
92
+ """Forward attribute access to legacy agent."""
93
+ return getattr(self.legacy_agent, name)
94
+
95
+ def __repr__(self) -> str:
96
+ return f"LegacyAgentWrapper({type(self.legacy_agent).__name__})"
97
+
@@ -0,0 +1,263 @@
1
+ """
2
+ Agent Domain Models
3
+
4
+ Defines the core data models for the base AI agent system.
5
+ """
6
+
7
+ from datetime import datetime
8
+ from typing import Dict, List, Any, Optional
9
+ from enum import Enum
10
+ from pydantic import BaseModel, Field, ConfigDict
11
+ import uuid
12
+
13
+
14
+ class AgentState(str, Enum):
15
+ """Agent lifecycle states."""
16
+
17
+ CREATED = "created"
18
+ INITIALIZING = "initializing"
19
+ ACTIVE = "active"
20
+ IDLE = "idle"
21
+ BUSY = "busy"
22
+ ERROR = "error"
23
+ STOPPED = "stopped"
24
+
25
+
26
+ class AgentType(str, Enum):
27
+ """Types of AI agents."""
28
+
29
+ CONVERSATIONAL = "conversational"
30
+ TASK_EXECUTOR = "task_executor"
31
+ RESEARCHER = "researcher"
32
+ ANALYST = "analyst"
33
+ CREATIVE = "creative"
34
+ DEVELOPER = "developer"
35
+ COORDINATOR = "coordinator"
36
+
37
+
38
+ class GoalStatus(str, Enum):
39
+ """Status of agent goals."""
40
+
41
+ PENDING = "pending"
42
+ IN_PROGRESS = "in_progress"
43
+ ACHIEVED = "achieved"
44
+ FAILED = "failed"
45
+ ABANDONED = "abandoned"
46
+
47
+
48
+ class GoalPriority(str, Enum):
49
+ """Priority levels for goals."""
50
+
51
+ LOW = "low"
52
+ MEDIUM = "medium"
53
+ HIGH = "high"
54
+ CRITICAL = "critical"
55
+
56
+
57
+ class CapabilityLevel(str, Enum):
58
+ """Proficiency levels for agent capabilities."""
59
+
60
+ BASIC = "basic"
61
+ INTERMEDIATE = "intermediate"
62
+ ADVANCED = "advanced"
63
+ EXPERT = "expert"
64
+
65
+
66
+ class MemoryType(str, Enum):
67
+ """Types of agent memory."""
68
+
69
+ SHORT_TERM = "short_term"
70
+ LONG_TERM = "long_term"
71
+
72
+
73
+ class RetryPolicy(BaseModel):
74
+ """Retry policy configuration for agent operations."""
75
+
76
+ max_retries: int = Field(default=5, ge=0, description="Maximum number of retry attempts")
77
+ base_delay: float = Field(default=1.0, ge=0, description="Base delay in seconds for exponential backoff")
78
+ max_delay: float = Field(default=32.0, ge=0, description="Maximum delay cap in seconds")
79
+ exponential_factor: float = Field(default=2.0, ge=1.0, description="Exponential factor for backoff")
80
+ jitter_factor: float = Field(
81
+ default=0.2, ge=0.0, le=1.0, description="Jitter factor (±percentage) for randomization"
82
+ )
83
+ rate_limit_base_delay: float = Field(
84
+ default=5.0, ge=0, description="Base delay for rate limit errors"
85
+ )
86
+ rate_limit_max_delay: float = Field(
87
+ default=120.0, ge=0, description="Maximum delay for rate limit errors"
88
+ )
89
+
90
+ model_config = ConfigDict()
91
+
92
+
93
+ class AgentConfiguration(BaseModel):
94
+ """Configuration model for agent behavior and capabilities."""
95
+
96
+ # LLM settings
97
+ llm_provider: Optional[str] = Field(None, description="LLM provider name (e.g., 'openai', 'vertex')")
98
+ llm_model: Optional[str] = Field(None, description="LLM model name")
99
+ temperature: float = Field(default=0.7, ge=0.0, le=2.0, description="LLM temperature setting")
100
+ max_tokens: int = Field(default=4096, ge=1, description="Maximum tokens for LLM responses")
101
+
102
+ # Tool access
103
+ allowed_tools: List[str] = Field(default_factory=list, description="List of tool names agent can use")
104
+ tool_selection_strategy: str = Field(
105
+ default="llm_based", description="Strategy for tool selection ('llm_based', 'rule_based')"
106
+ )
107
+
108
+ # Memory configuration
109
+ memory_enabled: bool = Field(default=True, description="Whether memory is enabled")
110
+ memory_capacity: int = Field(
111
+ default=1000, ge=0, description="Maximum number of memory items"
112
+ )
113
+ memory_ttl_seconds: Optional[int] = Field(
114
+ None, ge=0, description="Time-to-live for short-term memory in seconds"
115
+ )
116
+
117
+ # Behavior parameters
118
+ max_iterations: int = Field(default=10, ge=1, description="Maximum iterations for ReAct loop")
119
+ timeout_seconds: Optional[int] = Field(None, ge=0, description="Task execution timeout")
120
+ verbose: bool = Field(default=False, description="Verbose logging")
121
+
122
+ # Retry policy
123
+ retry_policy: RetryPolicy = Field(default_factory=RetryPolicy, description="Retry policy configuration")
124
+
125
+ # Goal and context
126
+ goal: Optional[str] = Field(None, description="Agent's primary goal")
127
+ backstory: Optional[str] = Field(None, description="Agent's backstory/context")
128
+ domain_knowledge: Optional[str] = Field(None, description="Domain-specific knowledge")
129
+ reasoning_guidance: Optional[str] = Field(None, description="Guidance for reasoning approach")
130
+
131
+ # Context compression
132
+ context_window_limit: int = Field(
133
+ default=20000, ge=0, description="Token limit for context window"
134
+ )
135
+ enable_context_compression: bool = Field(
136
+ default=True, description="Enable automatic context compression"
137
+ )
138
+
139
+ # Metadata
140
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional configuration metadata")
141
+
142
+ model_config = ConfigDict()
143
+
144
+
145
+ class AgentGoal(BaseModel):
146
+ """Model representing an agent goal."""
147
+
148
+ goal_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique goal identifier")
149
+ description: str = Field(..., description="Goal description")
150
+ status: GoalStatus = Field(default=GoalStatus.PENDING, description="Current goal status")
151
+ priority: GoalPriority = Field(default=GoalPriority.MEDIUM, description="Goal priority level")
152
+ progress: float = Field(default=0.0, ge=0.0, le=100.0, description="Progress percentage (0-100)")
153
+
154
+ # Success criteria
155
+ success_criteria: Optional[str] = Field(None, description="Criteria for goal achievement")
156
+ deadline: Optional[datetime] = Field(None, description="Goal deadline")
157
+
158
+ # Dependencies
159
+ parent_goal_id: Optional[str] = Field(None, description="Parent goal ID if this is a sub-goal")
160
+ depends_on: List[str] = Field(default_factory=list, description="List of goal IDs this depends on")
161
+
162
+ # Timestamps
163
+ created_at: datetime = Field(default_factory=datetime.utcnow, description="Goal creation timestamp")
164
+ started_at: Optional[datetime] = Field(None, description="When goal execution started")
165
+ achieved_at: Optional[datetime] = Field(None, description="When goal was achieved")
166
+
167
+ # Metadata
168
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional goal metadata")
169
+
170
+ model_config = ConfigDict()
171
+
172
+
173
+ class AgentCapabilityDeclaration(BaseModel):
174
+ """Model declaring an agent capability."""
175
+
176
+ capability_type: str = Field(..., description="Type of capability (e.g., 'text_generation', 'code_generation')")
177
+ level: CapabilityLevel = Field(..., description="Proficiency level")
178
+ constraints: Dict[str, Any] = Field(default_factory=dict, description="Capability constraints")
179
+ description: Optional[str] = Field(None, description="Capability description")
180
+
181
+ # Timestamps
182
+ acquired_at: datetime = Field(default_factory=datetime.utcnow, description="When capability was acquired")
183
+
184
+ model_config = ConfigDict()
185
+
186
+
187
+ class AgentMetrics(BaseModel):
188
+ """Model for tracking agent performance metrics."""
189
+
190
+ # Task execution metrics
191
+ total_tasks_executed: int = Field(default=0, ge=0, description="Total number of tasks executed")
192
+ successful_tasks: int = Field(default=0, ge=0, description="Number of successful tasks")
193
+ failed_tasks: int = Field(default=0, ge=0, description="Number of failed tasks")
194
+ success_rate: float = Field(default=0.0, ge=0.0, le=100.0, description="Success rate percentage")
195
+
196
+ # Execution time metrics
197
+ average_execution_time: Optional[float] = Field(None, ge=0, description="Average task execution time in seconds")
198
+ total_execution_time: float = Field(default=0.0, ge=0, description="Total execution time in seconds")
199
+ min_execution_time: Optional[float] = Field(None, ge=0, description="Minimum execution time in seconds")
200
+ max_execution_time: Optional[float] = Field(None, ge=0, description="Maximum execution time in seconds")
201
+
202
+ # Quality metrics
203
+ average_quality_score: Optional[float] = Field(
204
+ None, ge=0.0, le=1.0, description="Average quality score (0-1)"
205
+ )
206
+
207
+ # Resource usage
208
+ total_tokens_used: int = Field(default=0, ge=0, description="Total LLM tokens used")
209
+ total_tool_calls: int = Field(default=0, ge=0, description="Total tool calls made")
210
+ total_api_cost: Optional[float] = Field(None, ge=0, description="Total API cost (if tracked)")
211
+
212
+ # Retry metrics
213
+ total_retries: int = Field(default=0, ge=0, description="Total number of retry attempts")
214
+ retry_successes: int = Field(default=0, ge=0, description="Number of successful retries")
215
+
216
+ # Error tracking
217
+ error_count: int = Field(default=0, ge=0, description="Total number of errors")
218
+ error_types: Dict[str, int] = Field(
219
+ default_factory=dict, description="Count of errors by type"
220
+ )
221
+
222
+ # Timestamps
223
+ last_reset_at: Optional[datetime] = Field(None, description="When metrics were last reset")
224
+ updated_at: datetime = Field(default_factory=datetime.utcnow, description="Last metrics update")
225
+
226
+ model_config = ConfigDict()
227
+
228
+
229
+ class AgentInteraction(BaseModel):
230
+ """Model representing an agent interaction."""
231
+
232
+ interaction_id: str = Field(
233
+ default_factory=lambda: str(uuid.uuid4()), description="Unique interaction identifier"
234
+ )
235
+ agent_id: str = Field(..., description="Agent ID involved in interaction")
236
+ interaction_type: str = Field(..., description="Type of interaction (e.g., 'task', 'message', 'tool_call')")
237
+ content: Dict[str, Any] = Field(..., description="Interaction content")
238
+
239
+ # Timestamps
240
+ timestamp: datetime = Field(default_factory=datetime.utcnow, description="Interaction timestamp")
241
+ duration_seconds: Optional[float] = Field(None, ge=0, description="Interaction duration")
242
+
243
+ # Metadata
244
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional interaction metadata")
245
+
246
+ model_config = ConfigDict()
247
+
248
+
249
+ class AgentMemory(BaseModel):
250
+ """Model for agent memory interface (base model, not implementation)."""
251
+
252
+ memory_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique memory identifier")
253
+ agent_id: str = Field(..., description="Associated agent ID")
254
+ memory_type: MemoryType = Field(..., description="Type of memory")
255
+ key: str = Field(..., description="Memory key")
256
+ value: Any = Field(..., description="Memory value")
257
+ timestamp: datetime = Field(default_factory=datetime.utcnow, description="When memory was stored")
258
+
259
+ # Metadata
260
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional memory metadata")
261
+
262
+ model_config = ConfigDict()
263
+