agent.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from jinja2 import BaseLoader, Environment
  2. from opendevin.controller.agent import Agent
  3. from opendevin.controller.state.state import State
  4. from opendevin.core.config import AgentConfig
  5. from opendevin.core.message import ImageContent, Message, TextContent
  6. from opendevin.core.utils import json
  7. from opendevin.events.action import Action
  8. from opendevin.events.serialization.action import action_from_dict
  9. from opendevin.events.serialization.event import event_to_memory
  10. from opendevin.llm.llm import LLM
  11. from opendevin.memory.history import ShortTermHistory
  12. from .instructions import instructions
  13. from .registry import all_microagents
  14. def parse_response(orig_response: str) -> Action:
  15. # attempt to load the JSON dict from the response
  16. action_dict = json.loads(orig_response)
  17. # load the action from the dict
  18. return action_from_dict(action_dict)
  19. def to_json(obj, **kwargs):
  20. """Serialize an object to str format"""
  21. return json.dumps(obj, **kwargs)
  22. class MicroAgent(Agent):
  23. VERSION = '1.0'
  24. prompt = ''
  25. agent_definition: dict = {}
  26. def history_to_json(
  27. self, history: ShortTermHistory, max_events: int = 20, **kwargs
  28. ):
  29. """
  30. Serialize and simplify history to str format
  31. """
  32. processed_history = []
  33. event_count = 0
  34. for event in history.get_events(reverse=True):
  35. if event_count >= max_events:
  36. break
  37. processed_history.append(
  38. event_to_memory(event, self.llm.config.max_message_chars)
  39. )
  40. event_count += 1
  41. # history is in reverse order, let's fix it
  42. processed_history.reverse()
  43. return json.dumps(processed_history, **kwargs)
  44. def __init__(self, llm: LLM, config: AgentConfig):
  45. super().__init__(llm, config)
  46. if 'name' not in self.agent_definition:
  47. raise ValueError('Agent definition must contain a name')
  48. self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
  49. self.delegates = all_microagents.copy()
  50. del self.delegates[self.agent_definition['name']]
  51. def step(self, state: State) -> Action:
  52. last_user_message, last_image_urls = state.get_current_user_intent()
  53. prompt = self.prompt_template.render(
  54. state=state,
  55. instructions=instructions,
  56. to_json=to_json,
  57. history_to_json=self.history_to_json,
  58. delegates=self.delegates,
  59. latest_user_message=last_user_message,
  60. )
  61. content = [TextContent(text=prompt)]
  62. if last_image_urls:
  63. content.append(ImageContent(image_urls=last_image_urls))
  64. message = Message(role='user', content=content)
  65. resp = self.llm.completion(messages=[message.model_dump()])
  66. action_resp = resp['choices'][0]['message']['content']
  67. action = parse_response(action_resp)
  68. return action