anderson-ufrj commited on
Commit
f2c26ae
·
1 Parent(s): d568e3b

refactor(agents): migrate Anita agent to new BaseAgent pattern

Browse files

- Update constructor to use BaseAgent parameters (name, description, capabilities)
- Replace execute() method with process() returning AgentResponse
- Add initialize() and shutdown() methods as required by BaseAgent
- Update all agent_id references to use self.name
- Fix message parsing to use action/payload instead of message_type/content
- Update error handling and return types to match new pattern

This aligns Anita agent with the modern agent architecture defined in deodoro.py

Files changed (1) hide show
  1. src/agents/anita.py +52 -28
src/agents/anita.py CHANGED
@@ -16,8 +16,8 @@ from collections import defaultdict, Counter
16
  import numpy as np
17
  from pydantic import BaseModel, Field as PydanticField
18
 
19
- from src.agents.deodoro import BaseAgent, AgentContext, AgentMessage
20
- from src.core import get_logger
21
  from src.core.exceptions import AgentExecutionError, DataAnalysisError
22
  from src.tools.transparency_api import TransparencyAPIClient, TransparencyAPIFilter
23
  from src.ml.spectral_analyzer import SpectralAnalyzer, SpectralFeatures, PeriodicPattern
@@ -83,7 +83,6 @@ class AnalystAgent(BaseAgent):
83
 
