agent.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 config
  7. from opendevin.core.logger import opendevin_logger as logger
  8. from opendevin.core.schema import ConfigType
  9. from opendevin.events.stream import EventStream
  10. from opendevin.llm.llm import LLM
  11. from opendevin.runtime import DockerSSHBox
  12. from opendevin.runtime.e2b.runtime import E2BRuntime
  13. from opendevin.runtime.runtime import Runtime
  14. from opendevin.runtime.server.runtime import ServerRuntime
  15. class AgentSession:
  16. """Represents a session with an agent.
  17. Attributes:
  18. controller: The AgentController instance for controlling the agent.
  19. """
  20. sid: str
  21. event_stream: EventStream
  22. controller: Optional[AgentController] = None
  23. runtime: Optional[Runtime] = None
  24. _closed: bool = False
  25. def __init__(self, sid):
  26. """Initializes a new instance of the Session class."""
  27. self.sid = sid
  28. self.event_stream = EventStream(sid)
  29. async def start(self, start_event: dict):
  30. """Starts the agent session.
  31. Args:
  32. start_event: The start event data (optional).
  33. """
  34. if self.controller or self.runtime:
  35. raise Exception(
  36. 'Session already started. You need to close this session and start a new one.'
  37. )
  38. await self._create_runtime()
  39. await self._create_controller(start_event)
  40. async def close(self):
  41. if self._closed:
  42. return
  43. if self.controller is not None:
  44. end_state = self.controller.get_state()
  45. end_state.save_to_session(self.sid)
  46. await self.controller.close()
  47. if self.runtime is not None:
  48. self.runtime.close()
  49. self._closed = True
  50. async def _create_runtime(self):
  51. if self.runtime is not None:
  52. raise Exception('Runtime already created')
  53. if config.runtime == 'server':
  54. logger.info('Using server runtime')
  55. self.runtime = ServerRuntime(self.event_stream, self.sid)
  56. elif config.runtime == 'e2b':
  57. logger.info('Using E2B runtime')
  58. self.runtime = E2BRuntime(self.event_stream, self.sid)
  59. else:
  60. raise Exception(
  61. f'Runtime not defined in config, or is invalid: {config.runtime}'
  62. )
  63. async def _create_controller(self, start_event: dict):
  64. """Creates an AgentController instance.
  65. Args:
  66. start_event: The start event data (optional).
  67. """
  68. if self.controller is not None:
  69. raise Exception('Controller already created')
  70. if self.runtime is None:
  71. raise Exception('Runtime must be initialized before the agent controller')
  72. args = {
  73. key: value
  74. for key, value in start_event.get('args', {}).items()
  75. if value != ''
  76. } # remove empty values, prevent FE from sending empty strings
  77. agent_cls = args.get(ConfigType.AGENT, config.agent.name)
  78. model = args.get(ConfigType.LLM_MODEL, config.llm.model)
  79. api_key = args.get(ConfigType.LLM_API_KEY, config.llm.api_key)
  80. api_base = config.llm.base_url
  81. max_iterations = args.get(ConfigType.MAX_ITERATIONS, config.max_iterations)
  82. max_chars = args.get(ConfigType.MAX_CHARS, config.llm.max_chars)
  83. logger.info(f'Creating agent {agent_cls} using LLM {model}')
  84. llm = LLM(model=model, api_key=api_key, base_url=api_base)
  85. agent = Agent.get_cls(agent_cls)(llm)
  86. if isinstance(agent, CodeActAgent):
  87. if not self.runtime or not isinstance(self.runtime.sandbox, DockerSSHBox):
  88. logger.warning(
  89. 'CodeActAgent requires DockerSSHBox as sandbox! Using other sandbox that are not stateful (LocalBox, DockerExecBox) will not work properly.'
  90. )
  91. self.runtime.init_sandbox_plugins(agent.sandbox_plugins)
  92. self.runtime.init_runtime_tools(agent.runtime_tools)
  93. self.controller = AgentController(
  94. sid=self.sid,
  95. event_stream=self.event_stream,
  96. agent=agent,
  97. max_iterations=int(max_iterations),
  98. max_chars=int(max_chars),
  99. )
  100. try:
  101. agent_state = State.restore_from_session(self.sid)
  102. self.controller.set_state(agent_state)
  103. except Exception as e:
  104. print('Error restoring state', e)