agent.py 4.8 KB

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