84
  def __init__(
85
  self,
86
- agent_id: str = "analyst",
87
  min_correlation_threshold: float = 0.3,
88
  significance_threshold: float = 0.05,
89
  trend_detection_window: int = 6, # months
@@ -92,16 +91,29 @@ class AnalystAgent(BaseAgent):
92
  Initialize the Analyst Agent.
93
 
94
  Args:
95
- agent_id: Unique identifier for this agent
96
  min_correlation_threshold: Minimum correlation coefficient to report
97
  significance_threshold: P-value threshold for statistical significance
98
  trend_detection_window: Number of periods for trend analysis
99
  """
100
- super().__init__(agent_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  self.correlation_threshold = min_correlation_threshold
102
  self.significance_threshold = significance_threshold
103
  self.trend_window = trend_detection_window
104
- self.logger = get_logger(__name__)
105
 
106
  # Initialize spectral analyzer for frequency-domain analysis
107
  self.spectral_analyzer = SpectralAnalyzer()
@@ -121,50 +133,59 @@ class AnalystAgent(BaseAgent):
121
 
122
  self.logger.info(
123
  "analyst_agent_initialized",
124
- agent_id=agent_id,
125
  correlation_threshold=min_correlation_threshold,
126
  significance_threshold=significance_threshold,
127
  )
128
 
129
- async def execute(
 
 
 
 
 
 
 
 
130
  self,
131
  message: AgentMessage,
132
  context: AgentContext
133
- ) -> AgentMessage:
134
  """
135
- Execute pattern analysis based on the incoming message.
136
 
137
  Args:
138
  message: Analysis request message
139
  context: Agent execution context
140
 
141
  Returns:
142
- Analysis results with patterns and correlations
143
  """
144
  try:
145
  self.logger.info(
146
  "analysis_started",
147
  investigation_id=context.investigation_id,
148
- agent_id=self.agent_id,
149
- message_type=message.message_type,
150
  )
151
 
152
  # Parse analysis request
153
- if message.message_type == "analysis_request":
154
- request = AnalysisRequest(**message.content)
155
  else:
156
  raise AgentExecutionError(
157
- f"Unsupported message type: {message.message_type}",
158
- agent_id=self.agent_id
159
  )
160
 
161
  # Fetch data for analysis
162
  analysis_data = await self._fetch_analysis_data(request, context)
163
 
164
  if not analysis_data:
165
- return AgentMessage(
166
- message_type="analysis_result",
167
- content={
 
168
  "status": "no_data",
169
  "message": "No data found for the specified criteria",
170
  "patterns": [],
@@ -194,7 +215,7 @@ class AnalystAgent(BaseAgent):
194
  "metadata": {
195
  "investigation_id": context.investigation_id,
196
  "timestamp": datetime.utcnow().isoformat(),
197
- "agent_id": self.agent_id,
198
  "records_analyzed": len(analysis_data),
199
  "patterns_found": len(patterns),
200
  "correlations_found": len(correlations),
@@ -209,9 +230,10 @@ class AnalystAgent(BaseAgent):
209
  correlations_found=len(correlations),
210
  )
211
 
212
- return AgentMessage(
213
- message_type="analysis_result",
214
- content=result,
 
215
  metadata={"investigation_id": context.investigation_id}
216
  )
217
 
@@ -220,12 +242,14 @@ class AnalystAgent(BaseAgent):
220
  "analysis_failed",
221
  investigation_id=context.investigation_id,
222
  error=str(e),
223
- agent_id=self.agent_id,
224
  )
225
 
226
- return AgentMessage(
227
- message_type="analysis_error",
228
- content={
 
 
229
  "status": "error",
230
  "error": str(e),
231
  "investigation_id": context.investigation_id,
 
16
  import numpy as np
17
  from pydantic import BaseModel, Field as PydanticField
18
 
19
+ from src.agents.deodoro import BaseAgent, AgentContext, AgentMessage, AgentResponse
20
+ from src.core import get_logger, AgentStatus
21
  from src.core.exceptions import AgentExecutionError, DataAnalysisError
22
  from src.tools.transparency_api import TransparencyAPIClient, TransparencyAPIFilter
23
  from src.ml.spectral_analyzer import SpectralAnalyzer, SpectralFeatures, PeriodicPattern
 
83
 
84
  def __init__(
85
  self,
 
86
  min_correlation_threshold: float = 0.3,
87
  significance_threshold: float = 0.05,
88
  trend_detection_window: int = 6, # months
 
91
  Initialize the Analyst Agent.
92
 
93
  Args:
 
94
  min_correlation_threshold: Minimum correlation coefficient to report
95
  significance_threshold: P-value threshold for statistical significance
96
  trend_detection_window: Number of periods for trend analysis
97
  """
98
+ super().__init__(
99
+ name="Anita",
100
+ description="Anita Garibaldi - Agent specialized in pattern analysis and correlation detection",
101
+ capabilities=[
102
+ "spending_trend_analysis",
103
+ "organizational_comparison",
104
+ "vendor_behavior_analysis",
105
+ "seasonal_pattern_detection",
106
+ "value_distribution_analysis",
107
+ "correlation_analysis",
108
+ "efficiency_metrics",
109
+ "predictive_modeling"
110
+ ],
111
+ max_retries=3,
112
+ timeout=60
113
+ )
114
  self.correlation_threshold = min_correlation_threshold
115
  self.significance_threshold = significance_threshold
116
  self.trend_window = trend_detection_window
 
117
 
118
  # Initialize spectral analyzer for frequency-domain analysis
119
  self.spectral_analyzer = SpectralAnalyzer()
 
133
 
134
  self.logger.info(
135
  "analyst_agent_initialized",
136
+ agent_name=self.name,
137
  correlation_threshold=min_correlation_threshold,
138
  significance_threshold=significance_threshold,
139
  )
140
 
141
+ async def initialize(self) -> None:
142
+ """Initialize agent resources."""
143
+ self.logger.info(f"{self.name} agent initialized")
144
+
145
+ async def shutdown(self) -> None:
146
+ """Cleanup agent resources."""
147
+ self.logger.info(f"{self.name} agent shutting down")
148
+
149
+ async def process(
150
  self,
151
  message: AgentMessage,
152
  context: AgentContext
153
+ ) -> AgentResponse:
154
  """
155
+ Process pattern analysis request and return insights.
156
 
157
  Args:
158
  message: Analysis request message
159
  context: Agent execution context
160
 
161
  Returns:
162
+ AgentResponse with patterns and correlations
163
  """
164
  try:
165
  self.logger.info(
166
  "analysis_started",
167
  investigation_id=context.investigation_id,
168
+ agent_name=self.name,
169
+ action=message.action,
170
  )
171
 
172
  # Parse analysis request
173
+ if message.action == "analyze":
174
+ request = AnalysisRequest(**message.payload)
175
  else:
176
  raise AgentExecutionError(
177
+ f"Unsupported action: {message.action}",
178
+ agent_id=self.name
179
  )
180
 
181
  # Fetch data for analysis
182
  analysis_data = await self._fetch_analysis_data(request, context)
183
 
184
  if not analysis_data:
185
+ return AgentResponse(
186
+ agent_name=self.name,
187
+ status=AgentStatus.COMPLETED,
188
+ result={
189
  "status": "no_data",
190
  "message": "No data found for the specified criteria",
191
  "patterns": [],
 
215
  "metadata": {
216
  "investigation_id": context.investigation_id,
217
  "timestamp": datetime.utcnow().isoformat(),
218
+ "agent_name": self.name,
219
  "records_analyzed": len(analysis_data),
220
  "patterns_found": len(patterns),
221
  "correlations_found": len(correlations),
 
230
  correlations_found=len(correlations),
231
  )
232
 
233
+ return AgentResponse(
234
+ agent_name=self.name,
235
+ status=AgentStatus.COMPLETED,
236
+ result=result,
237
  metadata={"investigation_id": context.investigation_id}
238
  )
239
 
 
242
  "analysis_failed",
243
  investigation_id=context.investigation_id,
244
  error=str(e),
245
+ agent_name=self.name,
246
  )
247
 
248
+ return AgentResponse(
249
+ agent_name=self.name,
250
+ status=AgentStatus.ERROR,
251
+ error=str(e),
252
+ result={
253
  "status": "error",
254
  "error": str(e),
255
  "investigation_id": context.investigation_id,