Просмотр исходного кода

Track metrics throughout delegation & Polish UX for out of budget error (#2595)

* Track metrics (costs) throught delegation

* Metrics should be shared across agents for better UX

* Update cost before starting delegate
Boxuan Li 1 год назад
Родитель
Сommit
39d90c0b2a
2 измененных файлов с 11 добавлено и 2 удалено
  1. 8 2
      opendevin/controller/agent_controller.py
  2. 3 0
      opendevin/core/metrics.py

+ 8 - 2
opendevin/controller/agent_controller.py

@@ -108,7 +108,7 @@ class AgentController:
             current_cost = self.state.metrics.accumulated_cost
             current_cost = self.state.metrics.accumulated_cost
             if current_cost > self.max_budget_per_task:
             if current_cost > self.max_budget_per_task:
                 await self.report_error(
                 await self.report_error(
-                    f'Task budget exceeded. Current cost: {current_cost}, Max budget: {self.max_budget_per_task}'
+                    f'Task budget exceeded. Current cost: {current_cost:.2f}, Max budget: {self.max_budget_per_task:.2f}'
                 )
                 )
                 await self.set_agent_state_to(AgentState.ERROR)
                 await self.set_agent_state_to(AgentState.ERROR)
 
 
@@ -222,6 +222,8 @@ class AgentController:
             max_iterations=self.state.max_iterations,
             max_iterations=self.state.max_iterations,
             num_of_chars=self.state.num_of_chars,
             num_of_chars=self.state.num_of_chars,
             delegate_level=self.state.delegate_level + 1,
             delegate_level=self.state.delegate_level + 1,
+            # metrics should be shared between parent and child
+            metrics=self.state.metrics,
         )
         )
         logger.info(f'[Agent Controller {self.id}]: start delegate')
         logger.info(f'[Agent Controller {self.id}]: start delegate')
         self.delegate = AgentController(
         self.delegate = AgentController(
@@ -230,6 +232,7 @@ class AgentController:
             event_stream=self.event_stream,
             event_stream=self.event_stream,
             max_iterations=self.state.max_iterations,
             max_iterations=self.state.max_iterations,
             max_chars=self.max_chars,
             max_chars=self.max_chars,
+            max_budget_per_task=self.max_budget_per_task,
             initial_state=state,
             initial_state=state,
             is_delegate=True,
             is_delegate=True,
         )
         )
@@ -308,12 +311,15 @@ class AgentController:
 
 
         logger.info(action, extra={'msg_type': 'ACTION'})
         logger.info(action, extra={'msg_type': 'ACTION'})
 
 
-        await self.update_state_after_step()
         if action.runnable:
         if action.runnable:
             self._pending_action = action
             self._pending_action = action
         else:
         else:
             await self.add_history(action, NullObservation(''))
             await self.add_history(action, NullObservation(''))
 
 
+        await self.update_state_after_step()
+        if self.state.agent_state == AgentState.ERROR:
+            return
+
         if not isinstance(action, NullAction):
         if not isinstance(action, NullAction):
             await self.event_stream.add_event(action, EventSource.AGENT)
             await self.event_stream.add_event(action, EventSource.AGENT)
 
 

+ 3 - 0
opendevin/core/metrics.py

@@ -44,3 +44,6 @@ class Metrics:
         for key, value in metrics.items():
         for key, value in metrics.items():
             logs += f'{key}: {value}\n'
             logs += f'{key}: {value}\n'
         return logs
         return logs
+
+    def __repr__(self):
+        return f'Metrics({self.get()}'