agent.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from opendevin.controller import AgentController
  2. from opendevin.controller.agent import Agent
  3. from opendevin.controller.state.state import State
  4. from opendevin.core.config import AppConfig, LLMConfig
  5. from opendevin.core.logger import opendevin_logger as logger
  6. from opendevin.events.stream import EventStream
  7. from opendevin.runtime import get_runtime_cls
  8. from opendevin.runtime.runtime import Runtime
  9. from opendevin.security import SecurityAnalyzer, options
  10. from opendevin.storage.files import FileStore
  11. class AgentSession:
  12. """Represents a session with an agent.
  13. Attributes:
  14. controller: The AgentController instance for controlling the agent.
  15. """
  16. sid: str
  17. event_stream: EventStream
  18. file_store: FileStore
  19. controller: AgentController | None = None
  20. runtime: Runtime | None = None
  21. security_analyzer: SecurityAnalyzer | None = None
  22. _closed: bool = False
  23. def __init__(self, sid: str, file_store: FileStore):
  24. """Initializes a new instance of the Session class."""
  25. self.sid = sid
  26. self.event_stream = EventStream(sid, file_store)
  27. self.file_store = file_store
  28. async def start(
  29. self,
  30. runtime_name: str,
  31. config: AppConfig,
  32. agent: Agent,
  33. max_iterations: int,
  34. max_budget_per_task: float | None = None,
  35. agent_to_llm_config: dict[str, LLMConfig] | None = None,
  36. ):
  37. """Starts the agent session.
  38. Args:
  39. start_event: The start event data (optional).
  40. """
  41. if self.controller or self.runtime:
  42. raise Exception(
  43. 'Session already started. You need to close this session and start a new one.'
  44. )
  45. await self._create_security_analyzer(config.security.security_analyzer)
  46. await self._create_runtime(runtime_name, config, agent)
  47. await self._create_controller(
  48. agent,
  49. config.security.confirmation_mode,
  50. max_iterations,
  51. max_budget_per_task=max_budget_per_task,
  52. agent_to_llm_config=agent_to_llm_config,
  53. )
  54. async def close(self):
  55. if self._closed:
  56. return
  57. if self.controller is not None:
  58. end_state = self.controller.get_state()
  59. end_state.save_to_session(self.sid, self.file_store)
  60. await self.controller.close()
  61. if self.runtime is not None:
  62. await self.runtime.close()
  63. if self.security_analyzer is not None:
  64. await self.security_analyzer.close()
  65. self._closed = True
  66. async def _create_security_analyzer(self, security_analyzer: str | None):
  67. """Creates a SecurityAnalyzer instance that will be used to analyze the agent actions."""
  68. logger.info(f'Using security analyzer: {security_analyzer}')
  69. if security_analyzer:
  70. self.security_analyzer = options.SecurityAnalyzers.get(
  71. security_analyzer, SecurityAnalyzer
  72. )(self.event_stream)
  73. async def _create_runtime(self, runtime_name: str, config: AppConfig, agent: Agent):
  74. """Creates a runtime instance."""
  75. if self.runtime is not None:
  76. raise Exception('Runtime already created')
  77. logger.info(f'Using runtime: {runtime_name}')
  78. runtime_cls = get_runtime_cls(runtime_name)
  79. self.runtime = runtime_cls(
  80. config=config,
  81. event_stream=self.event_stream,
  82. sid=self.sid,
  83. plugins=agent.sandbox_plugins,
  84. )
  85. await self.runtime.ainit()
  86. async def _create_controller(
  87. self,
  88. agent: Agent,
  89. confirmation_mode: bool,
  90. max_iterations: int,
  91. max_budget_per_task: float | None = None,
  92. agent_to_llm_config: dict[str, LLMConfig] | None = None,
  93. ):
  94. """Creates an AgentController instance."""
  95. if self.controller is not None:
  96. raise Exception('Controller already created')
  97. if self.runtime is None:
  98. raise Exception('Runtime must be initialized before the agent controller')
  99. logger.info(f'Creating agent {agent.name} using LLM {agent.llm.config.model}')
  100. self.controller = AgentController(
  101. sid=self.sid,
  102. event_stream=self.event_stream,
  103. agent=agent,
  104. max_iterations=int(max_iterations),
  105. max_budget_per_task=max_budget_per_task,
  106. agent_to_llm_config=agent_to_llm_config,
  107. confirmation_mode=confirmation_mode,
  108. # AgentSession is designed to communicate with the frontend, so we don't want to
  109. # run the agent in headless mode.
  110. headless_mode=False,
  111. )
  112. try:
  113. agent_state = State.restore_from_session(self.sid, self.file_store)
  114. self.controller.set_initial_state(
  115. agent_state, max_iterations, confirmation_mode
  116. )
  117. logger.info(f'Restored agent state from session, sid: {self.sid}')
  118. except Exception as e:
  119. print('Error restoring state', e)